Additional semantic checking for tessellation shaders and related clean up:
authorJohn Kessenich <cepheus@frii.com>
Wed, 18 Dec 2013 03:06:24 +0000 (03:06 +0000)
committerJohn Kessenich <cepheus@frii.com>
Wed, 18 Dec 2013 03:06:24 +0000 (03:06 +0000)
 - non-arrayed geometry inputs and tessellation-control outputs
 - include user blocks in i/o array resizing based on primitive type
 - things belonging only to 'in' or 'out' are verified only on 'in' or 'out'
 - invocation number changing
 - move shader-scoped qualifier checking into its class
 - remove an incidental union of two levels of the node hierarchy in the yacc stack
 - remove layout(location=) default tracking when setting on a variable

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24551 e7fa87d3-cd2b-0410-9028-fcbf551c1848

20 files changed:
Test/150.geom
Test/300layout.vert
Test/400.geom
Test/400.tese
Test/420.geom
Test/420.tesc
Test/baseResults/150.geom.out
Test/baseResults/400.geom.out
Test/baseResults/400.tese.out
Test/baseResults/420.geom.out
Test/baseResults/420.tesc.out
Test/baseResults/specExamples.vert.out
Todo.txt
glslang/Include/Types.h
glslang/Include/revision.h
glslang/MachineIndependent/Initialize.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h
glslang/MachineIndependent/glslang.y
glslang/MachineIndependent/localintermediate.h

index 70ce7f2..ffb7286 100644 (file)
@@ -2,7 +2,7 @@
 \r
 in fromVertex {\r
     vec3 color;\r
-} fromV;\r
+} fromV[];\r
 \r
 out toFragment {\r
     vec3 color;\r
@@ -29,7 +29,7 @@ void main()
     EmitStreamVertex(1);    // ERROR\r
     EndStreamPrimitive(0);  // ERROR\r
 \r
-    color = fromV.color;\r
+    color = fromV[0].color;\r
     gl_ClipDistance[3] = gl_in[1].gl_ClipDistance[2];\r
     gl_Position = gl_in[0].gl_Position;\r
     gl_PointSize = gl_in[3].gl_PointSize;\r
@@ -72,7 +72,7 @@ layout(line_strip, points, stream = 3) out; // ERROR, changing output primitive
 layout(triangle_strip) in; // ERROR, not an input primitive\r
 layout(triangle_strip) uniform; // ERROR\r
 layout(triangle_strip) out vec4 badv4;  // ERROR, not on a variable\r
-layout(triangle_strip) in vec4 bad2v4;  // ERROR, not on a variable or input\r
+layout(triangle_strip) in vec4 bad2v4[];  // ERROR, not on a variable or input\r
 layout(invocations = 3) out outbn { int a; }; // ERROR, not on a block\r
 out outbn2 {\r
     layout(invocations = 3)  int a; // ERROR, not on a block member\r
@@ -84,16 +84,16 @@ layout(lines) out;  // ERROR, not on output
 layout(lines_adjancency) in;\r
 layout(triangles) in;             // ERROR, can't change it\r
 layout(triangles_adjacency) in;   // ERROR, can't change it\r
-\r
-layout(invocations = 4, max_vertices = 300) out;\r
+layout(invocations = 4) in;\r
+layout(max_vertices = 300) out;\r
 \r
 in inbn {\r
     layout(stream = 2) int a;     // ERROR, stream on input\r
-} inbi;\r
+} inbi[];\r
 \r
 in sameName {\r
     int a15;\r
-};\r
+} insn[];\r
 \r
 out sameName {\r
     float f15;\r
index 6a863cf..b5e1dbe 100644 (file)
@@ -51,7 +51,7 @@ shared vec4 compute_only;  // ERROR
 
 layout(packed) uniform;
 
-layout(packed) float aoeuntaoeu;
+layout(packed) float aoeuntaoeu;  // ERROR, packed on variable
 
 layout(location = 40) in float cd;
 layout(location = 37) in mat4x3 ce; // ERROR, overlap
index 51c78fe..adb29f6 100644 (file)
@@ -6,12 +6,12 @@ void main()
     EndStreamPrimitive(0);\r
     EmitVertex();\r
     EndPrimitive();\r
-\r
     int id = gl_InvocationID;\r
 }\r
 \r
-layout(invocations = 3) out outbn { int a; }; // ERROR, not on a block\r
-layout(max_vertices = 127, invocations = 4) out;\r
+layout(invocations = 4) in outbn { int a; } bn[]; // ERROR, not on a block\r
+layout(max_vertices = 127) out;\r
+layout(invocations = 4) in;\r
 \r
 #extension GL_ARB_separate_shader_objects : enable\r
 \r
@@ -55,5 +55,19 @@ layout(location = 4) in vec4 cva[3];
 layout(location = 5) in vec4 cvb[3];\r
 layout(location = 2) in mat3 cmc[3];  // ERROR, collision\r
 \r
-patch in vec4 patchIn;              // ERROR\r
-patch out vec4 patchOut;            // ERROR
\ No newline at end of file
+patch in vec4 patchIn[];            // ERROR\r
+patch out vec4 patchOut;            // ERROR\r
+\r
+in float scalar;  // ERROR, no array\r
+\r
+layout(max_vertices = 127, invocations = 4) out;      // ERROR\r
+layout(invocations = 4, max_vertices = 127) in;       // ERROR\r
+layout(max_vertices = 127, invocations = 4) uniform;  // 2 ERRORs\r
+\r
+in inblockscalar {\r
+    int a;\r
+} inbls;  // ERROR, not an array\r
+\r
+in inblocka {\r
+    int a;\r
+} inbla[17];  // ERROR, wrong array size\r
index 20f52bb..2933493 100644 (file)
@@ -5,8 +5,8 @@ layout(quads, cw) in;
 layout(triangles) in;     // ERROR\r
 layout(isolines) in;      // ERROR\r
 \r
-layout(cw) in;\r
 layout(ccw) in;           // ERROR\r
+layout(cw) in;\r
 \r
 layout(fractional_odd_spacing) in;    \r
 layout(equal_spacing) in;              // ERROR\r
@@ -60,3 +60,13 @@ in gl_PerVertex
 {
 float gl_ClipDistance[1];
 } gl_in[gl_MaxPatchVertices];
+
+layout(quads, cw) out;     // ERROR\r
+layout(triangles) out;     // ERROR\r
+layout(isolines) out;      // ERROR\r
+layout(cw) out;            // ERROR\r
+layout(fractional_odd_spacing) out;    // ERROR\r
+layout(equal_spacing) out;             // ERROR\r
+layout(fractional_even_spacing) out;   // ERROR\r
+layout(point_mode) out;                // ERROR\r
+\r
index 2d63256..e883f0b 100644 (file)
@@ -23,7 +23,7 @@ void foo3()
 }\r
 \r
 uniform sampler2D s2D;\r
-in vec2 coord;\r
+in vec2 coord[];\r
 uniform vec4 v4;\r
 \r
 void foo4()\r
@@ -37,7 +37,7 @@ void foo4()
         ivec2(2,1)\r
     };\r
 \r
-    vec4 v = textureGatherOffset(s2D, coord, offsets[i].xy);\r
+    vec4 v = textureGatherOffset(s2D, coord[0], offsets[i].xy);\r
 \r
     offsets[i].xy = ivec2(3);  // ERROR\r
     v4.x = 3.2;                // ERROR\r
index e289238..dcee3ca 100644 (file)
@@ -25,3 +25,5 @@ void main()
     gl_out[1].gl_Position = p;\r
     gl_out[1].gl_PointSize = ps;        // ERROR\r
 }\r
+\r
+out float outf;  // ERROR, no array\r
index ab9c71e..e1c1ae4 100644 (file)
@@ -13,8 +13,8 @@ ERROR: 0:60: 'stream' : member cannot contradict block
 ERROR: 0:65: 'max_vertices' : can only apply to a standalone qualifier \r
 ERROR: 0:70: 'points' : cannot change previously set output primitive \r
 ERROR: 0:71: 'points' : cannot change previously set output primitive \r
-ERROR: 0:72: 'triangle_strip' : does not apply to input \r
-ERROR: 0:73: 'triangle_strip' : cannot be used here \r
+ERROR: 0:72: 'triangle_strip' : cannot apply to input \r
+ERROR: 0:73: 'triangle_strip' : cannot apply to: uniform\r
 ERROR: 0:74: 'triangle_strip' : can only apply to a standalone qualifier \r
 ERROR: 0:75: 'triangle_strip' : can only apply to a standalone qualifier \r
 ERROR: 0:76: 'invocations' : not supported for this version or the enabled extensions \r
@@ -23,10 +23,10 @@ ERROR: 0:78: 'invocations' : not supported for this version or the enabled exten
 ERROR: 0:78: 'invocations' : can only apply to a standalone qualifier \r
 ERROR: 0:79: 'max_vertices' : can only apply to a standalone qualifier \r
 ERROR: 0:80: 'triangle_strip' : can only apply to a standalone qualifier \r
-ERROR: 0:83: 'lines' : does not apply to output \r
+ERROR: 0:83: 'lines' : cannot apply to 'out' \r
 ERROR: 0:85: 'triangles' : cannot change previously set input primitive \r
 ERROR: 0:86: 'triangles_adjacency' : cannot change previously set input primitive \r
-ERROR: 0:88: 'invocations' : not supported for this version or the enabled extensions \r
+ERROR: 0:87: 'invocations' : not supported for this version or the enabled extensions \r
 ERROR: 0:88: 'max_vertices' : too large, must be less than gl_MaxGeometryOutputVertices \r
 ERROR: 0:91: 'stream' : member cannot contradict block \r
 ERROR: 29 compilation errors.  No code generated.\r
@@ -52,7 +52,10 @@ ERROR: node is still EOpNull!
 0:32          Constant:\r
 0:32            0 (const uint)\r
 0:32        color: direct index for structure (3-component vector of float)\r
-0:32          'fromV' (in block{color})\r
+0:32          direct index (block{color})\r
+0:32            'fromV' (in 4-element array of block{color})\r
+0:32            Constant:\r
+0:32              0 (const int)\r
 0:32          Constant:\r
 0:32            0 (const int)\r
 0:33      move second child to first child (float)\r
@@ -119,7 +122,7 @@ ERROR: node is still EOpNull!
 0:67          1.000000\r
 0:67          1.000000\r
 0:?   Linker Objects\r
-0:?     'fromV' (in block{color})\r
+0:?     'fromV' (in 4-element array of block{color})\r
 0:?     'toF' (layout(stream=0 ) out block{color})\r
 0:?     '__anon__0' (layout(stream=0 ) out block{color})\r
 0:?     'gl_in' (in 4-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})\r
@@ -134,13 +137,13 @@ ERROR: node is still EOpNull!
 0:?     'ouua7' (layout(stream=7 ) out block{a})\r
 0:?     'ov2s3' (layout(stream=3 ) out 4-component vector of float)\r
 0:?     'badv4' (layout(stream=3 ) out 4-component vector of float)\r
-0:?     'bad2v4' (in 4-component vector of float)\r
+0:?     'bad2v4' (in 4-element array of 4-component vector of float)\r
 0:?     '__anon__1' (layout(stream=3 ) out block{a})\r
 0:?     'outbi' (layout(stream=3 ) out block{a,b,c})\r
-0:?     'inbi' (in block{a})\r
-0:?     '__anon__2' (in block{a15})\r
-0:?     '__anon__3' (layout(stream=3 ) out block{f15})\r
-0:?     '__anon__4' (layout(column_major shared ) uniform block{b15})\r
+0:?     'inbi' (in 4-element array of block{a})\r
+0:?     'insn' (in 4-element array of block{a15})\r
+0:?     '__anon__2' (layout(stream=3 ) out block{f15})\r
+0:?     '__anon__3' (layout(column_major shared ) uniform block{b15})\r
 \r
 \r
 Linked geometry stage:\r
index a9d7408..58a17b7 100644 (file)
@@ -1,17 +1,24 @@
 400.geom\r
 Warning, version 400 is not yet complete; some version-specific features are present, but many are missing.\r
-ERROR: 0:13: 'invocations' : can only apply to a standalone qualifier \r
+ERROR: 0:12: 'invocations' : can only apply to a standalone qualifier \r
 ERROR: 0:20: 'patch' : not supported in this stage: geometry\r
 ERROR: 0:20: 'gl_PointSize' : cannot add layout to redeclared block member \r
 ERROR: 0:20: 'gl_PointSize' : cannot add patch to redeclared block member \r
 ERROR: 0:25: 'length' :  array must first be sized by a redeclaration or layout qualifier\r
 ERROR: 0:36: 'length' :  array must first be sized by a redeclaration or layout qualifier\r
-ERROR: 0:40: 'triangles' : inconsistent input primitive for array size colorBad\r
-ERROR: 0:44: 'triangles' : inconsistent input primitive for array size colorbad2\r
+ERROR: 0:40: 'triangles' : inconsistent input primitive for array size of colorBad\r
+ERROR: 0:44: 'triangles' : inconsistent input primitive for array size of colorbad2\r
 ERROR: 0:56: 'location' : repeated use of location 4\r
 ERROR: 0:58: 'patch' : not supported in this stage: geometry\r
 ERROR: 0:59: 'patch' : not supported in this stage: geometry\r
-ERROR: 11 compilation errors.  No code generated.\r
+ERROR: 0:61: 'in' : type must be an array: scalar\r
+ERROR: 0:63: 'invocations' : can only apply to 'in' \r
+ERROR: 0:64: 'max_vertices' : can only apply to 'out' \r
+ERROR: 0:65: 'max_vertices' : can only apply to 'out' \r
+ERROR: 0:65: 'invocations' : can only apply to 'in' \r
+ERROR: 0:67: 'in' : type must be an array: inbls\r
+ERROR: 0:71: 'triangles' : inconsistent input primitive for array size of inbla\r
+ERROR: 18 compilation errors.  No code generated.\r
 \r
 \r
 invocations = 4\r
@@ -30,10 +37,10 @@ ERROR: node is still EOpNull!
 0:6          0 (const int)\r
 0:7      EmitVertex (void)\r
 0:8      EndPrimitive (void)\r
-0:10      Sequence\r
-0:10        move second child to first child (int)\r
-0:10          'id' (int)\r
-0:10          'gl_InvocationID' (in int)\r
+0:9      Sequence\r
+0:9        move second child to first child (int)\r
+0:9          'id' (int)\r
+0:9          'gl_InvocationID' (in int)\r
 0:23  Function Definition: foo( (void)\r
 0:23    Function Parameters: \r
 0:25    Sequence\r
@@ -65,7 +72,7 @@ ERROR: node is still EOpNull!
 0:51      Constant:\r
 0:51        3 (const int)\r
 0:?   Linker Objects\r
-0:?     '__anon__0' (layout(stream=0 ) out block{a})\r
+0:?     'bn' (in 3-element array of block{a})\r
 0:?     'gl_in' (in 3-element array of block{gl_Position,gl_PointSize})\r
 0:?     'color' (in 3-element array of 4-component vector of float)\r
 0:?     'color2' (in 3-element array of 4-component vector of float)\r
@@ -75,8 +82,11 @@ ERROR: node is still EOpNull!
 0:?     'cva' (layout(location=4 ) in 3-element array of 4-component vector of float)\r
 0:?     'cvb' (layout(location=5 ) in 3-element array of 4-component vector of float)\r
 0:?     'cmc' (layout(location=2 ) in 3-element array of 3X3 matrix of float)\r
-0:?     'patchIn' (patch in 4-component vector of float)\r
+0:?     'patchIn' (patch in 3-element array of 4-component vector of float)\r
 0:?     'patchOut' (layout(stream=0 ) patch out 4-component vector of float)\r
+0:?     'scalar' (in float)\r
+0:?     'inbls' (in block{a})\r
+0:?     'inbla' (in 17-element array of block{a})\r
 \r
 \r
 Linked geometry stage:\r
index 763ca31..121f32f 100644 (file)
@@ -3,7 +3,7 @@ Warning, version 400 is not yet complete; some version-specific features are pre
 ERROR: 0:3: 'vertices' : there is no such layout identifier for this stage taking an assigned value \r
 ERROR: 0:5: 'triangles' : cannot change previously set input primitive \r
 ERROR: 0:6: 'isolines' : cannot change previously set input primitive \r
-ERROR: 0:9: 'ccw' : cannot change previously set vertex order \r
+ERROR: 0:8: 'ccw' : cannot change previously set vertex order \r
 ERROR: 0:12: 'equal_spacing' : cannot change previously set vertex spacing \r
 ERROR: 0:13: 'fractional_even_spacing' : cannot change previously set vertex spacing \r
 ERROR: 0:18: 'patch' : can only use on input in tessellation-evaluation shader \r
@@ -14,7 +14,16 @@ ERROR: 0:49: 'patch' : cannot use interpolation qualifiers with patch
 ERROR: 0:50: '' : can only have one auxiliary qualifier (centroid, patch, and sample) \r
 ERROR: 0:54: 'gl_PerVertex' : block already declared with size, can't redeclare as unsized \r
 ERROR: 0:59: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use \r
-ERROR: 14 compilation errors.  No code generated.\r
+ERROR: 0:64: 'quads' : cannot apply to 'out' \r
+ERROR: 0:64: 'cw' : can only apply to 'in' \r
+ERROR: 0:65: 'triangles' : cannot apply to 'out' \r
+ERROR: 0:66: 'isolines' : cannot apply to 'out' \r
+ERROR: 0:67: 'cw' : can only apply to 'in' \r
+ERROR: 0:68: 'fractional_odd_spacing' : can only apply to 'in' \r
+ERROR: 0:69: 'equal_spacing' : can only apply to 'in' \r
+ERROR: 0:70: 'fractional_even_spacing' : can only apply to 'in' \r
+ERROR: 0:71: 'point_mode' : can only apply to 'in' \r
+ERROR: 23 compilation errors.  No code generated.\r
 \r
 \r
 input primitive = quads\r
index fc6e6c9..6865fa9 100644 (file)
@@ -53,7 +53,10 @@ ERROR: node is still EOpNull!
 0:40          'v' (4-component vector of float)\r
 0:40          Function Call: textureGatherOffset(s21;vf2;vi2; (4-component vector of float)\r
 0:40            's2D' (uniform sampler2D)\r
-0:40            'coord' (in 2-component vector of float)\r
+0:40            direct index (2-component vector of float)\r
+0:40              'coord' (in 3-element array of 2-component vector of float)\r
+0:40              Constant:\r
+0:40                0 (const int)\r
 0:40            vector swizzle (2-component vector of int)\r
 0:40              indirect index (2-component vector of int)\r
 0:40                Constant:\r
@@ -115,7 +118,7 @@ ERROR: node is still EOpNull!
 0:?     'gl_in' (in 3-element array of block{gl_Position,gl_PointSize,gl_ClipDistance})\r
 0:?     'color3' (in 3-element array of 4-component vector of float)\r
 0:?     's2D' (uniform sampler2D)\r
-0:?     'coord' (in 2-component vector of float)\r
+0:?     'coord' (in 3-element array of 2-component vector of float)\r
 0:?     'v4' (uniform 4-component vector of float)\r
 0:?     '__anon__0' (layout(stream=0 ) out block{gl_PointSize,gl_ClipDistance})\r
 \r
index 4ffba0b..12794d1 100644 (file)
@@ -1,11 +1,12 @@
 420.tesc\r
 Warning, version 400 is not yet complete; some version-specific features are present, but many are missing.\r
-ERROR: 0:7: 'vertices' : inconsistent output number of vertices for array size gl_out\r
-ERROR: 0:11: 'vertices' : inconsistent output number of vertices for array size a\r
-ERROR: 0:12: 'vertices' : inconsistent output number of vertices for array size outb\r
+ERROR: 0:7: 'vertices' : inconsistent output number of vertices for array size of gl_out\r
+ERROR: 0:11: 'vertices' : inconsistent output number of vertices for array size of a\r
+ERROR: 0:12: 'vertices' : inconsistent output number of vertices for array size of outb\r
 ERROR: 0:26: 'gl_PointSize' :  no such field in structure \r
 ERROR: 0:26: 'assign' :  cannot convert from 'float' to 'block{gl_Position}'\r
-ERROR: 5 compilation errors.  No code generated.\r
+ERROR: 0:29: 'out' : type must be an array: outf\r
+ERROR: 6 compilation errors.  No code generated.\r
 \r
 \r
 vertices = 4\r
@@ -76,6 +77,7 @@ ERROR: node is still EOpNull!
 0:?     'a' (out 3-element array of int)\r
 0:?     'outb' (out 5-element array of int)\r
 0:?     'outc' (out 4-element array of int)\r
+0:?     'outf' (out float)\r
 \r
 \r
 Linked tessellation control stage:\r
index 29bc8c9..f7aa45c 100644 (file)
@@ -21,7 +21,7 @@ ERROR: 0:85: 'offset' : there is no such layout identifier for this stage taking
 ERROR: 0:85: 'binding' : requires block, or sampler/image, or atomic-counter type \r
 ERROR: 0:87: 'binding' : requires block, or sampler/image, or atomic-counter type \r
 ERROR: 0:89: 'offset' : there is no such layout identifier for this stage taking an assigned value \r
-WARNING: 0:89: '' : cannot set qualifier defaults when using a type and no identifier \r
+WARNING: 0:89: 'layout' : useless application of layout qualifier \r
 ERROR: 0:91: 'bar' : redefinition \r
 ERROR: 0:92: 'offset' : there is no such layout identifier for this stage taking an assigned value \r
 ERROR: 0:92: 'bar' : redefinition \r
index c3b9413..35e8a7e 100644 (file)
--- a/Todo.txt
+++ b/Todo.txt
@@ -17,6 +17,7 @@ Link Validation
       - 1.3: only statically used built-ins have to be redeclared as flat
       - 1.5: matching between gl_PerVertex blocks and gl_PerFragment blocks
       - 1.3: deprecated mixing fixed vertex/fragment stage with programmable fragment/vertex stage.
+      + 4.0: tessellation primitive, vertices, spacing, order, 
       - 4.3: compute shader not combined with any other stages
       - 4.3: remove cross-version linking restrictions.
       - 4.3: Allow mismatches in interpolation and auxiliary qualification across stages.
@@ -26,8 +27,8 @@ Link Validation
       - limits checking:
           + bindings
           - number of input/output compononents
-          - tessellation limits
-          - tessellation primitive array sizing consistency
+          + tessellation limits
+          + tessellation primitive array sizing consistency
           + Non ES: gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords
           + Non ES: gl_ClipDistance ...
           - ...
@@ -106,10 +107,10 @@ Shader Functionality to Implement/Finish
       + texel offset limit checking
       + 1.50: geometry shaders: max_vertices must be checked against gl_MaxGeometryOutputVertices (maybe at compile time)
     GLSL 4.0
-      - tessellation control stage and tessellation evaluation stage. Includes barrier() built-in for synchronization.
-        - patch in, patch out
-        - input/output arrays
-          - unsized array sizing to gl_MaxPatchVertices, including gl_in/gl_out
+      + tessellation control stage and tessellation evaluation stage. Includes barrier() built-in for synchronization.
+        + patch in, patch out
+        + input/output arrays
+          + unsized array sizing to gl_MaxPatchVertices, including gl_in/gl_out
         + built-in variables, functions, and constants verification
         + layout qualifiers for primitive types
       - Polymorphic functions: Run-time selection of what function gets called, through the new keyword subroutine.
index 872477d..83e5105 100644 (file)
@@ -471,6 +471,28 @@ struct TShaderQualifiers {
         order = EvoNone;
         pointMode = false;
     }
+
+    // Merge in characteristics from the 'src' qualifier.  They can override when
+    // set, but never erase when not set.
+    void merge(const TShaderQualifiers& src)
+    {
+        if (src.geometry != ElgNone)
+            geometry = src.geometry;
+        if (src.pixelCenterInteger)
+            pixelCenterInteger = src.pixelCenterInteger;
+        if (src.originUpperLeft)
+            originUpperLeft = src.originUpperLeft;
+        if (src.invocations != 0)
+            invocations = src.invocations;
+        if (src.vertices != 0)
+            vertices = src.vertices;
+        if (src.spacing != EvsNone)
+            spacing = src.spacing;
+        if (src.order != EvoNone)
+            order = src.order;
+        if (src.pointMode)
+            pointMode = true;
+    }
 };
 
 //
index 9f79c7f..fd61d29 100644 (file)
@@ -9,5 +9,5 @@
 // source have to figure out how to create revision.h just to get a build\r
 // going.  However, if it is not updated, it can be a version behind.\r
 \r
-#define GLSLANG_REVISION "24522"\r
-#define GLSLANG_DATE     "2013/12/13 12:26:54"\r
+#define GLSLANG_REVISION "24530"\r
+#define GLSLANG_DATE     "2013/12/16 16:58:15"\r
index 7e071e8..ac576f2 100644 (file)
@@ -1285,8 +1285,6 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "patch out float gl_TessLevelOuter[4];"
             "patch out float gl_TessLevelInner[2];"
             "\n");
-
-        // TODO 4.0 tessellation: do we also need to support the gl_VerticesOut mentioned in the extension specification?
     }
 
     //============================================================================
index d208056..c13c1da 100644 (file)
@@ -529,13 +529,25 @@ void TParseContext::handleIndexLimits(TSourceLoc loc, TIntermTyped* base, TInter
 }
 
 // Return true if this is a geometry shader input array or tessellation control output array.
-bool TParseContext::isIoResizeArray(const TType& type)
+bool TParseContext::isIoResizeArray(const TType& type) const
 {
     return type.isArray() &&
            ((language == EShLangGeometry    && type.getQualifier().storage == EvqVaryingIn) ||
             (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch));
 }
 
+// Issue any errors if the non-array object is missing arrayness WRT
+// shader I/O that has array requirements.
+// All arrayness checking is handled in array paths, this is for 
+void TParseContext::ioArrayCheck(TSourceLoc loc, const TType& type, const TString& identifier)
+{
+    if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
+        if ((language == EShLangGeometry    && type.getQualifier().storage == EvqVaryingIn) ||
+            (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch))
+            error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
+    }
+}
+
 // Handle a dereference of a geometry shader input array or tessellation control output array.
 // See ioArrayNodeResizeList comment in ParseHelper.h.
 //
@@ -615,9 +627,9 @@ void TParseContext::checkIoArrayConsistency(TSourceLoc loc, int requiredSize, co
         type.changeArraySize(requiredSize);
     else if (type.getArraySize() != requiredSize) {
         if (language == EShLangGeometry)
-            error(loc, "inconsistent input primitive for array size", feature, name.c_str());
+            error(loc, "inconsistent input primitive for array size of", feature, name.c_str());
         else if (language == EShLangTessControl)
-            error(loc, "inconsistent output number of vertices for array size", feature, name.c_str());
+            error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str());
         else
             assert(0);
     }
@@ -871,43 +883,14 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(TSourceLoc loc, TFunct
 //  - user function
 //  - subroutine call (not implemented yet)
 //
-TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCall, TIntermNode* intermNode, TIntermAggregate* intermAggregate)
+TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCall, TIntermNode* intermNode)
 {
     TIntermTyped* result = 0;
 
     TOperator op = fnCall->getBuiltInOp();
-    if (op == EOpArrayLength) {
-        if (fnCall->getParamCount() > 0)
-            error(loc, "method does not accept any arguments", fnCall->getName().c_str(), "");
-        int length = 0;
-        if (intermNode->getAsTyped() == 0 || ! intermNode->getAsTyped()->getType().isArray())
-            error(loc, "", fnCall->getName().c_str(), "can only be applied to an array");
-        else if (intermNode->getAsTyped()->getType().getArraySize() == 0) {
-            bool implicitlySized = false;
-            if (intermNode->getAsSymbolNode() && isIoResizeArray(intermNode->getAsTyped()->getType())) {
-                // We could be between a layout declaration that gives a built-in io array implicit size and 
-                // a user redeclaration of that array, meaning we have to substitute its implicit size here 
-                // without actually redeclaring the array.  (It is an error to use a member before the
-                // redeclaration, but not an error to use the array name itself.)
-                const TString& name = intermNode->getAsSymbolNode()->getName();
-                if (name == "gl_in" || name == "gl_out")
-                    length = getIoArrayImplicitSize();
-            }
-            if (length == 0) {
-                if (isIoResizeArray(intermNode->getAsTyped()->getType()))
-                    error(loc, "", fnCall->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier");
-                else
-                    error(loc, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");
-            }
-        } else
-            length = intermNode->getAsTyped()->getType().getArraySize();
-
-        if (length == 0)
-            length = 1;
-        TConstUnionArray unionArray(1);
-        unionArray[0].setIConst(length);
-        result = intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc);
-    } else if (op != EOpNull) {
+    if (op == EOpArrayLength)
+        result = handleLengthMethod(loc, fnCall, intermNode);
+    else if (op != EOpNull) {
         //
         // Then this should be a constructor.
         // Don't go through the symbol table for constructors.
@@ -949,7 +932,7 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal
                 }
             } else {
                 // This is a function call not mapped to built-in operation
-                result = intermediate.setAggregateOperator(intermAggregate, EOpFunctionCall, fnCandidate->getType(), loc);
+                result = intermediate.setAggregateOperator(intermNode, EOpFunctionCall, fnCandidate->getType(), loc);
                 result->getAsAggregate()->setName(fnCandidate->getMangledName());
 
                 // this is how we know whether the given function is a built-in function or a user-defined function
@@ -989,6 +972,43 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal
     return result;
 }
 
+// Do all processing handling object.length().
+// Return resulting tree node.
+TIntermTyped* TParseContext::handleLengthMethod(TSourceLoc loc, TFunction* fnCall, TIntermNode* intermNode)
+{
+    int length = 0;
+
+    if (fnCall->getParamCount() > 0)
+        error(loc, "method does not accept any arguments", fnCall->getName().c_str(), "");
+    if (intermNode->getAsTyped() == 0 || ! intermNode->getAsTyped()->getType().isArray())
+        error(loc, "", fnCall->getName().c_str(), "can only be applied to an array");
+    else if (intermNode->getAsTyped()->getType().getArraySize() == 0) {
+        bool implicitlySized = false;
+        if (intermNode->getAsSymbolNode() && isIoResizeArray(intermNode->getAsTyped()->getType())) {
+            // We could be between a layout declaration that gives a built-in io array implicit size and 
+            // a user redeclaration of that array, meaning we have to substitute its implicit size here 
+            // without actually redeclaring the array.  (It is an error to use a member before the
+            // redeclaration, but not an error to use the array name itself.)
+            const TString& name = intermNode->getAsSymbolNode()->getName();
+            if (name == "gl_in" || name == "gl_out")
+                length = getIoArrayImplicitSize();
+        }
+        if (length == 0) {
+            if (isIoResizeArray(intermNode->getAsTyped()->getType()))
+                error(loc, "", fnCall->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier");
+            else
+                error(loc, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");
+        }
+    } else
+        length = intermNode->getAsTyped()->getType().getArraySize();
+
+    if (length == 0)
+        length = 1;
+    TConstUnionArray unionArray(1);
+    unionArray[0].setIConst(length);
+
+    return intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc);
+}
 //
 // Do additional checking of built-in function calls that were not mapped
 // to built-in operations (e.g., texturing functions).
@@ -2696,8 +2716,7 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
                 return;
             }
         } else {
-            // tessellation evaluation
-            // TODO: tessellation: semantic check these are on the in qualifier only
+            assert(language == EShLangTessEvaluation);
 
             // input primitive
             if (id == TQualifier::getGeometryString(ElgTriangles)) {
@@ -2833,24 +2852,6 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
     error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), "");
 }
 
-//
-// Merge characteristics of the 'src' qualifier into the 'dst', at the TPublicType level,
-// which means for layout-qualifier information not kept per qualifier.
-//
-void TParseContext::mergeShaderLayoutQualifiers(TSourceLoc loc, TShaderQualifiers& dst, const TShaderQualifiers& src)
-{
-    if (src.geometry != ElgNone)
-        dst.geometry = src.geometry;
-    if (src.invocations != 0)
-        dst.invocations = src.invocations;
-    if (src.vertices != 0)
-        dst.vertices = src.vertices;
-    if (src.pixelCenterInteger)
-        dst.pixelCenterInteger = src.pixelCenterInteger;
-    if (src.originUpperLeft)
-        dst.originUpperLeft = src.originUpperLeft;
-}
-
 // Merge any layout qualifier information from src into dst, leaving everything else in dst alone
 void TParseContext::mergeObjectLayoutQualifiers(TSourceLoc loc, TQualifier& dst, const TQualifier& src)
 {
@@ -2880,6 +2881,7 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TSymbol& symbol)
     layoutQualifierCheck(loc, qualifier);
 
     // now, error checking combining type and qualifier
+
     if (qualifier.hasLocation()) {
         switch (qualifier.storage) {
         case EvqVaryingIn:
@@ -2903,6 +2905,7 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TSymbol& symbol)
             break;
         }
         default:
+            error(loc, "location qualifiers only appy to uniform, buffer, in, or out storage qualifiers", symbol.getName().c_str(), "");
             break;
         }
 
@@ -2931,6 +2934,27 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TSymbol& symbol)
                 error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : "");
         }
     }
+
+    // Check packing and matrix
+    if (qualifier.layoutMatrix || qualifier.layoutPacking) {
+        switch (qualifier.storage) {
+        case EvqBuffer:
+        case EvqUniform:
+            if (symbol.getType().getBasicType() != EbtBlock) {
+                if (qualifier.layoutMatrix != ElmNone)
+                    error(loc, "cannot specify matrix layout on a variable declaration", symbol.getName().c_str(), "");
+                if (qualifier.layoutPacking != ElpNone)
+                    error(loc, "cannot specify packing on a variable declaration", symbol.getName().c_str(), "");
+            }
+            break;
+        default:
+            if (symbol.getType().getBasicType() != EbtBlock && symbol.getAsVariable()) {
+                if (qualifier.layoutMatrix != ElmNone ||
+                    qualifier.layoutPacking != ElpNone)
+                    error(loc, "layout qualifiers for matrix layout and packing only apply to uniform or buffer blocks", symbol.getName().c_str(), "");
+            }
+        }
+    }
 }
 
 // Do layout error checking that can be done within a qualifier proper, not needing to know
@@ -3220,6 +3244,7 @@ TVariable* TParseContext::declareNonArray(TSourceLoc loc, TString& identifier, T
     // make a new variable
     TVariable* variable = new TVariable(&identifier, type);
 
+    ioArrayCheck(loc, type, identifier);
     // add variable to symbol table
     if (! symbolTable.insert(*variable)) {
         error(loc, "redefinition", variable->getName().c_str(), "");
@@ -3677,6 +3702,8 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
     TType blockType(&typeList, *blockName, currentBlockQualifier);
     if (arraySizes)
         blockType.setArraySizes(arraySizes);
+    else
+        ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName);
 
     //
     // Don't make a user-defined type out of block name; that will cause an error
@@ -3724,6 +3751,11 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
     // Check for general layout qualifier errors
     layoutTypeCheck(loc, variable);
 
+    if (isIoResizeArray(blockType)) {
+        ioArraySymbolResizeList.push_back(&variable);
+        checkIoArraysConsistency(loc, true);
+    }
+
     // Save it in the AST for linker use.
     intermediate.addSymbolLinkageNode(linkage, variable);
 }
@@ -3793,21 +3825,20 @@ void TParseContext::invariantCheck(TSourceLoc loc, const TType& type, const TStr
 void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPublicType& publicType)
 {
     if (publicType.shaderQualifiers.vertices) {
-        if (! intermediate.setVertices(publicType.shaderQualifiers.vertices)) {            
-            if (language == EShLangGeometry)
-                error(loc, "cannot change previously set layout value", "max_vertices", "");
-            else if (language == EShLangTessControl)
-                error(loc, "cannot change previously set layout value", "vertices", "");
-            else
-                assert(0);
-        } else if (language == EShLangTessControl) {
-            if (publicType.qualifier.storage != EvqVaryingOut)
-                error(loc, "can only apply to 'out'", "vertices", "");
-            else
-                checkIoArraysConsistency(loc);
-        }
+        assert(language == EShLangTessControl || language == EShLangGeometry);
+        const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices";
+
+        if (publicType.qualifier.storage != EvqVaryingOut)
+            error(loc, "can only apply to 'out'", id, "");
+        if (! intermediate.setVertices(publicType.shaderQualifiers.vertices))
+            error(loc, "cannot change previously set layout value", id, "");
+        
+        if (language == EShLangTessControl)
+            checkIoArraysConsistency(loc);
     }
     if (publicType.shaderQualifiers.invocations) {
+        if (publicType.qualifier.storage != EvqVaryingIn)
+            error(loc, "can only apply to 'in'", "invocations", "");
         if (! intermediate.setInvocations(publicType.shaderQualifiers.invocations))
             error(loc, "cannot change previously set layout value", "invocations", "");
     }
@@ -3828,7 +3859,7 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub
                     error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
                 break;
             default:
-                error(loc, "does not apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
+                error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
             }
         } else if (publicType.qualifier.storage == EvqVaryingOut) {
             switch (publicType.shaderQualifiers.geometry) {
@@ -3839,21 +3870,31 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub
                     error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
                 break;
             default:
-                error(loc, "does not apply to output", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
+                error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
             }
         } else
-            error(loc, "cannot be used here", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
+            error(loc, "cannot apply to:", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), GetStorageQualifierString(publicType.qualifier.storage));
     }
     if (publicType.shaderQualifiers.spacing != EvsNone) {
-        if (! intermediate.setVertexSpacing(publicType.shaderQualifiers.spacing))
-            error(loc, "cannot change previously set vertex spacing", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
+        if (publicType.qualifier.storage == EvqVaryingIn) {
+            if (! intermediate.setVertexSpacing(publicType.shaderQualifiers.spacing))
+                error(loc, "cannot change previously set vertex spacing", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
+        } else
+            error(loc, "can only apply to 'in'", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), "");
     }
     if (publicType.shaderQualifiers.order != EvoNone) {
-        if (! intermediate.setVertexOrder(publicType.shaderQualifiers.order))
-            error(loc, "cannot change previously set vertex order", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
+        if (publicType.qualifier.storage == EvqVaryingIn) {
+            if (! intermediate.setVertexOrder(publicType.shaderQualifiers.order))
+                error(loc, "cannot change previously set vertex order", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
+        } else
+            error(loc, "can only apply to 'in'", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), "");
+    }
+    if (publicType.shaderQualifiers.pointMode) {
+        if (publicType.qualifier.storage == EvqVaryingIn)
+            intermediate.setPointMode();
+        else
+            error(loc, "can only apply to 'in'", "point_mode", "");
     }
-    if (publicType.shaderQualifiers.pointMode)
-        intermediate.setPointMode();
 
     const TQualifier& qualifier = publicType.qualifier;
 
@@ -3896,44 +3937,6 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub
 }
 
 //
-// Update defaults for qualifiers when declared with a type, and optionally an identifier.
-// (But, not the case of just a qualifier.)
-//
-void TParseContext::updateTypedDefaults(TSourceLoc loc, const TQualifier& qualifier, const TString* id)
-{
-    if (! id) {
-        if (qualifier.hasLayout())
-            warn(loc, "cannot set qualifier defaults when using a type and no identifier", "", "");
-
-        return;
-    }
-
-    switch (qualifier.storage) {
-    case EvqBuffer:
-    case EvqUniform:
-        if (qualifier.layoutMatrix != ElmNone)
-            error(loc, "cannot specify matrix layout on a variable declaration", id->c_str(), "");
-        if (qualifier.layoutPacking != ElpNone)
-            error(loc, "cannot specify packing on a variable declaration", id->c_str(), "");
-        break;
-    case EvqVaryingIn:
-        if (qualifier.hasLocation())
-            globalInputDefaults.layoutSlotLocation = qualifier.layoutSlotLocation;
-        break;
-    case EvqVaryingOut:
-        if (qualifier.hasLocation())
-            globalOutputDefaults.layoutSlotLocation = qualifier.layoutSlotLocation;
-        break;
-    default:
-        if (qualifier.layoutMatrix != ElmNone ||
-            qualifier.layoutPacking != ElpNone)
-            error(loc, "layout qualifiers for matrix layout and packing only apply to uniform or buffer blocks", id->c_str(), "");
-        else if (qualifier.hasLocation())
-            error(loc, "location qualifiers only appy to uniform, buffer, in, or out storage qualifiers", id->c_str(), "");
-    }
-}
-
-//
 // Take the sequence of statements that has been built up since the last case/default,
 // put it on the list of top-level nodes for the current (inner-most) switch statement,
 // and follow that by the case/default we are on now.  (See switch topology comment on
@@ -4009,4 +4012,3 @@ TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression,
 }
 
 } // end namespace glslang
-// TODO: geometry and tessellation: make sure all inputs/outputs that should have extra level of arrayness do have the extra level of arrayness
\ No newline at end of file
index 3d4713b..50acbcf 100644 (file)
@@ -85,7 +85,8 @@ public:
     void checkIndex(TSourceLoc, const TType&, int& index);
     void handleIndexLimits(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
 
-    bool isIoResizeArray(const TType&);
+    bool isIoResizeArray(const TType&) const;
+    void ioArrayCheck(TSourceLoc, const TType&, const TString& identifier);
     void handleIoResizeArrayAccess(TSourceLoc, TIntermTyped* base);
     void checkIoArraysConsistency(TSourceLoc, bool tailOnly = false);
     int getIoArrayImplicitSize() const;
@@ -94,7 +95,8 @@ public:
     TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field);
     TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function, bool prototype);
     TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&);
-    TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*, TIntermAggregate*);
+    TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*);
+    TIntermTyped* handleLengthMethod(TSourceLoc, TFunction*, TIntermNode*);
     void nonOpBuiltInCheck(TSourceLoc, const TFunction&, TIntermAggregate&);
     TFunction* handleConstructorCall(TSourceLoc, TPublicType&);
 
@@ -146,7 +148,6 @@ public:
 
     void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
     void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
-    void mergeShaderLayoutQualifiers(TSourceLoc, TShaderQualifiers& dst, const TShaderQualifiers& src);
     void mergeObjectLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src);
     void layoutTypeCheck(TSourceLoc, const TSymbol&);
     void layoutQualifierCheck(TSourceLoc, const TQualifier&);
@@ -165,7 +166,6 @@ public:
     void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
     void invariantCheck(TSourceLoc, const TType&, const TString& identifier);
     void updateStandaloneQualifierDefaults(TSourceLoc, const TPublicType&);
-    void updateTypedDefaults(TSourceLoc, const TQualifier&, const TString* id);
     void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
     TIntermNode* addSwitch(TSourceLoc, TIntermTyped* expression, TIntermAggregate* body);
 
index 696006d..cd20b3e 100644 (file)
@@ -82,7 +82,6 @@ using namespace glslang;
             TIntermNode* intermNode;\r
             glslang::TIntermNodePair nodePair;\r
             glslang::TIntermTyped* intermTypedNode;\r
-            glslang::TIntermAggregate* intermAggregate;\r
         };\r
         union {\r
             glslang::TPublicType type;\r
@@ -184,7 +183,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
 \r
 %type <interm.intermNode> translation_unit function_definition\r
 %type <interm.intermNode> statement simple_statement\r
-%type <interm.intermAggregate>  statement_list switch_statement_list compound_statement\r
+%type <interm.intermNode> statement_list switch_statement_list compound_statement\r
 %type <interm.intermNode> declaration_statement selection_statement expression_statement\r
 %type <interm.intermNode> switch_statement case_label\r
 %type <interm.intermNode> declaration external_declaration\r
@@ -300,7 +299,7 @@ integer_expression
 \r
 function_call\r
     : function_call_or_method {\r
-        $$ = parseContext.handleFunctionCall($1.loc, $1.function, $1.intermNode, $1.intermAggregate);\r
+        $$ = parseContext.handleFunctionCall($1.loc, $1.function, $1.intermNode);\r
         delete $1.function;\r
     }\r
     ;\r
@@ -753,9 +752,9 @@ declaration
         // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature\r
     }\r
     | init_declarator_list SEMICOLON {\r
-        if ($1.intermAggregate)\r
-            $1.intermAggregate->setOperator(EOpSequence);\r
-        $$ = $1.intermAggregate;\r
+        if ($1.intermNode && $1.intermNode->getAsAggregate())\r
+            $1.intermNode->getAsAggregate()->setOperator(EOpSequence);\r
+        $$ = $1.intermNode;\r
     }\r
     | PRECISION precision_qualifier type_specifier SEMICOLON {\r
         parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "precision statement");\r
@@ -980,42 +979,41 @@ init_declarator_list
     | init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer {\r
         $$.type = $1.type;\r
         TIntermNode* initNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes, $6);\r
-        $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermAggregate, initNode, $5.loc);\r
+        $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, initNode, $5.loc);\r
     }\r
     | init_declarator_list COMMA IDENTIFIER EQUAL initializer {\r
         $$.type = $1.type;\r
         TIntermNode* initNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, 0, $5);\r
-        $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermAggregate, initNode, $4.loc);\r
+        $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, initNode, $4.loc);\r
     }\r
     ;\r
 \r
 single_declaration\r
     : fully_specified_type {\r
         $$.type = $1;\r
-        $$.intermAggregate = 0;\r
-        parseContext.updateTypedDefaults($1.loc, $$.type.qualifier, 0);\r
+        $$.intermNode = 0;\r
+        if ($$.type.qualifier.hasLayout())\r
+            parseContext.warn($1.loc, "useless application of layout qualifier", "layout", "");\r
     }\r
     | fully_specified_type IDENTIFIER {\r
         $$.type = $1;\r
-        $$.intermAggregate = 0;\r
+        $$.intermNode = 0;\r
         parseContext.declareVariable($2.loc, *$2.string, $1);\r
-        parseContext.updateTypedDefaults($2.loc, $$.type.qualifier, $2.string);\r
     }\r
     | fully_specified_type IDENTIFIER array_specifier {\r
         $$.type = $1;\r
-        $$.intermAggregate = 0;\r
+        $$.intermNode = 0;\r
         parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes);\r
-        parseContext.updateTypedDefaults($2.loc, $$.type.qualifier, $2.string);\r
     }\r
     | fully_specified_type IDENTIFIER array_specifier EQUAL initializer {\r
         $$.type = $1;\r
         TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes, $5);\r
-        $$.intermAggregate = parseContext.intermediate.growAggregate(0, initNode, $4.loc);\r
+        $$.intermNode = parseContext.intermediate.growAggregate(0, initNode, $4.loc);\r
     }\r
     | fully_specified_type IDENTIFIER EQUAL initializer {\r
         $$.type = $1;\r
         TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4);\r
-        $$.intermAggregate = parseContext.intermediate.growAggregate(0, initNode, $3.loc);\r
+        $$.intermNode = parseContext.intermediate.growAggregate(0, initNode, $3.loc);\r
     }\r
 \r
 // Grammar Note:  No 'enum', or 'typedef'.\r
@@ -1045,7 +1043,7 @@ fully_specified_type
             $2.arraySizes = 0;\r
         \r
         parseContext.checkNoShaderLayouts($2.loc, $1.shaderQualifiers);\r
-        parseContext.mergeShaderLayoutQualifiers($2.loc, $2.shaderQualifiers, $1.shaderQualifiers);\r
+        $2.shaderQualifiers.merge($1.shaderQualifiers);\r
         parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);\r
         parseContext.precisionQualifierCheck($2.loc, $2);\r
 \r
@@ -1103,7 +1101,7 @@ layout_qualifier_id_list
     }\r
     | layout_qualifier_id_list COMMA layout_qualifier_id {\r
         $$ = $1;\r
-        parseContext.mergeShaderLayoutQualifiers($2.loc, $$.shaderQualifiers, $3.shaderQualifiers);\r
+        $$.shaderQualifiers.merge($3.shaderQualifiers);\r
         parseContext.mergeObjectLayoutQualifiers($2.loc, $$.qualifier, $3.qualifier);\r
     }\r
 \r
@@ -1142,7 +1140,7 @@ type_qualifier
         if ($$.basicType == EbtVoid)\r
             $$.basicType = $2.basicType;\r
 \r
-        parseContext.mergeShaderLayoutQualifiers($$.loc, $$.shaderQualifiers, $2.shaderQualifiers);\r
+        $$.shaderQualifiers.merge($2.shaderQualifiers);\r
         parseContext.mergeQualifiers($$.loc, $$.qualifier, $2.qualifier, false);\r
     }\r
     ;\r
@@ -2159,8 +2157,8 @@ compound_statement
         --parseContext.controlFlowNestingLevel;\r
     }\r
       RIGHT_BRACE {\r
-        if ($3 != 0)\r
-            $3->setOperator(EOpSequence);\r
+        if ($3 && $3->getAsAggregate())\r
+            $3->getAsAggregate()->setOperator(EOpSequence);\r
         $$ = $3;\r
     }\r
     ;\r
@@ -2188,8 +2186,8 @@ compound_statement_no_new_scope
         $$ = 0;\r
     }\r
     | LEFT_BRACE statement_list RIGHT_BRACE {\r
-        if ($2)\r
-            $2->setOperator(EOpSequence);\r
+        if ($2 && $2->getAsAggregate())\r
+            $2->getAsAggregate()->setOperator(EOpSequence);\r
         $$ = $2;\r
     }\r
     ;\r
@@ -2206,7 +2204,7 @@ statement_list
     | statement_list statement {\r
         if ($2 && $2->getAsBranchNode() && ($2->getAsBranchNode()->getFlowOp() == EOpCase || \r
                                             $2->getAsBranchNode()->getFlowOp() == EOpDefault)) {\r
-            parseContext.wrapupSwitchSubsequence($1, $2);\r
+            parseContext.wrapupSwitchSubsequence($1 ? $1->getAsAggregate() : 0, $2);\r
             $$ = 0;  // start a fresh subsequence for what's after this case\r
         } else\r
             $$ = parseContext.intermediate.growAggregate($1, $2);\r
@@ -2261,7 +2259,7 @@ switch_statement
         parseContext.switchLevel.push_back(parseContext.controlFlowNestingLevel);\r
     } \r
     LEFT_BRACE switch_statement_list RIGHT_BRACE {\r
-        $$ = parseContext.addSwitch($1.loc, $3, $7);\r
+        $$ = parseContext.addSwitch($1.loc, $3, $7 ? $7->getAsAggregate() : 0);\r
         delete parseContext.switchSequenceStack.back();\r
         parseContext.switchSequenceStack.pop_back();\r
         parseContext.switchLevel.pop_back();\r
@@ -2422,14 +2420,14 @@ external_declaration
 function_definition\r
     : function_prototype {\r
         $1.function = parseContext.handleFunctionDeclarator($1.loc, *$1.function, false /* not prototype */);\r
-        $1.intermAggregate = parseContext.handleFunctionDefinition($1.loc, *$1.function);\r
+        $1.intermNode = parseContext.handleFunctionDefinition($1.loc, *$1.function);\r
     }\r
     compound_statement_no_new_scope {\r
         //   May be best done as post process phase on intermediate code\r
         if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue)\r
             parseContext.error($1.loc, "function does not return a value:", "", $1.function->getName().c_str());\r
         parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);\r
-        $$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3);\r
+        $$ = parseContext.intermediate.growAggregate($1.intermNode, $3);\r
         parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.function->getType(), $1.loc);\r
         $$->getAsAggregate()->setName($1.function->getMangledName().c_str());\r
 \r
index 539a947..2ce1f1f 100644 (file)
@@ -118,7 +118,7 @@ public:
     bool setInvocations(int i) 
     {
         if (invocations > 0)
-            return false;
+            return invocations == i;
         invocations = i;
         return true;
     }