Array of array: Implement the core functionality: types, constructors, operations.
authorJohn Kessenich <cepheus@frii.com>
Mon, 10 Aug 2015 23:08:55 +0000 (17:08 -0600)
committerJohn Kessenich <cepheus@frii.com>
Mon, 10 Aug 2015 23:08:55 +0000 (17:08 -0600)
There will be subsequent commits to refine semantics, esp. version-specific semantics,
as well as I/O functionality and restrictions.

Note: I'm getting white-space differences in the preprocessor test results,
which I'm not checking in.  I think they need to be tagged as binary or something.

23 files changed:
SPIRV/GlslangToSpv.cpp
Test/430AofA.frag [new file with mode: 0644]
Test/baseResults/120.vert.out
Test/baseResults/300.frag.out
Test/baseResults/310.frag.out
Test/baseResults/310.vert.out
Test/baseResults/310AofA.vert.out
Test/baseResults/430AofA.frag.out [new file with mode: 0644]
Test/baseResults/450.vert.out
Test/baseResults/specExamples.frag.out
Test/baseResults/specExamples.vert.out
Test/specExamples.vert
Test/testlist
glslang/Include/Types.h
glslang/Include/arrays.h
glslang/Include/revision.h
glslang/MachineIndependent/Initialize.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h
glslang/MachineIndependent/SymbolTable.cpp
glslang/MachineIndependent/glslang.y
glslang/MachineIndependent/linkValidate.cpp
glslang/MachineIndependent/reflection.cpp

index 1d1dcaf..4b8c933 100755 (executable)
@@ -953,7 +953,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     {
         glslang::TIntermTyped* typedNode = node->getSequence()[0]->getAsTyped();
         assert(typedNode);
-        spv::Id length = builder.makeIntConstant(typedNode->getType().getArraySize());
+        spv::Id length = builder.makeIntConstant(typedNode->getType().getOuterArraySize());
 
         builder.clearAccessChain();
         builder.setAccessChainRValue(length);
@@ -1428,7 +1428,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
             spv::MissingFunctionality("Unsized array");
             arraySize = 8;
         } else
-            arraySize = type.getArraySize();
+            arraySize = type.getOuterArraySize();
         spvType = builder.makeArrayType(spvType, arraySize);
     }
 
@@ -2637,15 +2637,11 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangT
     spv::Id typeId = convertGlslangToSpvType(glslangType);
 
     if (glslangType.isArray()) {
-        glslang::TType elementType;
-        elementType.deepCopy(glslangType);
-        elementType.dereference();
-        for (int i = 0; i < glslangType.getArraySize(); ++i)
+        glslang::TType elementType(glslangType, 0);
+        for (int i = 0; i < glslangType.getOuterArraySize(); ++i)
             spvConsts.push_back(createSpvConstant(elementType, consts, nextConst));
     } else if (glslangType.isMatrix()) {
-        glslang::TType vectorType;
-        vectorType.shallowCopy(glslangType);
-        vectorType.dereference();
+        glslang::TType vectorType(glslangType, 0);
         for (int col = 0; col < glslangType.getMatrixCols(); ++col)
             spvConsts.push_back(createSpvConstant(vectorType, consts, nextConst));
     } else if (glslangType.getStruct()) {
diff --git a/Test/430AofA.frag b/Test/430AofA.frag
new file mode 100644 (file)
index 0000000..54d0923
--- /dev/null
@@ -0,0 +1,108 @@
+#version 430\r
+\r
+float[4][5][6] many[1][2][3];\r
+\r
+float gu[][7];\r
+float gimp[][];    // ERROR, implicit inner\r
+float g4[4][7];\r
+float g5[5][7];\r
+\r
+float[4][7] foo(float a[5][7])\r
+{\r
+    float r[7];\r
+    r = a[2];\r
+    float[](a[0], a[1], r, a[3]);              // ERROR, too few dims\r
+    float[4][7][4](a[0], a[1], r, a[3]);       // ERROR, too many dims\r
+    return float[4][7](a[0], a[1], r, a[3]);\r
+    return float[][](a[0], a[1], r, a[3]);\r
+    return float[][7](a[0], a[1], a[2], a[3]);\r
+}\r
+\r
+void bar(float[5][7]) {}\r
+\r
+void main()\r
+{\r
+    {\r
+        float gu[3][4][2];\r
+\r
+        gu[2][4][1] = 4.0;                     // ERROR, overflow\r
+    }\r
+    vec4 ca4[3][2] = vec4[][](vec4[2](vec4(0.0), vec4(1.0)),\r
+                              vec4[2](vec4(0.0), vec4(1.0)),\r
+                              vec4[2](vec4(0.0), vec4(1.0)));\r
+    vec4 caim[][2] = vec4[][](vec4[2](vec4(4.0), vec4(2.0)),\r
+                              vec4[2](vec4(4.0), vec4(2.0)),\r
+                              vec4[2](vec4(4.0), vec4(2.0)));\r
+    vec4 caim2[][] = vec4[][](vec4[2](vec4(4.0), vec4(2.0)),\r
+                              vec4[2](vec4(4.0), vec4(2.0)),\r
+                              vec4[2](vec4(4.0), vec4(2.0)));\r
+    vec4 caim3[3][] = vec4[][](vec4[2](vec4(4.0), vec4(2.0)),\r
+                               vec4[2](vec4(4.0), vec4(2.0)),\r
+                               vec4[2](vec4(4.0), vec4(2.0)));\r
+\r
+    vec4 a4[3][2] = {vec4[](vec4(0.0), vec4(1.0)),\r
+                     vec4[2](vec4(0.0), vec4(1.0)),\r
+                     vec4[2](vec4(0.0), vec4(1.0)) };\r
+    vec4 aim[][2] = {vec4[2](vec4(4.0), vec4(2.0)),\r
+                     vec4[](vec4(4.0), vec4(2.0)),\r
+                     vec4[2](vec4(4.0), vec4(2.0)) };\r
+    vec4 aim2[][] = {vec4[2](vec4(4.0), vec4(2.0)),\r
+                     vec4[2](vec4(4.0), vec4(2.0)),\r
+                     vec4[](vec4(4.0), vec4(2.0)) };\r
+    vec4 aim3[3][] = {vec4[2](vec4(4.0), vec4(2.0)),\r
+                      vec4[2](vec4(4.0), vec4(2.0)),\r
+                      vec4[2](vec4(4.0), vec4(2.0)) };\r
+\r
+    vec4 bad2[3][] = {vec4[2](vec4(4.0), vec4(2.0)),              // ERROR\r
+                      vec4[3](vec4(4.0), vec4(2.0), vec4(5.0)),\r
+                      vec4[2](vec4(4.0), vec4(2.0)) };\r
+\r
+    vec4 bad3[3][] = {vec4[3](vec4(4.0), vec4(2.0), vec4(5.0)),   // ERROR\r
+                      vec4[2](vec4(4.0), vec4(2.0)),\r
+                      vec4[2](vec4(4.0), vec4(2.0)) };\r
+\r
+    vec4 bad4[4][] = {vec4[2](vec4(4.0), vec4(2.0)),              // ERROR\r
+                      vec4[2](vec4(4.0), vec4(2.0)),\r
+                      vec4[2](vec4(4.0), vec4(2.0)) };\r
+\r
+\r
+    g4 = foo(g5);\r
+    g5 = g4;           // ERROR, wrong types\r
+    gu = g4;           // ERROR, not yet sized\r
+\r
+    foo(gu);           // ERROR, not yet sized\r
+    bar(g5);\r
+\r
+    if (foo(g5) == g4)\r
+        ;\r
+    if (foo(g5) == g5)  // ERROR, different types\r
+        ;\r
+\r
+    float u[][7];\r
+    u[2][2] = 3.0;\r
+    float u[5][7];\r
+    u[5][2] = 5.0;      // ERROR\r
+    foo(u);\r
+}\r
+\r
+void foo3()\r
+{\r
+    float resize1[][5][7];\r
+    resize1.length();           // ERROR\r
+    resize1[1][4][5] = 2.0;\r
+    resize1.length();           // ERROR\r
+    float resize1[3][5][7];\r
+    resize1.length();           // 3 in AST\r
+    resize1[1].length();        // 5 in AST\r
+    resize1[1][1].length();     // 7 in AST\r
+    resize1[1][1][1].length();  // ERROR\r
+\r
+    float resize2[][5][7];\r
+    float resize2[3][4][7];     // ERROR, inner dim change\r
+\r
+    float resize3[][5][7];\r
+    float resize3[3][5][9];     // ERROR, inner dim changed\r
+\r
+    float resize4[][5][7];\r
+    int  resize4[3][5][7];      // ERROR, element type\r
+}\r
index 8db27da..7b58c8b 100644 (file)
@@ -17,7 +17,6 @@ ERROR: 0:34: '.' : cannot apply to an array: flizbit
 ERROR: 0:34: 'f' : can't use function syntax on variable \r
 ERROR: 0:34: 'a4' : redefinition \r
 ERROR: 0:35: 'arrays of arrays' : not supported with this profile: none\r
-WARNING: 0:35: 'Not supported yet.' : arrays of arrays \r
 ERROR: 0:36: 'arrays of arrays' : not supported with this profile: none\r
 ERROR: 0:37: 'arrays of arrays' : not supported with this profile: none\r
 ERROR: 0:38: 'arrays of arrays' : not supported with this profile: none\r
index 1d1d533..fb050a5 100644 (file)
@@ -21,7 +21,6 @@ ERROR: 0:85: 'double vector' : not supported with this profile: es
 ERROR: 0:86: 'dvec4' : Reserved word. \r
 ERROR: 0:86: 'double vector' : not supported with this profile: es\r
 ERROR: 0:101: 'arrays of arrays' : not supported for this version or the enabled extensions \r
-WARNING: 0:101: 'Not supported yet.' : arrays of arrays \r
 ERROR: 0:102: 'arrays of arrays' : not supported for this version or the enabled extensions \r
 ERROR: 0:102: 'arrays of arrays' : not supported for this version or the enabled extensions \r
 ERROR: 0:103: 'arrays of arrays' : not supported for this version or the enabled extensions \r
index 7676e70..c74b9f0 100644 (file)
@@ -37,7 +37,6 @@ ERROR: 0:111: '' : image variables not declared 'writeonly' must have a format l
 ERROR: 0:112: 'out' : cannot be a matrix \r
 ERROR: 0:114: 'in' : cannot be bool \r
 ERROR: 0:115: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: ino\r
-WARNING: 0:117: 'Not supported yet.' : arrays of arrays \r
 ERROR: 0:117: 'fragment-shader array-of-array input' : not supported with this profile: es\r
 ERROR: 0:120: 'fragment-shader array-of-struct input' : not supported with this profile: es\r
 ERROR: 0:121: 'fragment-shader array-of-struct input' : not supported with this profile: es\r
index 82a1311..d6face4 100644 (file)
@@ -9,7 +9,6 @@ ERROR: 0:58: 'sampler/image' : type requires declaration of default precision qu
 ERROR: 0:67: 'textureSamples' : no matching overloaded function found \r
 ERROR: 0:72: 'out' : cannot be bool \r
 ERROR: 0:73: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: outo\r
-WARNING: 0:75: 'Not supported yet.' : arrays of arrays \r
 ERROR: 0:75: 'vertex-shader array-of-array output' : not supported with this profile: es\r
 ERROR: 0:78: 'vertex-shader array-of-struct output' : not supported with this profile: es\r
 ERROR: 0:79: 'vertex-shader array-of-struct output' : not supported with this profile: es\r
index a8de634..63598fc 100644 (file)
@@ -1,6 +1,5 @@
 310AofA.vert\r
 Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.\r
-WARNING: 0:8: 'Not supported yet.' : arrays of arrays \r
 \r
 Shader version: 310\r
 0:? Sequence\r
diff --git a/Test/baseResults/430AofA.frag.out b/Test/baseResults/430AofA.frag.out
new file mode 100644 (file)
index 0000000..c6ab950
--- /dev/null
@@ -0,0 +1,803 @@
+430AofA.frag\r
+Warning, version 430 is not yet complete; most version-specific features are present, but some are missing.\r
+ERROR: 0:6: '[]' : only outermost dimension of an array of arrays can be implicitly sized \r
+ERROR: 0:14: 'constructor' : constructing non-array constituent from array argument \r
+ERROR: 0:15: 'constructior' : array constructor argument not correct type to construct array element \r
+ERROR: 0:28: '[' :  array index out of range '4'\r
+ERROR: 0:56: 'constructor' :  cannot convert parameter 2 from 'const 3-element array of 4-component vector of float' to 'temp 2-element array of 4-component vector of float'\r
+ERROR: 0:60: 'constructor' :  cannot convert parameter 2 from 'const 2-element array of 4-component vector of float' to 'temp 3-element array of 4-component vector of float'\r
+ERROR: 0:64: '=' :  cannot convert from 'temp 3-element array of 2-element array of 4-component vector of float' to 'temp 4-element array of 2-element array of 4-component vector of float'\r
+ERROR: 0:70: 'assign' :  cannot convert from 'global 4-element array of 7-element array of float' to 'global 5-element array of 7-element array of float'\r
+ERROR: 0:71: 'assign' :  cannot convert from 'global 4-element array of 7-element array of float' to 'global implicitly-sized array of 7-element array of float'\r
+ERROR: 0:73: 'foo' : no matching overloaded function found \r
+ERROR: 0:78: '==' :  wrong operand types: no operation '==' exists that takes a left-hand operand of type 'global 4-element array of 7-element array of float' and a right operand of type 'global 5-element array of 7-element array of float' (or there is no acceptable conversion)\r
+ERROR: 0:84: '[' :  array index out of range '5'\r
+ERROR: 0:91: 'length' :  array must be declared with a size before using this method\r
+ERROR: 0:93: 'length' :  array must be declared with a size before using this method\r
+ERROR: 0:98: 'length' : does not operate on this type: temp float\r
+ERROR: 0:98: '' : function call, method, or subroutine call expected \r
+ERROR: 0:98: '' : no matching overloaded function found \r
+ERROR: 0:101: 'resize2' : redeclaration of array with a different array dimensions or sizes \r
+ERROR: 0:104: 'resize3' : redeclaration of array with a different array dimensions or sizes \r
+ERROR: 0:107: 'resize4' : redeclaration of array with a different element type \r
+ERROR: 20 compilation errors.  No code generated.\r
+\r
+\r
+Shader version: 430\r
+ERROR: node is still EOpNull!\r
+0:10  Function Definition: foo(f1[5][7]; (global 4-element array of 7-element array of float)\r
+0:10    Function Parameters: \r
+0:10      'a' (in 5-element array of 7-element array of float)\r
+0:?     Sequence\r
+0:13      move second child to first child (temp 7-element array of float)\r
+0:13        'r' (temp 7-element array of float)\r
+0:13        direct index (temp 7-element array of float)\r
+0:13          'a' (in 5-element array of 7-element array of float)\r
+0:13          Constant:\r
+0:13            2 (const int)\r
+0:14      Constant:\r
+0:14        0.000000\r
+0:15      Constant:\r
+0:15        0.000000\r
+0:16      Branch: Return with expression\r
+0:16        Construct float (temp 4-element array of 7-element array of float)\r
+0:16          direct index (temp 7-element array of float)\r
+0:16            'a' (in 5-element array of 7-element array of float)\r
+0:16            Constant:\r
+0:16              0 (const int)\r
+0:16          direct index (temp 7-element array of float)\r
+0:16            'a' (in 5-element array of 7-element array of float)\r
+0:16            Constant:\r
+0:16              1 (const int)\r
+0:16          'r' (temp 7-element array of float)\r
+0:16          direct index (temp 7-element array of float)\r
+0:16            'a' (in 5-element array of 7-element array of float)\r
+0:16            Constant:\r
+0:16              3 (const int)\r
+0:17      Branch: Return with expression\r
+0:17        Construct float (temp 4-element array of 7-element array of float)\r
+0:17          direct index (temp 7-element array of float)\r
+0:17            'a' (in 5-element array of 7-element array of float)\r
+0:17            Constant:\r
+0:17              0 (const int)\r
+0:17          direct index (temp 7-element array of float)\r
+0:17            'a' (in 5-element array of 7-element array of float)\r
+0:17            Constant:\r
+0:17              1 (const int)\r
+0:17          'r' (temp 7-element array of float)\r
+0:17          direct index (temp 7-element array of float)\r
+0:17            'a' (in 5-element array of 7-element array of float)\r
+0:17            Constant:\r
+0:17              3 (const int)\r
+0:18      Branch: Return with expression\r
+0:18        Construct float (temp 4-element array of 7-element array of float)\r
+0:18          direct index (temp 7-element array of float)\r
+0:18            'a' (in 5-element array of 7-element array of float)\r
+0:18            Constant:\r
+0:18              0 (const int)\r
+0:18          direct index (temp 7-element array of float)\r
+0:18            'a' (in 5-element array of 7-element array of float)\r
+0:18            Constant:\r
+0:18              1 (const int)\r
+0:18          direct index (temp 7-element array of float)\r
+0:18            'a' (in 5-element array of 7-element array of float)\r
+0:18            Constant:\r
+0:18              2 (const int)\r
+0:18          direct index (temp 7-element array of float)\r
+0:18            'a' (in 5-element array of 7-element array of float)\r
+0:18            Constant:\r
+0:18              3 (const int)\r
+0:21  Function Definition: bar(f1[5][7]; (global void)\r
+0:21    Function Parameters: \r
+0:21      '' (in 5-element array of 7-element array of float)\r
+0:23  Function Definition: main( (global void)\r
+0:23    Function Parameters: \r
+0:?     Sequence\r
+0:?       Sequence\r
+0:28        move second child to first child (temp float)\r
+0:28          direct index (temp float)\r
+0:28            direct index (temp 2-element array of float)\r
+0:28              direct index (temp 4-element array of 2-element array of float)\r
+0:28                'gu' (temp 3-element array of 4-element array of 2-element array of float)\r
+0:28                Constant:\r
+0:28                  2 (const int)\r
+0:28              Constant:\r
+0:28                4 (const int)\r
+0:28            Constant:\r
+0:28              1 (const int)\r
+0:28          Constant:\r
+0:28            4.000000\r
+0:30      Sequence\r
+0:30        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:30          'ca4' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:32          Constant:\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:33      Sequence\r
+0:33        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:33          'caim' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:35          Constant:\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:36      Sequence\r
+0:36        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:36          'caim2' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:38          Constant:\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:39      Sequence\r
+0:39        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:39          'caim3' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:41          Constant:\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:43      Sequence\r
+0:43        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:43          'a4' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:43          Constant:\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:46      Sequence\r
+0:46        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:46          'aim' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:46          Constant:\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:49      Sequence\r
+0:49        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:49          'aim2' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:49          Constant:\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:52      Sequence\r
+0:52        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:52          'aim3' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:52          Constant:\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:69      move second child to first child (temp 4-element array of 7-element array of float)\r
+0:69        'g4' (global 4-element array of 7-element array of float)\r
+0:69        Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float)\r
+0:69          'g5' (global 5-element array of 7-element array of float)\r
+0:70      'g5' (global 5-element array of 7-element array of float)\r
+0:71      'gu' (global implicitly-sized array of 7-element array of float)\r
+0:73      Constant:\r
+0:73        0.000000\r
+0:74      Function Call: bar(f1[5][7]; (global void)\r
+0:74        'g5' (global 5-element array of 7-element array of float)\r
+0:76      Test condition and select (temp void)\r
+0:76        Condition\r
+0:76        Compare Equal (temp bool)\r
+0:76          Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float)\r
+0:76            'g5' (global 5-element array of 7-element array of float)\r
+0:76          'g4' (global 4-element array of 7-element array of float)\r
+0:76        true case is null\r
+0:78      Test condition and select (temp void)\r
+0:78        Condition\r
+0:78        Constant:\r
+0:78          false (const bool)\r
+0:78        true case is null\r
+0:82      move second child to first child (temp float)\r
+0:82        direct index (temp float)\r
+0:82          direct index (temp 7-element array of float)\r
+0:82            'u' (temp 5-element array of 7-element array of float)\r
+0:82            Constant:\r
+0:82              2 (const int)\r
+0:82          Constant:\r
+0:82            2 (const int)\r
+0:82        Constant:\r
+0:82          3.000000\r
+0:84      move second child to first child (temp float)\r
+0:84        direct index (temp float)\r
+0:84          direct index (temp 7-element array of float)\r
+0:84            'u' (temp 5-element array of 7-element array of float)\r
+0:84            Constant:\r
+0:84              5 (const int)\r
+0:84          Constant:\r
+0:84            2 (const int)\r
+0:84        Constant:\r
+0:84          5.000000\r
+0:85      Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float)\r
+0:85        'u' (temp 5-element array of 7-element array of float)\r
+0:88  Function Definition: foo3( (global void)\r
+0:88    Function Parameters: \r
+0:?     Sequence\r
+0:91      Constant:\r
+0:91        1 (const int)\r
+0:92      move second child to first child (temp float)\r
+0:92        direct index (temp float)\r
+0:92          direct index (temp 7-element array of float)\r
+0:92            direct index (temp 5-element array of 7-element array of float)\r
+0:92              'resize1' (temp 3-element array of 5-element array of 7-element array of float)\r
+0:92              Constant:\r
+0:92                1 (const int)\r
+0:92            Constant:\r
+0:92              4 (const int)\r
+0:92          Constant:\r
+0:92            5 (const int)\r
+0:92        Constant:\r
+0:92          2.000000\r
+0:93      Constant:\r
+0:93        1 (const int)\r
+0:95      Constant:\r
+0:95        3 (const int)\r
+0:96      Constant:\r
+0:96        5 (const int)\r
+0:97      Constant:\r
+0:97        7 (const int)\r
+0:98      Constant:\r
+0:98        0.000000\r
+0:?   Linker Objects\r
+0:?     'many' (global 1-element array of 2-element array of 3-element array of 4-element array of 5-element array of 6-element array of float)\r
+0:?     'gu' (global implicitly-sized array of 7-element array of float)\r
+0:?     'gimp' (global implicitly-sized array of implicitly-sized array of float)\r
+0:?     'g4' (global 4-element array of 7-element array of float)\r
+0:?     'g5' (global 5-element array of 7-element array of float)\r
+\r
+\r
+Linked fragment stage:\r
+\r
+\r
+Shader version: 430\r
+ERROR: node is still EOpNull!\r
+0:10  Function Definition: foo(f1[5][7]; (global 4-element array of 7-element array of float)\r
+0:10    Function Parameters: \r
+0:10      'a' (in 5-element array of 7-element array of float)\r
+0:?     Sequence\r
+0:13      move second child to first child (temp 7-element array of float)\r
+0:13        'r' (temp 7-element array of float)\r
+0:13        direct index (temp 7-element array of float)\r
+0:13          'a' (in 5-element array of 7-element array of float)\r
+0:13          Constant:\r
+0:13            2 (const int)\r
+0:14      Constant:\r
+0:14        0.000000\r
+0:15      Constant:\r
+0:15        0.000000\r
+0:16      Branch: Return with expression\r
+0:16        Construct float (temp 4-element array of 7-element array of float)\r
+0:16          direct index (temp 7-element array of float)\r
+0:16            'a' (in 5-element array of 7-element array of float)\r
+0:16            Constant:\r
+0:16              0 (const int)\r
+0:16          direct index (temp 7-element array of float)\r
+0:16            'a' (in 5-element array of 7-element array of float)\r
+0:16            Constant:\r
+0:16              1 (const int)\r
+0:16          'r' (temp 7-element array of float)\r
+0:16          direct index (temp 7-element array of float)\r
+0:16            'a' (in 5-element array of 7-element array of float)\r
+0:16            Constant:\r
+0:16              3 (const int)\r
+0:17      Branch: Return with expression\r
+0:17        Construct float (temp 4-element array of 7-element array of float)\r
+0:17          direct index (temp 7-element array of float)\r
+0:17            'a' (in 5-element array of 7-element array of float)\r
+0:17            Constant:\r
+0:17              0 (const int)\r
+0:17          direct index (temp 7-element array of float)\r
+0:17            'a' (in 5-element array of 7-element array of float)\r
+0:17            Constant:\r
+0:17              1 (const int)\r
+0:17          'r' (temp 7-element array of float)\r
+0:17          direct index (temp 7-element array of float)\r
+0:17            'a' (in 5-element array of 7-element array of float)\r
+0:17            Constant:\r
+0:17              3 (const int)\r
+0:18      Branch: Return with expression\r
+0:18        Construct float (temp 4-element array of 7-element array of float)\r
+0:18          direct index (temp 7-element array of float)\r
+0:18            'a' (in 5-element array of 7-element array of float)\r
+0:18            Constant:\r
+0:18              0 (const int)\r
+0:18          direct index (temp 7-element array of float)\r
+0:18            'a' (in 5-element array of 7-element array of float)\r
+0:18            Constant:\r
+0:18              1 (const int)\r
+0:18          direct index (temp 7-element array of float)\r
+0:18            'a' (in 5-element array of 7-element array of float)\r
+0:18            Constant:\r
+0:18              2 (const int)\r
+0:18          direct index (temp 7-element array of float)\r
+0:18            'a' (in 5-element array of 7-element array of float)\r
+0:18            Constant:\r
+0:18              3 (const int)\r
+0:21  Function Definition: bar(f1[5][7]; (global void)\r
+0:21    Function Parameters: \r
+0:21      '' (in 5-element array of 7-element array of float)\r
+0:23  Function Definition: main( (global void)\r
+0:23    Function Parameters: \r
+0:?     Sequence\r
+0:?       Sequence\r
+0:28        move second child to first child (temp float)\r
+0:28          direct index (temp float)\r
+0:28            direct index (temp 2-element array of float)\r
+0:28              direct index (temp 4-element array of 2-element array of float)\r
+0:28                'gu' (temp 3-element array of 4-element array of 2-element array of float)\r
+0:28                Constant:\r
+0:28                  2 (const int)\r
+0:28              Constant:\r
+0:28                4 (const int)\r
+0:28            Constant:\r
+0:28              1 (const int)\r
+0:28          Constant:\r
+0:28            4.000000\r
+0:30      Sequence\r
+0:30        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:30          'ca4' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:32          Constant:\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            0.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:32            1.000000\r
+0:33      Sequence\r
+0:33        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:33          'caim' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:35          Constant:\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            4.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:35            2.000000\r
+0:36      Sequence\r
+0:36        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:36          'caim2' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:38          Constant:\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            4.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:38            2.000000\r
+0:39      Sequence\r
+0:39        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:39          'caim3' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:41          Constant:\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            4.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:41            2.000000\r
+0:43      Sequence\r
+0:43        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:43          'a4' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:43          Constant:\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            0.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:43            1.000000\r
+0:46      Sequence\r
+0:46        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:46          'aim' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:46          Constant:\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            4.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:46            2.000000\r
+0:49      Sequence\r
+0:49        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:49          'aim2' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:49          Constant:\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            4.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:49            2.000000\r
+0:52      Sequence\r
+0:52        move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:52          'aim3' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:52          Constant:\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            4.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:52            2.000000\r
+0:69      move second child to first child (temp 4-element array of 7-element array of float)\r
+0:69        'g4' (global 4-element array of 7-element array of float)\r
+0:69        Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float)\r
+0:69          'g5' (global 5-element array of 7-element array of float)\r
+0:70      'g5' (global 5-element array of 7-element array of float)\r
+0:71      'gu' (global 1-element array of 7-element array of float)\r
+0:73      Constant:\r
+0:73        0.000000\r
+0:74      Function Call: bar(f1[5][7]; (global void)\r
+0:74        'g5' (global 5-element array of 7-element array of float)\r
+0:76      Test condition and select (temp void)\r
+0:76        Condition\r
+0:76        Compare Equal (temp bool)\r
+0:76          Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float)\r
+0:76            'g5' (global 5-element array of 7-element array of float)\r
+0:76          'g4' (global 4-element array of 7-element array of float)\r
+0:76        true case is null\r
+0:78      Test condition and select (temp void)\r
+0:78        Condition\r
+0:78        Constant:\r
+0:78          false (const bool)\r
+0:78        true case is null\r
+0:82      move second child to first child (temp float)\r
+0:82        direct index (temp float)\r
+0:82          direct index (temp 7-element array of float)\r
+0:82            'u' (temp 5-element array of 7-element array of float)\r
+0:82            Constant:\r
+0:82              2 (const int)\r
+0:82          Constant:\r
+0:82            2 (const int)\r
+0:82        Constant:\r
+0:82          3.000000\r
+0:84      move second child to first child (temp float)\r
+0:84        direct index (temp float)\r
+0:84          direct index (temp 7-element array of float)\r
+0:84            'u' (temp 5-element array of 7-element array of float)\r
+0:84            Constant:\r
+0:84              5 (const int)\r
+0:84          Constant:\r
+0:84            2 (const int)\r
+0:84        Constant:\r
+0:84          5.000000\r
+0:85      Function Call: foo(f1[5][7]; (global 4-element array of 7-element array of float)\r
+0:85        'u' (temp 5-element array of 7-element array of float)\r
+0:88  Function Definition: foo3( (global void)\r
+0:88    Function Parameters: \r
+0:?     Sequence\r
+0:91      Constant:\r
+0:91        1 (const int)\r
+0:92      move second child to first child (temp float)\r
+0:92        direct index (temp float)\r
+0:92          direct index (temp 7-element array of float)\r
+0:92            direct index (temp 5-element array of 7-element array of float)\r
+0:92              'resize1' (temp 3-element array of 5-element array of 7-element array of float)\r
+0:92              Constant:\r
+0:92                1 (const int)\r
+0:92            Constant:\r
+0:92              4 (const int)\r
+0:92          Constant:\r
+0:92            5 (const int)\r
+0:92        Constant:\r
+0:92          2.000000\r
+0:93      Constant:\r
+0:93        1 (const int)\r
+0:95      Constant:\r
+0:95        3 (const int)\r
+0:96      Constant:\r
+0:96        5 (const int)\r
+0:97      Constant:\r
+0:97        7 (const int)\r
+0:98      Constant:\r
+0:98        0.000000\r
+0:?   Linker Objects\r
+0:?     'many' (global 1-element array of 2-element array of 3-element array of 4-element array of 5-element array of 6-element array of float)\r
+0:?     'gu' (global 1-element array of 7-element array of float)\r
+0:?     'gimp' (global 1-element array of implicitly-sized array of float)\r
+0:?     'g4' (global 4-element array of 7-element array of float)\r
+0:?     'g5' (global 5-element array of 7-element array of float)\r
+\r
index aecef87..44aff42 100644 (file)
@@ -2,7 +2,6 @@
 Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.\r
 ERROR: 0:12: 'out' : cannot be bool \r
 ERROR: 0:13: 'sampler2D' : sampler/image types can only be used in uniform variables or function parameters: outo\r
-WARNING: 0:15: 'Not supported yet.' : arrays of arrays \r
 ERROR: 2 compilation errors.  No code generated.\r
 \r
 \r
index bf3ae55..f73c7e3 100644 (file)
@@ -17,10 +17,6 @@ ERROR: 0:102: 'color' : redefinition
 ERROR: 0:112: 'redeclaration' : all redeclarations must use the same depth layout on gl_FragDepth\r
 ERROR: 0:118: 'redeclaration' : all redeclarations must use the same depth layout on gl_FragDepth\r
 ERROR: 0:121: 'redeclaration' : all redeclarations must use the same depth layout on gl_FragDepth\r
-WARNING: 0:146: 'Not supported yet.' : arrays of arrays \r
-ERROR: 0:150: 'constructor' : constructing from a non-dereferenced array \r
-ERROR: 0:150: '=' :  cannot convert from 'const float' to 'temp 3-element array of 2-element array of 4-component vector of float'\r
-ERROR: 0:152: 'constructor' :  cannot convert parameter 1 from 'const 2-element array of 4-component vector of float' to 'temp 4-component vector of float'\r
 ERROR: 0:172: 'x' : undeclared identifier \r
 ERROR: 0:172: '[]' : scalar integer expression required \r
 ERROR: 0:175: 'x' : undeclared identifier \r
@@ -42,7 +38,7 @@ ERROR: 0:226: 'in' : not allowed in nested scope
 ERROR: 0:227: 'in' : not allowed in nested scope \r
 ERROR: 0:228: 'in' : not allowed in nested scope \r
 ERROR: 0:232: 'out' : not allowed in nested scope \r
-ERROR: 41 compilation errors.  No code generated.\r
+ERROR: 38 compilation errors.  No code generated.\r
 \r
 \r
 Shader version: 430\r
@@ -164,6 +160,41 @@ ERROR: node is still EOpNull!
 0:149              0.100000\r
 0:149              0.100000\r
 0:149              0.100000\r
+0:150        Sequence\r
+0:150          move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:150            'a3' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:150            Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:150              'b' (temp 2-element array of 4-component vector of float)\r
+0:150              'b' (temp 2-element array of 4-component vector of float)\r
+0:150              'b' (temp 2-element array of 4-component vector of float)\r
+0:152        Sequence\r
+0:152          move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:152            'a4' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:152            Constant:\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
 0:?       Sequence\r
 0:159        Sequence\r
 0:159          Sequence\r
@@ -191,7 +222,7 @@ ERROR: node is still EOpNull!
 0:171        Constant:\r
 0:171          3 (const int)\r
 0:172        Constant:\r
-0:172          4 (const int)\r
+0:172          2 (const int)\r
 0:175      Constant:\r
 0:175        0.000000\r
 0:178      Constant:\r
@@ -418,6 +449,41 @@ ERROR: node is still EOpNull!
 0:149              0.100000\r
 0:149              0.100000\r
 0:149              0.100000\r
+0:150        Sequence\r
+0:150          move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:150            'a3' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:150            Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:150              'b' (temp 2-element array of 4-component vector of float)\r
+0:150              'b' (temp 2-element array of 4-component vector of float)\r
+0:150              'b' (temp 2-element array of 4-component vector of float)\r
+0:152        Sequence\r
+0:152          move second child to first child (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:152            'a4' (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:152            Constant:\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              0.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
+0:152              1.000000\r
 0:?       Sequence\r
 0:159        Sequence\r
 0:159          Sequence\r
@@ -445,7 +511,7 @@ ERROR: node is still EOpNull!
 0:171        Constant:\r
 0:171          3 (const int)\r
 0:172        Constant:\r
-0:172          4 (const int)\r
+0:172          2 (const int)\r
 0:175      Constant:\r
 0:175        0.000000\r
 0:178      Constant:\r
index 80e4929..8359f12 100644 (file)
@@ -1,6 +1,5 @@
 specExamples.vert\r
 Warning, version 430 is not yet complete; most version-specific features are present, but some are missing.\r
-ERROR: 0:23: 'transforms' : redeclaration of array with size \r
 ERROR: 0:29: 'location' : can only appy to uniform, buffer, in, or out storage qualifiers \r
 ERROR: 0:31: 'triangles' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) \r
 ERROR: 0:31: 'invocations' : there is no such layout identifier for this stage taking an assigned value \r
@@ -35,11 +34,7 @@ ERROR: 0:134: '' : function does not return a value: funcA
 ERROR: 0:136: '' : function does not return a value: funcB\r
 ERROR: 0:153: '' : function does not return a value: func3\r
 ERROR: 0:170: 'coherent' : argument cannot drop memory qualifier when passed to formal parameter \r
-WARNING: 0:192: 'Not supported yet.' : arrays of arrays \r
-ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array \r
-ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array \r
-ERROR: 0:194: 'constructor' : constructing from a non-dereferenced array \r
-ERROR: 37 compilation errors.  No code generated.\r
+ERROR: 33 compilation errors.  No code generated.\r
 \r
 \r
 Shader version: 430\r
@@ -269,18 +264,25 @@ ERROR: node is still EOpNull!
 0:191              1.000000\r
 0:191              1.000000\r
 0:191              1.000000\r
-0:192        Constant:\r
-0:192          0.000000\r
-0:193        Constant:\r
-0:193          0.000000\r
-0:194        Constant:\r
-0:194          0.000000\r
+0:192        Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:192          'b' (temp 2-element array of 4-component vector of float)\r
+0:192          'b' (temp 2-element array of 4-component vector of float)\r
+0:192          'b' (temp 2-element array of 4-component vector of float)\r
+0:193        Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:193          'b' (temp 2-element array of 4-component vector of float)\r
+0:193          'b' (temp 2-element array of 4-component vector of float)\r
+0:193          'b' (temp 2-element array of 4-component vector of float)\r
+0:194        Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:194          'b' (temp 2-element array of 4-component vector of float)\r
+0:194          'b' (temp 2-element array of 4-component vector of float)\r
+0:194          'b' (temp 2-element array of 4-component vector of float)\r
 0:?   Linker Objects\r
 0:?     'Coords' (out block{out 4-component vector of float Position, out 2-component vector of float Texture})\r
 0:?     'anon@0' (out block{out 4-component vector of float Color})\r
 0:?     'transforms' (layout(column_major shared ) uniform 4-element array of block{layout(column_major shared ) uniform 4X4 matrix of float ModelViewMatrix, layout(column_major shared ) uniform 4X4 matrix of float ModelViewProjectionMatrix, layout(column_major shared ) uniform implicitly-sized array of 4-component vector of float a, layout(column_major shared ) uniform float Deformation})\r
 0:?     'normal' (layout(location=3 ) in 4-component vector of float)\r
 0:?     'colors' (layout(location=6 ) in 3-element array of 4-component vector of float)\r
+0:?     'transforms2' (layout(location=9 ) in 2-element array of 4X4 matrix of float)\r
 0:?     's' (layout(location=3 ) temp structure{global 3-component vector of float a1, global 2X2 matrix of float b, global 2-element array of 4-component vector of float c})\r
 0:?     'var1' (smooth out 4-component vector of float)\r
 0:?     'anon@1' (out block{out 4-component vector of float var2, out 2-component vector of float var3, out 3-component vector of float var4})\r
@@ -546,18 +548,25 @@ ERROR: node is still EOpNull!
 0:191              1.000000\r
 0:191              1.000000\r
 0:191              1.000000\r
-0:192        Constant:\r
-0:192          0.000000\r
-0:193        Constant:\r
-0:193          0.000000\r
-0:194        Constant:\r
-0:194          0.000000\r
+0:192        Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:192          'b' (temp 2-element array of 4-component vector of float)\r
+0:192          'b' (temp 2-element array of 4-component vector of float)\r
+0:192          'b' (temp 2-element array of 4-component vector of float)\r
+0:193        Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:193          'b' (temp 2-element array of 4-component vector of float)\r
+0:193          'b' (temp 2-element array of 4-component vector of float)\r
+0:193          'b' (temp 2-element array of 4-component vector of float)\r
+0:194        Construct vec4 (temp 3-element array of 2-element array of 4-component vector of float)\r
+0:194          'b' (temp 2-element array of 4-component vector of float)\r
+0:194          'b' (temp 2-element array of 4-component vector of float)\r
+0:194          'b' (temp 2-element array of 4-component vector of float)\r
 0:?   Linker Objects\r
 0:?     'Coords' (out block{out 4-component vector of float Position, out 2-component vector of float Texture})\r
 0:?     'anon@0' (out block{out 4-component vector of float Color})\r
 0:?     'transforms' (layout(column_major shared ) uniform 4-element array of block{layout(column_major shared ) uniform 4X4 matrix of float ModelViewMatrix, layout(column_major shared ) uniform 4X4 matrix of float ModelViewProjectionMatrix, layout(column_major shared ) uniform 1-element array of 4-component vector of float a, layout(column_major shared ) uniform float Deformation})\r
 0:?     'normal' (layout(location=3 ) in 4-component vector of float)\r
 0:?     'colors' (layout(location=6 ) in 3-element array of 4-component vector of float)\r
+0:?     'transforms2' (layout(location=9 ) in 2-element array of 4X4 matrix of float)\r
 0:?     's' (layout(location=3 ) temp structure{global 3-component vector of float a1, global 2X2 matrix of float b, global 2-element array of 4-component vector of float c})\r
 0:?     'var1' (smooth out 4-component vector of float)\r
 0:?     'anon@1' (out block{out 4-component vector of float var2, out 2-component vector of float var3, out 3-component vector of float var4})\r
index a9c9178..9df1561 100644 (file)
@@ -20,7 +20,7 @@ uniform Transform {  // API uses 
 \r
 layout(location = 3) in vec4 normal;\r
 layout(location = 6) in vec4 colors[3];\r
-layout(location = 9) in mat4 transforms[2];\r
+layout(location = 9) in mat4 transforms2[2];\r
 \r
 layout(location = 3) struct S {\r
     vec3 a1;\r
index 797dca2..3478040 100644 (file)
@@ -76,6 +76,7 @@ numeral.frag
 410.geom
 430.vert
 430.comp
+430AofA.frag
 440.vert
 440.frag
 450.vert
index fd12bcc..8900b5b 100644 (file)
@@ -896,15 +896,32 @@ public:
     // and using only shallow copy
     TType(const TType& type, int derefIndex, bool rowMajor = false)
                             {
-                                if (! type.isArray() && (type.basicType == EbtStruct || type.basicType == EbtBlock)) {
+                                if (type.isArray()) {
+                                    shallowCopy(type);
+                                    if (type.getArraySizes()->getNumDims() == 1) {
+                                        arraySizes = nullptr;
+                                    } else {
+                                        // want our own copy of the array, so we can edit it
+                                        arraySizes = new TArraySizes;
+                                        arraySizes->copyDereferenced(*type.arraySizes);
+                                    }
+                                } else if (type.basicType == EbtStruct || type.basicType == EbtBlock) {
                                     // do a structure dereference
                                     const TTypeList& memberList = *type.getStruct();
                                     shallowCopy(*memberList[derefIndex].type);
                                     return;
                                 } else {
-                                    // do an array/vector/matrix dereference
+                                    // do a vector/matrix dereference
                                     shallowCopy(type);
-                                    dereference(rowMajor);
+                                    if (matrixCols > 0) {
+                                        if (rowMajor)
+                                            vectorSize = matrixCols;
+                                        else
+                                            vectorSize = matrixRows;
+                                        matrixCols = 0;
+                                        matrixRows = 0;
+                                    } else if (vectorSize > 1)
+                                        vectorSize = 1;
                                 }
                             }
     // for making structures, ...
@@ -990,28 +1007,13 @@ public:
         qualifier = parentType.qualifier;
         sampler = parentType.sampler;
         if (parentType.arraySizes)
-            setArraySizes(parentType.arraySizes);
+            newArraySizes(*parentType.arraySizes);
         if (parentType.userDef) {
             structure = parentType.userDef->getWritableStruct();
             setTypeName(parentType.userDef->getTypeName());
         }
     }
 
-    virtual void dereference(bool rowMajor = false)
-    {
-        if (arraySizes)
-            arraySizes = nullptr;
-        else if (matrixCols > 0) {
-            if (rowMajor)
-                vectorSize = matrixCols;
-            else
-                vectorSize = matrixRows;
-            matrixCols = 0;
-            matrixRows = 0;
-        } else if (vectorSize > 1)
-            vectorSize = 1;
-    }
-
     virtual void hideMember() { basicType = EbtVoid; vectorSize = 1; }
     virtual bool hiddenMember() const { return basicType == EbtVoid; }
 
@@ -1038,17 +1040,20 @@ public:
     virtual int getVectorSize() const { return vectorSize; }
     virtual int getMatrixCols() const { return matrixCols; }
     virtual int getMatrixRows() const { return matrixRows; }
-    virtual int getArraySize()  const { return arraySizes->getOuterSize(); }
+    virtual int getOuterArraySize()  const { return arraySizes->getOuterSize(); }
+    virtual int getCumulativeArraySize()  const { return arraySizes->getCumulativeSize(); }
     virtual bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; }
     virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
+    virtual const TArraySizes* getArraySizes() const { return arraySizes; }
+    virtual       TArraySizes& getArraySizes()       { assert(arraySizes != nullptr); return *arraySizes; }
 
     virtual bool isScalar() const { return vectorSize == 1 && ! isStruct() && ! isArray(); }
     virtual bool isVector() const { return vectorSize > 1; }
     virtual bool isMatrix() const { return matrixCols ? true : false; }
     virtual bool isArray()  const { return arraySizes != nullptr; }
-    virtual bool isExplicitlySizedArray() const { return isArray() && getArraySize() != UnsizedArraySize; }
-    virtual bool isImplicitlySizedArray() const { return isArray() && getArraySize() == UnsizedArraySize && qualifier.storage != EvqBuffer; }
-    virtual bool isRuntimeSizedArray()    const { return isArray() && getArraySize() == UnsizedArraySize && qualifier.storage == EvqBuffer; }
+    virtual bool isExplicitlySizedArray() const { return isArray() && getOuterArraySize() != UnsizedArraySize; }
+    virtual bool isImplicitlySizedArray() const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage != EvqBuffer; }
+    virtual bool isRuntimeSizedArray()    const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage == EvqBuffer; }
     virtual bool isStruct() const { return structure != nullptr; }
     virtual bool isImage() const { return basicType == EbtSampler && getSampler().image; }
 
@@ -1125,22 +1130,27 @@ public:
         assert(type.arraySizes != nullptr);
         *arraySizes = *type.arraySizes;
     }
-    void setArraySizes(TArraySizes* s)
+    void newArraySizes(const TArraySizes& s)
     {
         // For setting a fresh new set of array sizes, not yet worrying about sharing.
         arraySizes = new TArraySizes;
-        assert(s != nullptr);
-        *arraySizes = *s;
+        *arraySizes = s;
+    }
+    void addArrayOuterSizes(const TArraySizes& s)
+    {
+        if (arraySizes == nullptr)
+            newArraySizes(s);
+        else
+            arraySizes->addOuterSizes(s);
     }
-    void setArraySizes(const TType& type) { setArraySizes(type.arraySizes); }
-    void changeArraySize(int s) { arraySizes->changeOuterSize(s); }
+    void changeOuterArraySize(int s) { arraySizes->changeOuterSize(s); }
     void setImplicitArraySize (int s) { arraySizes->setImplicitSize(s); }
 
     // Recursively make the implicit array size the explicit array size, through the type tree.
     void adoptImplicitArraySizes()
     {
         if (isImplicitlySizedArray())
-            changeArraySize(getImplicitArraySize());
+            changeOuterArraySize(getImplicitArraySize());
         if (isStruct()) {
             for (int i = 0; i < (int)structure->size(); ++i)
                 (*structure)[i].type->adoptImplicitArraySizes();
@@ -1151,7 +1161,7 @@ public:
     {
         return TType::getBasicString(basicType);
     }
-    
+
     static const char* getBasicString(TBasicType t)
     {
         switch (t) {
@@ -1242,12 +1252,12 @@ public:
             p += snprintf(p, end - p, "writeonly ");
         p += snprintf(p, end - p, "%s ", getStorageQualifierString());
         if (arraySizes) {
-            if (arraySizes->getOuterSize() == UnsizedArraySize) {
-                p += snprintf(p, end - p, "implicitly-sized array of ");
-            } else {
-                for(int i = 0; i < (int)arraySizes->getNumDims() ; ++i) {
-                    p += snprintf(p, end - p, "%d-element array of ", (*arraySizes)[i]);
-                }
+            for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
+                int size = arraySizes->getDimSize(i);
+                if (size == 0)
+                    p += snprintf(p, end - p, "implicitly-sized array of ");
+                else
+                    p += snprintf(p, end - p, "%d-element array of ", arraySizes->getDimSize(i));
             }
         }
         if (qualifier.precision != EpqNone)
@@ -1310,10 +1320,8 @@ public:
         else
             components = vectorSize;
 
-        if (isArray()) {
-            // this function can only be used in paths that have a known array size
-            assert(isExplicitlySizedArray());
-            components *= getArraySize();
+        if (arraySizes != nullptr) {
+            components *= arraySizes->getCumulativeSize();
         }
 
         return components;
@@ -1371,7 +1379,14 @@ public:
     bool sameArrayness(const TType& right) const
     {
         return ((arraySizes == nullptr && right.arraySizes == nullptr) ||
-                (arraySizes && right.arraySizes && *arraySizes == *right.arraySizes));
+                (arraySizes != nullptr && right.arraySizes != nullptr && *arraySizes == *right.arraySizes));
+    }
+
+    // See if two type's arrayness match in everything except their outer dimension
+    bool sameInnerArrayness(const TType& right) const
+    {
+        assert(arraySizes != nullptr && right.arraySizes != nullptr);
+        return arraySizes->sameInnerArrayness(*right.arraySizes);
     }
 
     // See if two type's elements match in all ways except basic type
index 67f91e9..cc2cdab 100644 (file)
 
 namespace glslang {
 
-// This is used to mean there is no size yet, it is waiting to get a size from somewhere else.
-// Historically, this is not fully encapsulated, trying to catch them all...
+// This is used to mean there is no size yet (unsized), it is waiting to get a size from somewhere else.
 const int UnsizedArraySize = 0;
 
 //
 // TSmallArrayVector is used as the container for the set of sizes in TArraySizes.
 // It has generic-container semantics, while TArraySizes has array-of-array semantics.
+// That is, TSmallArrayVector should be more focused on mechanism and TArraySizes on policy.
 //
 struct TSmallArrayVector {
     //
@@ -101,9 +101,43 @@ struct TSmallArrayVector {
         sizes->push_back(e);
     }
 
+    void push_front(const TSmallArrayVector& newDims)
+    {
+        alloc();
+        sizes->insert(sizes->begin(), newDims.sizes->begin(), newDims.sizes->end());
+    }
+
+    void pop_front()
+    {
+        assert(sizes != nullptr && sizes->size() > 0);
+        if (sizes->size() == 1)
+            dealloc();
+        else
+            sizes->erase(sizes->begin());
+    }
+
+    // 'this' should currently not be holding anything, and copyNonFront
+    // will make it hold a copy of all but the first element of rhs.
+    // (This would be useful for making a type that is dereferenced by
+    // one dimension.)
+    void copyNonFront(const TSmallArrayVector& rhs)
+    {
+        assert(sizes == nullptr);
+        if (rhs.size() > 1) {
+            alloc();
+            sizes->insert(sizes->begin(), rhs.sizes->begin() + 1, rhs.sizes->end());
+        }
+    }
+
     unsigned int operator[](int i) const
     {
-        assert(sizes && (int)sizes->size() > i);
+        assert(sizes != nullptr  && (int)sizes->size() > i);
+        return (*sizes)[i];
+    }
+
+    unsigned int& operator[](int i)
+    {
+        assert(sizes != nullptr  && (int)sizes->size() > i);
         return (*sizes)[i];
     }
 
@@ -115,6 +149,7 @@ struct TSmallArrayVector {
             return false;
         return *sizes == *rhs.sizes;
     }
+    bool operator!=(const TSmallArrayVector& rhs) const { return ! operator==(rhs); }
 
 protected:
     TSmallArrayVector(const TSmallArrayVector&);
@@ -127,6 +162,7 @@ protected:
     void dealloc()
     {
         delete sizes;
+        sizes = nullptr;
     }
 
     TVector<unsigned int>* sizes; // will either hold such a pointer, or in the future, hold the two array sizes
@@ -134,11 +170,17 @@ protected:
 
 //
 // Represent an array, or array of arrays, to arbitrary depth.  This is not
-// done through a hierarchy of types, but localized into this single cumulative object.
+// done through a hierarchy of types in a type tree, rather all contiguous arrayness
+// in the type hierarchy is localized into this single cumulative object.
 //
 // The arrayness in TTtype is a pointer, so that it can be non-allocated and zero
 // for the vast majority of types that are non-array types.
 //
+// Order Policy: these are all identical:
+//  - left to right order within a contiguous set of ...[..][..][..]... in the source language
+//  - index order 0, 1, 2, ... within the 'sizes' member below
+//  - outer-most to inner-most
+//
 struct TArraySizes {
     POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 
@@ -155,13 +197,57 @@ struct TArraySizes {
 
     // translate from array-of-array semantics to container semantics
     int getNumDims() const { return sizes.size(); }
+    int getDimSize(int dim) const { return sizes[dim]; }
+    void setDimSize(int dim, int size) { sizes[dim] = size; }
     int getOuterSize() const { return sizes.front(); }
-    void setOuterSize(int s) { sizes.push_back((unsigned)s); }
+    int getCumulativeSize() const
+    {
+        int size = 1;
+        for (int d = 0; d < sizes.size(); ++d) {
+            // this only makes sense in paths that have a known array size
+            assert(sizes[d] != UnsizedArraySize);
+            size *= sizes[d];
+        }
+        return size;
+    }
+    void addInnerSize() { sizes.push_back((unsigned)UnsizedArraySize); }
+    void addInnerSize(int s) { sizes.push_back((unsigned)s); }
     void changeOuterSize(int s) { sizes.changeFront((unsigned)s); }
     int getImplicitSize() const { return (int)implicitArraySize; }
     void setImplicitSize(int s) { implicitArraySize = s; }
-    int operator[](int i) const { return sizes[i]; }
-    bool operator==(const TArraySizes& rhs) const { return sizes == rhs.sizes; }
+    bool isInnerImplicit() const
+    {
+        for (int d = 1; d < sizes.size(); ++d) {
+            if (sizes[d] == (unsigned)UnsizedArraySize)
+                return true;
+        }
+
+        return false;
+    }
+    void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); }
+    void dereference() { sizes.pop_front(); }
+    void copyDereferenced(const TArraySizes& rhs)
+    {
+        assert(sizes.size() == 0);
+        if (rhs.sizes.size() > 1)
+            sizes.copyNonFront(rhs.sizes);
+    }
+
+    bool sameInnerArrayness(const TArraySizes& rhs) const
+    {
+        if (sizes.size() != rhs.sizes.size())
+            return false;
+
+        for (int d = 1; d < sizes.size(); ++d) {
+            if (sizes[d] != rhs.sizes[d])
+                return false;
+        }
+
+        return true;
+    }
+
+    bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
+    bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
 
 protected:
     TSmallArrayVector sizes;
index f129ded..e7d7f4d 100644 (file)
@@ -3,4 +3,4 @@
 // For the date, it uses the current date (when then script is run).
 
 #define GLSLANG_REVISION "2.3.706"
-#define GLSLANG_DATE "09-Aug-2015"
+#define GLSLANG_DATE "10-Aug-2015"
index f3620c2..28b8ccd 100644 (file)
@@ -3276,9 +3276,9 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
         if (version == 100 || IncludeLegacy(version, profile) || (! ForwardCompatibility && profile != EEsProfile && version < 420)) {
             TPrecisionQualifier pq = profile == EEsProfile ? EpqMedium : EpqNone;
             TType fragData(EbtFloat, EvqFragColor, pq, 4);
-            TArraySizes* arraySizes = new TArraySizes;
-            arraySizes->setOuterSize(resources.maxDrawBuffers);
-            fragData.setArraySizes(arraySizes);
+            TArraySizes& arraySizes = *new TArraySizes;
+            arraySizes.addInnerSize(resources.maxDrawBuffers);
+            fragData.newArraySizes(arraySizes);
             symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
             SpecialQualifier("gl_FragData", EvqFragColor, EbvFragData, symbolTable);
         }
index 56f65a6..4f44376 100644 (file)
@@ -558,9 +558,9 @@ void TParseContext::checkIndex(const TSourceLoc& loc, const TType& type, int& in
         error(loc, "", "[", "index out of range '%d'", index);
         index = 0;
     } else if (type.isArray()) {
-        if (type.isExplicitlySizedArray() && index >= type.getArraySize()) {
+        if (type.isExplicitlySizedArray() && index >= type.getOuterArraySize()) {
             error(loc, "", "[", "array index out of range '%d'", index);
-            index = type.getArraySize() - 1;
+            index = type.getOuterArraySize() - 1;
         }
     } else if (type.isVector()) {
         if (index >= type.getVectorSize()) {
@@ -629,10 +629,10 @@ void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type)
         return;
 
     if (language == EShLangTessControl || language == EShLangTessEvaluation) {
-        if (type.getArraySize() != resources.maxPatchVertices) {
+        if (type.getOuterArraySize() != resources.maxPatchVertices) {
             if (type.isExplicitlySizedArray())
                 error(loc, "tessellation input array size must be gl_MaxPatchVertices or implicitly sized", "[]", "");
-            type.changeArraySize(resources.maxPatchVertices);
+            type.changeOuterArraySize(resources.maxPatchVertices);
         }
     }
 }
@@ -662,7 +662,7 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm
     if (symbolNode->getType().isImplicitlySizedArray()) {
         int newSize = getIoArrayImplicitSize();
         if (newSize)
-            symbolNode->getWritableType().changeArraySize(newSize);
+            symbolNode->getWritableType().changeOuterArraySize(newSize);
     }
 }
 
@@ -710,8 +710,8 @@ int TParseContext::getIoArrayImplicitSize() const
 void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name)
 {
     if (type.isImplicitlySizedArray())
-        type.changeArraySize(requiredSize);
-    else if (type.getArraySize() != requiredSize) {
+        type.changeOuterArraySize(requiredSize);
+    else if (type.getOuterArraySize() != requiredSize) {
         if (language == EShLangGeometry)
             error(loc, "inconsistent input primitive for array size of", feature, name.c_str());
         else if (language == EShLangTessControl)
@@ -1203,7 +1203,7 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
                         error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method");
                 }
             } else
-                length = type.getArraySize();
+                length = type.getOuterArraySize();
         } else if (type.isMatrix())
             length = type.getMatrixCols();
         else if (type.isVector())
@@ -1993,17 +1993,41 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
             error(loc, "array constructor must have at least one argument", "constructor", "");
             return true;
         }
+
         if (type.isImplicitlySizedArray()) {
             // auto adapt the constructor type to the number of arguments
-            type.changeArraySize(function.getParamCount());
-        } else if (type.getArraySize() != function.getParamCount()) {
+            type.changeOuterArraySize(function.getParamCount());
+        } else if (type.getOuterArraySize() != function.getParamCount()) {
             error(loc, "array constructor needs one argument per array element", "constructor", "");
             return true;
         }
+
+        if (type.isArrayOfArrays()) {
+            // Types have to match, but we're still making the type.
+            // Finish making the type, and the comparison is done later
+            // when checking for conversion.
+            TArraySizes& arraySizes = type.getArraySizes();
+
+            // At least the dimensionalities have to match.
+            if (! function[0].type->isArray() || arraySizes.getNumDims() != function[0].type->getArraySizes().getNumDims() + 1) {
+                error(loc, "array constructor argument not correct type to construct array element", "constructior", "");
+                return true;
+            }
+
+            if (arraySizes.isInnerImplicit()) {
+                // "Arrays of arrays ..., and the size for any dimension is optional"
+                // That means we need to adopt (from the first argument) the other array sizes into the type.
+                for (int d = 1; d < arraySizes.getNumDims(); ++d) {
+                    if (arraySizes.getDimSize(d) == UnsizedArraySize) {
+                        arraySizes.setDimSize(d, function[0].type->getArraySizes().getDimSize(d - 1));
+                    }
+                }
+            }
+        }
     }
 
-    if (arrayArg && op != EOpConstructStruct) {
-        error(loc, "constructing from a non-dereferenced array", "constructor", "");
+    if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) {
+        error(loc, "constructing non-array constituent from array argument", "constructor", "");
         return true;
     }
 
@@ -2490,13 +2514,13 @@ bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type)
     if (type.getQualifier().storage == EvqVaryingOut && language == EShLangVertex) {
         if (type.isArrayOfArrays())
             requireProfile(loc, ~EEsProfile, "vertex-shader array-of-array output");
-        else if (type.getArraySize() && type.isStruct())
+        else if (type.isStruct())
             requireProfile(loc, ~EEsProfile, "vertex-shader array-of-struct output");
     }
     if (type.getQualifier().storage == EvqVaryingIn && language == EShLangFragment) {
         if (type.isArrayOfArrays())
             requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array input");
-        else if (type.getArraySize() && type.isStruct())
+        else if (type.isStruct())
             requireProfile(loc, ~EEsProfile, "fragment-shader array-of-struct input");
     }
 
@@ -2522,11 +2546,24 @@ void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& typ
     }
 }
 
-void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& qualifier, int size, bool initializer)
+void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TArraySizes* arraySizes, bool initializer)
 {
-    // desktop always allows unsized variable arrays,
-    // ES always allows them if there is an initializer present to get the size from
-    if (parsingBuiltins || profile != EEsProfile || initializer)
+    assert(arraySizes);
+
+    // always allow special built-in ins/outs sized to topologies
+    if (parsingBuiltins)
+        return;
+
+    // always allow an initializer to set any unknown array sizes
+    if (initializer)
+        return;
+
+    // No environment lets any non-outer-dimension that's to be implicitly sized
+    if (arraySizes->isInnerImplicit())
+        error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
+
+    // desktop always allows outer-dimension-unsized variable arrays,
+    if (profile != EEsProfile)
         return;
 
     // for ES, if size isn't coming from an initializer, it has to be explicitly declared now,
@@ -2553,7 +2590,7 @@ void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& q
         break;
     }
 
-    arraySizeRequiredCheck(loc, size);
+    arraySizeRequiredCheck(loc, arraySizes->getOuterSize());
 }
 
 void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc)
@@ -2563,15 +2600,9 @@ void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc)
     requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature);
     profileRequires(loc, EEsProfile, 310, nullptr, feature);
     profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature);
-
-    static int once = false;
-    if (! once) {
-        warn(loc, feature, "Not supported yet.", "");
-        once = true;
-    }
 }
 
-void TParseContext::arrayDimCheck(const TSourceLoc& loc, TArraySizes* sizes1, TArraySizes* sizes2)
+void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TArraySizes* sizes1, const TArraySizes* sizes2)
 {
     if ((sizes1 && sizes2) ||
         (sizes1 && sizes1->getNumDims() > 1) ||
@@ -2579,13 +2610,28 @@ void TParseContext::arrayDimCheck(const TSourceLoc& loc, TArraySizes* sizes1, TA
         arrayOfArrayVersionCheck(loc);
 }
 
-void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TType* type, TArraySizes* sizes2)
+void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TType* type, const TArraySizes* sizes2)
 {
+    // skip checking for multiple dimensions on the type; it was caught earlier
     if ((type && type->isArray() && sizes2) ||
         (sizes2 && sizes2->getNumDims() > 1))
         arrayOfArrayVersionCheck(loc);
 }
 
+// Merge array dimensions listed in 'sizes' onto the type's array dimensions.
+//
+// From the spec: "vec4[2] a[3]; // size-3 array of size-2 array of vec4"
+//
+// That means, the 'sizes' go in front of the 'type' as outermost sizes.
+// 'type' is the type part of the declaration (to the left)
+// 'sizes' is the arrayness tagged on the identifier (to the right)
+//
+void TParseContext::arrayDimMerge(TType& type, const TArraySizes* sizes)
+{
+    if (sizes)
+        type.addArrayOuterSizes(*sizes);
+}
+
 //
 // Do all the semantic checking for declaring or redeclaring an array, with and
 // without a size, and make the right changes to the symbol table.
@@ -2642,19 +2688,25 @@ void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, con
         error(loc, "redeclaring non-array as array", identifier.c_str(), "");
         return;
     }
-    if (existingType.isExplicitlySizedArray()) {
-        // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size
-        if (! (isIoResizeArray(type) && existingType.getArraySize() == type.getArraySize()))
-            error(loc, "redeclaration of array with size", identifier.c_str(), "");
+
+    if (! existingType.sameElementType(type)) {
+        error(loc, "redeclaration of array with a different element type", identifier.c_str(), "");
         return;
     }
 
-    if (! existingType.sameElementType(type)) {
-        error(loc, "redeclaration of array with a different type", identifier.c_str(), "");
+    if (! existingType.sameInnerArrayness(type)) {
+        error(loc, "redeclaration of array with a different array dimensions or sizes", identifier.c_str(), "");
         return;
     }
 
-    arrayLimitCheck(loc, identifier, type.getArraySize());
+    if (existingType.isExplicitlySizedArray()) {
+        // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size
+        if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize()))
+            error(loc, "redeclaration of array with size", identifier.c_str(), "");
+        return;
+    }
+
+    arrayLimitCheck(loc, identifier, type.getOuterArraySize());
 
     existingType.updateArraySizes(type);
 
@@ -2954,7 +3006,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
             else if (! oldType.sameArrayness(newType) && oldType.isExplicitlySizedArray())
                 error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), "");
             else if (newType.isArray())
-                arrayLimitCheck(loc, member->type->getFieldName(), newType.getArraySize());
+                arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize());
             if (newType.getQualifier().isMemory())
                 error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
             if (newType.getQualifier().hasLayout())
@@ -2990,10 +3042,10 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
     else if (type.isArray()) {
         if (type.isExplicitlySizedArray() && arraySizes->getOuterSize() == UnsizedArraySize)
             error(loc, "block already declared with size, can't redeclare as implicitly-sized", blockName.c_str(), "");
-        else if (type.isExplicitlySizedArray() && type.getArraySize() != arraySizes->getOuterSize())
+        else if (type.isExplicitlySizedArray() && type.getArraySizes() != *arraySizes)
             error(loc, "cannot change array size of redeclared block", blockName.c_str(), "");
         else if (type.isImplicitlySizedArray() && arraySizes->getOuterSize() != UnsizedArraySize)
-            type.changeArraySize(arraySizes->getOuterSize());
+            type.changeOuterArraySize(arraySizes->getOuterSize());
     }
 
     symbolTable.insert(*block);
@@ -3224,7 +3276,7 @@ void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init,
     inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable);
 }
 
-// Do limit checks against for all built-in arrays.
+// Do limit checks for built-in arrays.
 void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size)
 {
     if (identifier.compare("gl_TexCoord") == 0)
@@ -3806,7 +3858,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
         if (type.getBasicType() == EbtSampler) {
             int lastBinding = qualifier.layoutBinding;
             if (type.isArray())
-                lastBinding += type.getArraySize();
+                lastBinding += type.getCumulativeArraySize();
             if (lastBinding >= resources.maxCombinedTextureImageUnits)
                 error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : "");
         }
@@ -3990,7 +4042,7 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol)
             // Check for overlap
             int numOffsets = 4;
             if (symbol.getType().isArray())
-                numOffsets *= symbol.getType().getArraySize();
+                numOffsets *= symbol.getType().getCumulativeArraySize();
             int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets);
             if (repeated >= 0)
                 error(loc, "atomic counters sharing the same offset:", "offset", "%d", repeated);
@@ -4138,6 +4190,9 @@ void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType
 // Returns a subtree node that computes an initializer, if needed.
 // Returns nullptr if there is no code to execute for initialization.
 //
+// 'publicType' is the type part of the declaration (to the left)
+// 'arraySizes' is the arrayness tagged on the identifier (to the right)
+//
 TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer)
 {
     TType type(publicType);
@@ -4170,13 +4225,12 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
     if (arraySizes || type.isArray()) {
         // Arrayness is potentially coming both from the type and from the 
         // variable: "int[] a[];" or just one or the other.
-        // For now, arrays of arrays aren't supported, so it's just one or the
-        // other.  Move it to the type, so all arrayness is part of the type.
+        // Merge it all to the type, so all arrayness is part of the type.
         arrayDimCheck(loc, &type, arraySizes);
-        if (arraySizes)
-            type.setArraySizes(arraySizes);
+        arrayDimMerge(type, arraySizes);
 
-        arrayUnsizedCheck(loc, type.getQualifier(), type.getArraySize(), initializer != nullptr);
+        // Check that implicit sizing is only where allowed.
+        arrayUnsizedCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr);
 
         if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
             declareArray(loc, identifier, type, symbol, newDeclaration);
@@ -4299,10 +4353,21 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
         return nullptr;
     }
 
-    // Fix arrayness if variable is unsized, getting size from the initializer
-    if (initializer->getType().isArray() && initializer->getType().isExplicitlySizedArray() &&
+    // Fix outer arrayness if variable is unsized, getting size from the initializer
+    if (initializer->getType().isExplicitlySizedArray() &&
         variable->getType().isImplicitlySizedArray())
-        variable->getWritableType().changeArraySize(initializer->getType().getArraySize());
+        variable->getWritableType().changeOuterArraySize(initializer->getType().getOuterArraySize());
+
+    // Inner arrayness can also get set by an initializer
+    if (initializer->getType().isArrayOfArrays() && variable->getType().isArrayOfArrays() &&
+        initializer->getType().getArraySizes()->getNumDims() ==
+           variable->getType().getArraySizes()->getNumDims()) {
+        // adopt unsized sizes from the initializer's sizes
+        for (int d = 1; d < variable->getType().getArraySizes()->getNumDims(); ++d) {
+            if (variable->getType().getArraySizes()->getDimSize(d) == UnsizedArraySize)
+                variable->getWritableType().getArraySizes().setDimSize(d, initializer->getType().getArraySizes()->getDimSize(d));
+        }
+    }
 
     // Uniform and global consts require a constant initializer
     if (qualifier == EvqUniform && initializer->getType().getQualifier().storage != EvqConst) {
@@ -4390,9 +4455,20 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
         // The type's array might be unsized, which could be okay, so base sizes on the size of the aggregate.
         // Later on, initializer execution code will deal with array size logic.
         TType arrayType;
-        arrayType.shallowCopy(type);
-        arrayType.setArraySizes(type);
-        arrayType.changeArraySize((int)initList->getSequence().size());
+        arrayType.shallowCopy(type);                     // sharing struct stuff is fine
+        arrayType.newArraySizes(*type.getArraySizes());  // but get a fresh copy of the array information, to edit below
+
+        // edit array sizes to fill in unsized dimensions
+        arrayType.changeOuterArraySize((int)initList->getSequence().size());
+        TIntermTyped* firstInit = initList->getSequence()[0]->getAsTyped();
+        if (arrayType.isArrayOfArrays() && firstInit->getType().isArray() &&
+            arrayType.getArraySizes().getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) {
+            for (int d = 1; d < arrayType.getArraySizes().getNumDims(); ++d) {
+                if (arrayType.getArraySizes().getDimSize(d) == UnsizedArraySize)
+                    arrayType.getArraySizes().setDimSize(d, firstInit->getType().getArraySizes()->getDimSize(d - 1));
+            }
+        }
+
         TType elementType(arrayType, 0); // dereferenced type
         for (size_t i = 0; i < initList->getSequence().size(); ++i) {
             initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
@@ -4455,9 +4531,11 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
         memberTypes = type.getStruct()->begin();
 
     TType elementType;
-    elementType.shallowCopy(type);
-    if (type.isArray())
-        elementType.dereference();
+    if (type.isArray()) {
+        TType dereferenced(type, 0);
+        elementType.shallowCopy(dereferenced);
+    } else
+        elementType.shallowCopy(type);
 
     bool singleArg;
     if (aggrNode) {
@@ -4471,11 +4549,11 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
     TIntermTyped *newNode;
     if (singleArg) {
         // If structure constructor or array constructor is being called
-        // for only one parameter inside the structure, we need to call constructStruct function once.
+        // for only one parameter inside the structure, we need to call constructAggregate function once.
         if (type.isArray())
-            newNode = constructStruct(node, elementType, 1, node->getLoc());
+            newNode = constructAggregate(node, elementType, 1, node->getLoc());
         else if (op == EOpConstructStruct)
-            newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLoc());
+            newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc());
         else
             newNode = constructBuiltIn(type, op, node->getAsTyped(), node->getLoc(), false);
 
@@ -4501,9 +4579,9 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
     for (TIntermSequence::iterator p = sequenceVector.begin();
                                    p != sequenceVector.end(); p++, paramCount++) {
         if (type.isArray())
-            newNode = constructStruct(*p, elementType, paramCount+1, node->getLoc());
+            newNode = constructAggregate(*p, elementType, paramCount+1, node->getLoc());
         else if (op == EOpConstructStruct)
-            newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
+            newNode = constructAggregate(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
         else
             newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true);
 
@@ -4610,12 +4688,12 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
     return intermediate.setAggregateOperator(newNode, op, type, loc);
 }
 
-// This function tests for the type of the parameters to the structures constructors. Raises
+// This function tests for the type of the parameters to the structure or array constructor. Raises
 // an error message if the expected type does not match the parameter passed to the constructor.
 //
 // Returns nullptr for an error or the input node itself if the expected and the given parameter types match.
 //
-TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc)
+TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc)
 {
     TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
     if (! converted || converted->getType() != type) {
@@ -4635,9 +4713,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
 {
     blockStageIoCheck(loc, currentBlockQualifier);
     blockQualifierCheck(loc, currentBlockQualifier);
-    if (arraySizes)
-        arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes->getOuterSize(), false);
-    arrayDimCheck(loc, arraySizes, nullptr);
+    if (arraySizes) {
+        arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes, false);
+        arrayDimCheck(loc, arraySizes, 0);
+    }
 
     // fix and check for member storage qualifiers and types that don't belong within a block
     for (unsigned int member = 0; member < typeList.size(); ++member) {
@@ -4766,7 +4845,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
 
     TType blockType(&typeList, *blockName, currentBlockQualifier);
     if (arraySizes)
-        blockType.setArraySizes(arraySizes);
+        blockType.newArraySizes(*arraySizes);
     else
         ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName);
 
index e008c0f..81c9eac 100644 (file)
@@ -138,10 +138,11 @@ public:
     bool arrayError(const TSourceLoc&, const TType&);
     void arraySizeRequiredCheck(const TSourceLoc&, int size);
     void structArrayCheck(const TSourceLoc&, const TType& structure);
-    void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, int size, bool initializer);
+    void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer);
     void arrayOfArrayVersionCheck(const TSourceLoc&);
-    void arrayDimCheck(const TSourceLoc&, TArraySizes* sizes1, TArraySizes* sizes2);
-    void arrayDimCheck(const TSourceLoc&, const TType*, TArraySizes*);
+    void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2);
+    void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*);
+    void arrayDimMerge(TType& type, const TArraySizes* sizes);
     bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType);
     void boolCheck(const TSourceLoc&, const TIntermTyped*);
     void boolCheck(const TSourceLoc&, const TPublicType&);
@@ -189,7 +190,7 @@ public:
     void declareTypeDefaults(const TSourceLoc&, const TPublicType&);
     TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
     TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator);
-    TIntermTyped* constructStruct(TIntermNode*, const TType&, int, const TSourceLoc&);
+    TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
     TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
     void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
     void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
index e07a984..3a401ec 100644 (file)
@@ -113,7 +113,7 @@ void TType::buildMangledName(TString& mangledName)
         const int maxSize = 11;
         char buf[maxSize];
         for (int i = 0; i < arraySizes->getNumDims(); ++i) {
-            snprintf(buf, maxSize, "%d", (*arraySizes)[i]);
+            snprintf(buf, maxSize, "%d", arraySizes->getDimSize(i));
             mangledName += '[';
             mangledName += buf;
             mangledName += ']';
index 2726014..0c87757 100644 (file)
@@ -691,7 +691,7 @@ declaration
 
         // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope
         parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]);
-               parseContext.setDefaultPrecision($1.loc, $3, $2.qualifier.precision);
+        parseContext.setDefaultPrecision($1.loc, $3, $2.qualifier.precision);
         $$ = 0;
     }
     | block_structure SEMICOLON {
@@ -1240,7 +1240,7 @@ array_specifier
     : LEFT_BRACKET RIGHT_BRACKET {
         $$.loc = $1.loc;
         $$.arraySizes = new TArraySizes;
-        $$.arraySizes->setOuterSize(0);
+        $$.arraySizes->addInnerSize();
     }
     | LEFT_BRACKET constant_expression RIGHT_BRACKET {
         $$.loc = $1.loc;
@@ -1248,18 +1248,18 @@ array_specifier
 
         int size;
         parseContext.arraySizeCheck($2->getLoc(), $2, size);
-        $$.arraySizes->setOuterSize(size);
+        $$.arraySizes->addInnerSize(size);
     }
     | array_specifier LEFT_BRACKET RIGHT_BRACKET {
         $$ = $1;
-        $$.arraySizes->setOuterSize(0);
+        $$.arraySizes->addInnerSize();
     }
     | array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
         $$ = $1;
 
         int size;
         parseContext.arraySizeCheck($3->getLoc(), $3, size);
-        $$.arraySizes->setOuterSize(size);
+        $$.arraySizes->addInnerSize(size);
     }
     ;
 
@@ -1903,19 +1903,19 @@ precision_qualifier
         parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "highp precision qualifier");
         $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
         if (parseContext.profile == EEsProfile)
-                   $$.qualifier.precision = EpqHigh;
+            $$.qualifier.precision = EpqHigh;
     }
     | MEDIUM_PRECISION {
         parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "mediump precision qualifier");
         $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
         if (parseContext.profile == EEsProfile)
-               $$.qualifier.precision = EpqMedium;
+            $$.qualifier.precision = EpqMedium;
     }
     | LOW_PRECISION {
         parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "lowp precision qualifier");
         $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
         if (parseContext.profile == EEsProfile)
-               $$.qualifier.precision = EpqLow;
+            $$.qualifier.precision = EpqLow;
     }
     ;
 
@@ -2020,7 +2020,7 @@ struct_declarator
         $$.type = new TType(EbtVoid);
         $$.loc = $1.loc;
         $$.type->setFieldName(*$1.string);
-        $$.type->setArraySizes($2.arraySizes);
+        $$.type->newArraySizes(*$2.arraySizes);
     }
     ;
 
@@ -2354,7 +2354,7 @@ jump_statement
                 $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc);
             }
         } else
-                   $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc);
+            $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc);
     }
     | DISCARD SEMICOLON {
         parseContext.requireStage($1.loc, EShLangFragment, "discard");
index eafe135..751d0c3 100644 (file)
@@ -240,9 +240,7 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
 void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
 {
     if (type.isImplicitlySizedArray() && unitType.isArray()) {
-        int newImplicitArraySize = unitType.getArraySize();
-        if (newImplicitArraySize == 0)
-            newImplicitArraySize = unitType.getImplicitArraySize();
+        int newImplicitArraySize = unitType.isImplicitlySizedArray() ? unitType.getImplicitArraySize() : unitType.getOuterArraySize();
         if (newImplicitArraySize > type.getImplicitArraySize ())
             type.setImplicitArraySize(newImplicitArraySize);
     }
@@ -623,7 +621,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
     int size;
     if (qualifier.isUniformOrBuffer()) {
         if (type.isArray())
-            size = type.getArraySize();
+            size = type.getCumulativeArraySize();
         else
             size = 1;
     } else {
@@ -693,12 +691,13 @@ int TIntermediate::computeTypeLocationSize(const TType& type) const
     // "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n 
     // consecutive locations..."
     if (type.isArray()) {
+        // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
         TType elementType(type, 0);
         if (type.isImplicitlySizedArray()) {
             // TODO: are there valid cases of having an implicitly-sized array with a location?  If so, running this code too early.
             return computeTypeLocationSize(elementType);
         } else
-            return type.getArraySize() * computeTypeLocationSize(elementType);
+            return type.getOuterArraySize() * computeTypeLocationSize(elementType);
     }
 
     // "The locations consumed by block and structure members are determined by applying the rules above 
@@ -783,10 +782,11 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
     // that component's size.  Aggregate types are flattened down to the component
     // level to get this sequence of components."
 
-    if (type.isArray()) {
+    if (type.isArray()) {        
+        // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
         assert(type.isExplicitlySizedArray());
         TType elementType(type, 0);
-        return type.getArraySize() * computeTypeXfbSize(elementType, containsDouble);
+        return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble);
     }
 
     if (type.isStruct()) {
@@ -913,12 +913,13 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, bool std140)
 
     // rules 4, 6, and 8
     if (type.isArray()) {
+        // TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
         TType derefType(type, 0);
         alignment = getBaseAlignment(derefType, size, std140);
         if (std140)
             alignment = std::max(baseAlignmentVec4Std140, alignment);
         RoundToPow2(size, alignment);
-        size *= type.getArraySize();
+        size *= type.getOuterArraySize();
         return alignment;
     }
 
index 3d96743..85caff7 100644 (file)
@@ -166,7 +166,7 @@ public:
             switch (visitNode->getOp()) {
             case EOpIndexIndirect:
                 // Visit all the indices of this array, and for each one add on the remaining dereferencing
-                for (int i = 0; i < visitNode->getLeft()->getType().getArraySize(); ++i) {
+                for (int i = 0; i < visitNode->getLeft()->getType().getOuterArraySize(); ++i) {
                     TString newBaseName = name;
                     if (baseType.getBasicType() != EbtBlock)
                         newBaseName.append(TString("[") + String(i) + "]");
@@ -201,7 +201,7 @@ public:
             if (terminalType->isArray()) {
                 // Visit all the indices of this array, and for each one,
                 // fully explode the remaining aggregate to dereference
-                for (int i = 0; i < terminalType->getArraySize(); ++i) {
+                for (int i = 0; i < terminalType->getOuterArraySize(); ++i) {
                     TString newBaseName = name;
                     newBaseName.append(TString("[") + String(i) + "]");
                     TType derefType(*terminalType, 0);
@@ -286,7 +286,7 @@ public:
             anonymous = IsAnonymous(base->getName());
             if (base->getType().isArray()) {
                 assert(! anonymous);
-                for (int e = 0; e < base->getType().getArraySize(); ++e)
+                for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e)
                     blockIndex = addBlockName(base->getType().getTypeName() + "[" + String(e) + "]", getBlockSize(base->getType()));
             } else
                 blockIndex = addBlockName(base->getType().getTypeName(), getBlockSize(base->getType()));
@@ -610,7 +610,7 @@ public:
 
     int mapToGlArraySize(const TType& type)
     {
-        return type.isArray() ? type.getArraySize() : 1;
+        return type.isArray() ? type.getOuterArraySize() : 1;
     }
 
     typedef std::list<TIntermAggregate*> TFunctionStack;