Implement write-only semantic checking, the non-r32f/i/u readonly/writeonly check...
authorJohn Kessenich <cepheus@frii.com>
Tue, 19 Aug 2014 20:32:48 +0000 (20:32 +0000)
committerJohn Kessenich <cepheus@frii.com>
Tue, 19 Aug 2014 20:32:48 +0000 (20:32 +0000)
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@27765 e7fa87d3-cd2b-0410-9028-fcbf551c1848

StandAlone/StandAlone.cpp
Test/310.comp
Test/baseResults/310.comp.out
Test/baseResults/test.conf
glslang/MachineIndependent/Intermediate.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h
glslang/MachineIndependent/Scan.cpp
glslang/MachineIndependent/glslang.y
glslang/MachineIndependent/localintermediate.h

index dd1d434..06710f5 100644 (file)
@@ -142,7 +142,7 @@ const char* DefaultConfig =
     "MaxComputeWorkGroupCountY 65535\n"
     "MaxComputeWorkGroupCountZ 65535\n"
     "MaxComputeWorkGroupSizeX 1024\n"
-    "MaxComputeWorkGroupSizeX 1024\n"
+    "MaxComputeWorkGroupSizeY 1024\n"
     "MaxComputeWorkGroupSizeZ 64\n"
     "MaxComputeUniformComponents 1024\n"
     "MaxComputeTextureImageUnits 16\n"
index f2cd8c5..6826a5d 100644 (file)
@@ -77,8 +77,8 @@ uniform iimage2DArray ii2dabad;  // ERROR, not writeonly
 uniform writeonly iimage2DArray ii2da;\r
 \r
 layout(r32i) uniform iimage2D iimg2D;\r
-layout(rgba32i) uniform iimage2D iimg2Drgba;\r
-layout(rgba32f) uniform image2D img2Drgba;\r
+layout(rgba32i) uniform readonly iimage2D iimg2Drgba;\r
+layout(rgba32f) uniform readonly image2D img2Drgba;\r
 layout(r32ui) uniform uimage2D uimg2D;\r
 \r
 void qux()\r
@@ -111,12 +111,12 @@ void passrc()
     passr(iimg2D);\r
 }\r
 \r
-layout(rg8i) uniform uimage2D i1bad;     // ERROR, type mismatch\r
-layout(rgba32i) uniform image2D i2bad;   // ERROR, type mismatch\r
-layout(rgba32f) uniform uimage2D i3bad;  // ERROR, type mismatch\r
-layout(r8_snorm) uniform iimage2D i4bad; // ERROR, type mismatch\r
-layout(rgba32ui) uniform iimage2D i5bad; // ERROR, type mismatch\r
-layout(r8ui) uniform iimage2D i6bad;     // ERROR, type mismatch\r
+layout(rg8i)     uniform readonly uimage2D i1bad; // ERROR, type mismatch\r
+layout(rgba32i)  uniform readonly image2D i2bad;  // ERROR, type mismatch\r
+layout(rgba32f)  uniform readonly uimage2D i3bad; // ERROR, type mismatch\r
+layout(r8_snorm) uniform readonly iimage2D i4bad; // ERROR, type mismatch\r
+layout(rgba32ui) uniform readonly iimage2D i5bad; // ERROR, type mismatch\r
+layout(r8ui)     uniform readonly iimage2D i6bad; // ERROR, type mismatch\r
 \r
 layout(binding = 0) uniform atomic_uint counter;\r
 \r
@@ -146,7 +146,7 @@ uniform int i;
 void opac()\r
 {\r
     int a[3];\r
-    a[counter];         // ERROR\r
+    a[counter];         // ERROR, non-integer\r
     countArr[2];\r
     countArr[i];\r
 }\r
@@ -172,3 +172,54 @@ uniform samplerCubeArray sca;   // ERROR
 uniform iimage2DRect i2dr;      // ERROR\r
 uniform image2DMS i2dms;        // ERROR\r
 uniform uimage2DMSArray u2dmsa; // ERROR\r
+\r
+layout(r32f)  coherent volatile restrict readonly writeonly uniform  image2D okay1;\r
+layout(r32i)  coherent volatile restrict readonly           uniform iimage2D okay2;\r
+layout(r32ui) coherent volatile restrict          writeonly uniform uimage2D okay3;\r
+layout(r32f)  coherent volatile restrict                    uniform  image2D okay4;\r
\r
+layout(rgba32f)  coherent volatile restrict                 uniform  image2D badQ1;  // ERROR, bad qualifiers\r
+layout(rgba8i)   coherent volatile restrict                 uniform iimage2D badQ2;  // ERROR, bad qualifiers\r
+layout(rgba16ui) coherent volatile restrict                 uniform uimage2D badQ3;  // ERROR, bad qualifiers\r
+\r
+writeonly buffer woblock\r
+{\r
+    int value;\r
+    float values[];\r
+} wo;\r
+\r
+void foowo()\r
+{\r
+    float g;\r
+    g = wo.values[2];            // ERROR, writeonly\r
+    float f = wo.values[2];      // ERROR, writeonly\r
+    ++wo.values[2];              // ERROR, writeonly\r
+    wo.values[2]--;              // ERROR, writeonly\r
+    f + wo.values[2];            // ERROR, writeonly\r
+    wo.values[2] - f;            // ERROR, writeonly\r
+    bool b;\r
+    b ? f : wo.values[2];        // ERROR, writeonly\r
+    b ? wo.values[2] : f;        // ERROR, writeonly\r
+    if (f == wo.values[2])       // ERROR, writeonly\r
+        ++f;\r
+    if (f >= wo.values[2])       // ERROR, writeonly\r
+        ++f;\r
+    f = vec3(wo.values[2]).x;    // ERROR, writeonly\r
+    ~wo.value;                   // ERROR, writeonly\r
+    wo.values[2] = 3.4;\r
+}\r
+\r
+buffer multioblock\r
+{\r
+    readonly int value;\r
+    writeonly float values[];\r
+} multio;\r
+\r
+void foomultio()\r
+{\r
+    float g;\r
+    g = wo.values[2];            // ERROR, writeonly\r
+    ~wo.value;\r
+    wo.values[2] = 3.4;\r
+    wo.value = 2;                // ERROR, readonly\r
+}\r
index 69dd191..30df51b 100644 (file)
@@ -22,7 +22,6 @@ ERROR: 0:88: 'imageAtomicAdd' : no matching overloaded function found
 ERROR: 0:89: 'imageAtomicMin' : no matching overloaded function found \r
 ERROR: 0:90: 'imageAtomicMax' : no matching overloaded function found \r
 ERROR: 0:94: 'writeonly' : argument cannot drop memory qualifier when passed to formal parameter \r
-ERROR: 0:97: 'volatile' : Reserved word. \r
 ERROR: 0:97: '' : memory qualifiers cannot be used on this type \r
 ERROR: 0:98: '' : memory qualifiers cannot be used on this type \r
 ERROR: 0:110: 'restrict' : argument cannot drop memory qualifier when passed to formal parameter \r
@@ -57,7 +56,24 @@ ERROR: 0:173: '' : image variables not declared 'writeonly' must have a format l
 ERROR: 0:174: 'uimage2DMSArray' : Reserved word. \r
 ERROR: 0:174: 'sampler/image' : type requires declaration of default precision qualifier \r
 ERROR: 0:174: '' : image variables not declared 'writeonly' must have a format layout qualifier \r
-ERROR: 57 compilation errors.  No code generated.\r
+ERROR: 0:181: 'rgba32f' : format requires readonly or writeonly memory qualifier \r
+ERROR: 0:182: 'rgba8i' : format requires readonly or writeonly memory qualifier \r
+ERROR: 0:183: 'rgba16ui' : format requires readonly or writeonly memory qualifier \r
+ERROR: 0:194: 'assign' : can't read from writeonly object:  wo\r
+ERROR: 0:195: 'initializer' : can't read from writeonly object:  wo\r
+ERROR: 0:196: '++' : can't read from writeonly object:  wo\r
+ERROR: 0:197: '--' : can't read from writeonly object:  wo\r
+ERROR: 0:198: '+' : can't read from writeonly object:  wo\r
+ERROR: 0:199: '-' : can't read from writeonly object:  wo\r
+ERROR: 0:201: ':' : can't read from writeonly object:  wo\r
+ERROR: 0:202: ':' : can't read from writeonly object:  wo\r
+ERROR: 0:203: '==' : can't read from writeonly object:  wo\r
+ERROR: 0:205: '>=' : can't read from writeonly object:  wo\r
+ERROR: 0:207: 'constructor' : can't read from writeonly object:  wo\r
+ERROR: 0:208: '~' : can't read from writeonly object:  wo\r
+ERROR: 0:221: 'assign' : can't read from writeonly object:  wo\r
+ERROR: 0:222: '~' : can't read from writeonly object:  wo\r
+ERROR: 73 compilation errors.  No code generated.\r
 \r
 \r
 Shader version: 310\r
@@ -141,7 +157,7 @@ ERROR: node is still EOpNull!
 0:92          0 (const int)\r
 0:92          0 (const int)\r
 0:93      Function Call: imageLoad(I21;vi2; (highp 4-component vector of float)\r
-0:93        'img2Drgba' (layout(rgba32f ) uniform lowp image2D)\r
+0:93        'img2Drgba' (layout(rgba32f ) readonly uniform lowp image2D)\r
 0:93        Construct ivec2 (2-component vector of int)\r
 0:93          'i' (highp int)\r
 0:93          'i' (highp int)\r
@@ -233,6 +249,178 @@ ERROR: node is still EOpNull!
 0:162            10 (const uint)\r
 0:162          Constant:\r
 0:162            8 (const uint)\r
+0:191  Function Definition: foowo( (void)\r
+0:191    Function Parameters: \r
+0:?     Sequence\r
+0:194      move second child to first child (highp float)\r
+0:194        'g' (highp float)\r
+0:194        direct index (layout(column_major shared ) highp float)\r
+0:194          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:194            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:194            Constant:\r
+0:194              1 (const int)\r
+0:194          Constant:\r
+0:194            2 (const int)\r
+0:195      Sequence\r
+0:195        move second child to first child (highp float)\r
+0:195          'f' (highp float)\r
+0:195          direct index (layout(column_major shared ) highp float)\r
+0:195            values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:195              'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:195              Constant:\r
+0:195                1 (const int)\r
+0:195            Constant:\r
+0:195              2 (const int)\r
+0:196      Pre-Increment (highp float)\r
+0:196        direct index (layout(column_major shared ) highp float)\r
+0:196          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:196            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:196            Constant:\r
+0:196              1 (const int)\r
+0:196          Constant:\r
+0:196            2 (const int)\r
+0:197      Post-Decrement (highp float)\r
+0:197        direct index (layout(column_major shared ) highp float)\r
+0:197          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:197            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:197            Constant:\r
+0:197              1 (const int)\r
+0:197          Constant:\r
+0:197            2 (const int)\r
+0:198      add (highp float)\r
+0:198        'f' (highp float)\r
+0:198        direct index (layout(column_major shared ) highp float)\r
+0:198          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:198            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:198            Constant:\r
+0:198              1 (const int)\r
+0:198          Constant:\r
+0:198            2 (const int)\r
+0:199      subtract (highp float)\r
+0:199        direct index (layout(column_major shared ) highp float)\r
+0:199          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:199            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:199            Constant:\r
+0:199              1 (const int)\r
+0:199          Constant:\r
+0:199            2 (const int)\r
+0:199        'f' (highp float)\r
+0:201      Test condition and select (highp float)\r
+0:201        Condition\r
+0:201        'b' (bool)\r
+0:201        true case\r
+0:201        'f' (highp float)\r
+0:201        false case\r
+0:201        direct index (layout(column_major shared ) highp float)\r
+0:201          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:201            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:201            Constant:\r
+0:201              1 (const int)\r
+0:201          Constant:\r
+0:201            2 (const int)\r
+0:202      Test condition and select (layout(column_major shared ) highp float)\r
+0:202        Condition\r
+0:202        'b' (bool)\r
+0:202        true case\r
+0:202        direct index (layout(column_major shared ) highp float)\r
+0:202          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:202            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:202            Constant:\r
+0:202              1 (const int)\r
+0:202          Constant:\r
+0:202            2 (const int)\r
+0:202        false case\r
+0:202        'f' (highp float)\r
+0:203      Test condition and select (void)\r
+0:203        Condition\r
+0:203        Compare Equal (bool)\r
+0:203          'f' (highp float)\r
+0:203          direct index (layout(column_major shared ) highp float)\r
+0:203            values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:203              'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:203              Constant:\r
+0:203                1 (const int)\r
+0:203            Constant:\r
+0:203              2 (const int)\r
+0:203        true case\r
+0:204        Pre-Increment (highp float)\r
+0:204          'f' (highp float)\r
+0:205      Test condition and select (void)\r
+0:205        Condition\r
+0:205        Compare Greater Than or Equal (bool)\r
+0:205          'f' (highp float)\r
+0:205          direct index (layout(column_major shared ) highp float)\r
+0:205            values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:205              'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:205              Constant:\r
+0:205                1 (const int)\r
+0:205            Constant:\r
+0:205              2 (const int)\r
+0:205        true case\r
+0:206        Pre-Increment (highp float)\r
+0:206          'f' (highp float)\r
+0:207      move second child to first child (highp float)\r
+0:207        'f' (highp float)\r
+0:207        direct index (highp float)\r
+0:207          Construct vec3 (highp 3-component vector of float)\r
+0:207            direct index (layout(column_major shared ) highp float)\r
+0:207              values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:207                'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:207                Constant:\r
+0:207                  1 (const int)\r
+0:207              Constant:\r
+0:207                2 (const int)\r
+0:207          Constant:\r
+0:207            0 (const int)\r
+0:208      Bitwise not (highp int)\r
+0:208        value: direct index for structure (layout(column_major shared ) buffer highp int)\r
+0:208          'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:208          Constant:\r
+0:208            0 (const int)\r
+0:209      move second child to first child (highp float)\r
+0:209        direct index (layout(column_major shared ) highp float)\r
+0:209          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:209            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:209            Constant:\r
+0:209              1 (const int)\r
+0:209          Constant:\r
+0:209            2 (const int)\r
+0:209        Constant:\r
+0:209          3.400000\r
+0:218  Function Definition: foomultio( (void)\r
+0:218    Function Parameters: \r
+0:?     Sequence\r
+0:221      move second child to first child (highp float)\r
+0:221        'g' (highp float)\r
+0:221        direct index (layout(column_major shared ) highp float)\r
+0:221          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:221            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:221            Constant:\r
+0:221              1 (const int)\r
+0:221          Constant:\r
+0:221            2 (const int)\r
+0:222      Bitwise not (highp int)\r
+0:222        value: direct index for structure (layout(column_major shared ) buffer highp int)\r
+0:222          'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:222          Constant:\r
+0:222            0 (const int)\r
+0:223      move second child to first child (highp float)\r
+0:223        direct index (layout(column_major shared ) highp float)\r
+0:223          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:223            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:223            Constant:\r
+0:223              1 (const int)\r
+0:223          Constant:\r
+0:223            2 (const int)\r
+0:223        Constant:\r
+0:223          3.400000\r
+0:224      move second child to first child (highp int)\r
+0:224        value: direct index for structure (layout(column_major shared ) buffer highp int)\r
+0:224          'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:224          Constant:\r
+0:224            0 (const int)\r
+0:224        Constant:\r
+0:224          2 (const int)\r
 0:?   Linker Objects\r
 0:?     'gl_WorkGroupSize' (const highp 3-component vector of uint)\r
 0:?       2 (const uint)\r
@@ -258,19 +446,19 @@ ERROR: node is still EOpNull!
 0:?     'ii2dabad' (uniform highp iimage2DArray)\r
 0:?     'ii2da' (writeonly uniform highp iimage2DArray)\r
 0:?     'iimg2D' (layout(r32i ) uniform highp iimage2D)\r
-0:?     'iimg2Drgba' (layout(rgba32i ) uniform highp iimage2D)\r
-0:?     'img2Drgba' (layout(rgba32f ) uniform lowp image2D)\r
+0:?     'iimg2Drgba' (layout(rgba32i ) readonly uniform highp iimage2D)\r
+0:?     'img2Drgba' (layout(rgba32f ) readonly uniform lowp image2D)\r
 0:?     'uimg2D' (layout(r32ui ) uniform highp uimage2D)\r
 0:?     'vol' (volatile highp float)\r
 0:?     'vol2' (readonly highp int)\r
 0:?     'qualim1' (layout(r32i ) coherent readonly uniform highp iimage2D)\r
 0:?     'qualim2' (layout(r32i ) coherent restrict readonly uniform highp iimage2D)\r
-0:?     'i1bad' (layout(rg8i ) uniform highp uimage2D)\r
-0:?     'i2bad' (layout(rgba32i ) uniform lowp image2D)\r
-0:?     'i3bad' (layout(rgba32f ) uniform highp uimage2D)\r
-0:?     'i4bad' (layout(r8_snorm ) uniform highp iimage2D)\r
-0:?     'i5bad' (layout(rgba32ui ) uniform highp iimage2D)\r
-0:?     'i6bad' (layout(r8ui ) uniform highp iimage2D)\r
+0:?     'i1bad' (layout(rg8i ) readonly uniform highp uimage2D)\r
+0:?     'i2bad' (layout(rgba32i ) readonly uniform lowp image2D)\r
+0:?     'i3bad' (layout(rgba32f ) readonly uniform highp uimage2D)\r
+0:?     'i4bad' (layout(r8_snorm ) readonly uniform highp iimage2D)\r
+0:?     'i5bad' (layout(rgba32ui ) readonly uniform highp iimage2D)\r
+0:?     'i6bad' (layout(r8ui ) readonly uniform highp iimage2D)\r
 0:?     'counter' (layout(binding=0 offset=0 ) uniform highp atomic_uint)\r
 0:?     'counterBad' (layout(binding=1 ) uniform mediump atomic_uint)\r
 0:?     'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
@@ -283,6 +471,15 @@ ERROR: node is still EOpNull!
 0:?     'i2dr' (uniform mediump iimage2DRect)\r
 0:?     'i2dms' (uniform lowp image2DMS)\r
 0:?     'u2dmsa' (uniform mediump uimage2DMSArray)\r
+0:?     'okay1' (layout(r32f ) coherent volatile restrict readonly writeonly uniform lowp image2D)\r
+0:?     'okay2' (layout(r32i ) coherent volatile restrict readonly uniform highp iimage2D)\r
+0:?     'okay3' (layout(r32ui ) coherent volatile restrict writeonly uniform highp uimage2D)\r
+0:?     'okay4' (layout(r32f ) coherent volatile restrict uniform lowp image2D)\r
+0:?     'badQ1' (layout(rgba32f ) coherent volatile restrict uniform lowp image2D)\r
+0:?     'badQ2' (layout(rgba8i ) coherent volatile restrict uniform highp iimage2D)\r
+0:?     'badQ3' (layout(rgba16ui ) coherent volatile restrict uniform highp uimage2D)\r
+0:?     'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:?     'multio' (layout(column_major shared ) buffer block{layout(column_major shared ) readonly buffer highp int value, layout(column_major shared ) writeonly buffer implicitly-sized array of highp float values})\r
 \r
 \r
 Linked compute stage:\r
@@ -369,7 +566,7 @@ ERROR: node is still EOpNull!
 0:92          0 (const int)\r
 0:92          0 (const int)\r
 0:93      Function Call: imageLoad(I21;vi2; (highp 4-component vector of float)\r
-0:93        'img2Drgba' (layout(rgba32f ) uniform lowp image2D)\r
+0:93        'img2Drgba' (layout(rgba32f ) readonly uniform lowp image2D)\r
 0:93        Construct ivec2 (2-component vector of int)\r
 0:93          'i' (highp int)\r
 0:93          'i' (highp int)\r
@@ -461,6 +658,178 @@ ERROR: node is still EOpNull!
 0:162            10 (const uint)\r
 0:162          Constant:\r
 0:162            8 (const uint)\r
+0:191  Function Definition: foowo( (void)\r
+0:191    Function Parameters: \r
+0:?     Sequence\r
+0:194      move second child to first child (highp float)\r
+0:194        'g' (highp float)\r
+0:194        direct index (layout(column_major shared ) highp float)\r
+0:194          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:194            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:194            Constant:\r
+0:194              1 (const int)\r
+0:194          Constant:\r
+0:194            2 (const int)\r
+0:195      Sequence\r
+0:195        move second child to first child (highp float)\r
+0:195          'f' (highp float)\r
+0:195          direct index (layout(column_major shared ) highp float)\r
+0:195            values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:195              'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:195              Constant:\r
+0:195                1 (const int)\r
+0:195            Constant:\r
+0:195              2 (const int)\r
+0:196      Pre-Increment (highp float)\r
+0:196        direct index (layout(column_major shared ) highp float)\r
+0:196          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:196            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:196            Constant:\r
+0:196              1 (const int)\r
+0:196          Constant:\r
+0:196            2 (const int)\r
+0:197      Post-Decrement (highp float)\r
+0:197        direct index (layout(column_major shared ) highp float)\r
+0:197          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:197            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:197            Constant:\r
+0:197              1 (const int)\r
+0:197          Constant:\r
+0:197            2 (const int)\r
+0:198      add (highp float)\r
+0:198        'f' (highp float)\r
+0:198        direct index (layout(column_major shared ) highp float)\r
+0:198          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:198            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:198            Constant:\r
+0:198              1 (const int)\r
+0:198          Constant:\r
+0:198            2 (const int)\r
+0:199      subtract (highp float)\r
+0:199        direct index (layout(column_major shared ) highp float)\r
+0:199          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:199            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:199            Constant:\r
+0:199              1 (const int)\r
+0:199          Constant:\r
+0:199            2 (const int)\r
+0:199        'f' (highp float)\r
+0:201      Test condition and select (highp float)\r
+0:201        Condition\r
+0:201        'b' (bool)\r
+0:201        true case\r
+0:201        'f' (highp float)\r
+0:201        false case\r
+0:201        direct index (layout(column_major shared ) highp float)\r
+0:201          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:201            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:201            Constant:\r
+0:201              1 (const int)\r
+0:201          Constant:\r
+0:201            2 (const int)\r
+0:202      Test condition and select (layout(column_major shared ) highp float)\r
+0:202        Condition\r
+0:202        'b' (bool)\r
+0:202        true case\r
+0:202        direct index (layout(column_major shared ) highp float)\r
+0:202          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:202            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:202            Constant:\r
+0:202              1 (const int)\r
+0:202          Constant:\r
+0:202            2 (const int)\r
+0:202        false case\r
+0:202        'f' (highp float)\r
+0:203      Test condition and select (void)\r
+0:203        Condition\r
+0:203        Compare Equal (bool)\r
+0:203          'f' (highp float)\r
+0:203          direct index (layout(column_major shared ) highp float)\r
+0:203            values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:203              'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:203              Constant:\r
+0:203                1 (const int)\r
+0:203            Constant:\r
+0:203              2 (const int)\r
+0:203        true case\r
+0:204        Pre-Increment (highp float)\r
+0:204          'f' (highp float)\r
+0:205      Test condition and select (void)\r
+0:205        Condition\r
+0:205        Compare Greater Than or Equal (bool)\r
+0:205          'f' (highp float)\r
+0:205          direct index (layout(column_major shared ) highp float)\r
+0:205            values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:205              'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:205              Constant:\r
+0:205                1 (const int)\r
+0:205            Constant:\r
+0:205              2 (const int)\r
+0:205        true case\r
+0:206        Pre-Increment (highp float)\r
+0:206          'f' (highp float)\r
+0:207      move second child to first child (highp float)\r
+0:207        'f' (highp float)\r
+0:207        direct index (highp float)\r
+0:207          Construct vec3 (highp 3-component vector of float)\r
+0:207            direct index (layout(column_major shared ) highp float)\r
+0:207              values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:207                'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:207                Constant:\r
+0:207                  1 (const int)\r
+0:207              Constant:\r
+0:207                2 (const int)\r
+0:207          Constant:\r
+0:207            0 (const int)\r
+0:208      Bitwise not (highp int)\r
+0:208        value: direct index for structure (layout(column_major shared ) buffer highp int)\r
+0:208          'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:208          Constant:\r
+0:208            0 (const int)\r
+0:209      move second child to first child (highp float)\r
+0:209        direct index (layout(column_major shared ) highp float)\r
+0:209          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:209            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:209            Constant:\r
+0:209              1 (const int)\r
+0:209          Constant:\r
+0:209            2 (const int)\r
+0:209        Constant:\r
+0:209          3.400000\r
+0:218  Function Definition: foomultio( (void)\r
+0:218    Function Parameters: \r
+0:?     Sequence\r
+0:221      move second child to first child (highp float)\r
+0:221        'g' (highp float)\r
+0:221        direct index (layout(column_major shared ) highp float)\r
+0:221          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:221            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:221            Constant:\r
+0:221              1 (const int)\r
+0:221          Constant:\r
+0:221            2 (const int)\r
+0:222      Bitwise not (highp int)\r
+0:222        value: direct index for structure (layout(column_major shared ) buffer highp int)\r
+0:222          'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:222          Constant:\r
+0:222            0 (const int)\r
+0:223      move second child to first child (highp float)\r
+0:223        direct index (layout(column_major shared ) highp float)\r
+0:223          values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of highp float)\r
+0:223            'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:223            Constant:\r
+0:223              1 (const int)\r
+0:223          Constant:\r
+0:223            2 (const int)\r
+0:223        Constant:\r
+0:223          3.400000\r
+0:224      move second child to first child (highp int)\r
+0:224        value: direct index for structure (layout(column_major shared ) buffer highp int)\r
+0:224          'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:224          Constant:\r
+0:224            0 (const int)\r
+0:224        Constant:\r
+0:224          2 (const int)\r
 0:?   Linker Objects\r
 0:?     'gl_WorkGroupSize' (const highp 3-component vector of uint)\r
 0:?       2 (const uint)\r
@@ -486,19 +855,19 @@ ERROR: node is still EOpNull!
 0:?     'ii2dabad' (uniform highp iimage2DArray)\r
 0:?     'ii2da' (writeonly uniform highp iimage2DArray)\r
 0:?     'iimg2D' (layout(r32i ) uniform highp iimage2D)\r
-0:?     'iimg2Drgba' (layout(rgba32i ) uniform highp iimage2D)\r
-0:?     'img2Drgba' (layout(rgba32f ) uniform lowp image2D)\r
+0:?     'iimg2Drgba' (layout(rgba32i ) readonly uniform highp iimage2D)\r
+0:?     'img2Drgba' (layout(rgba32f ) readonly uniform lowp image2D)\r
 0:?     'uimg2D' (layout(r32ui ) uniform highp uimage2D)\r
 0:?     'vol' (volatile highp float)\r
 0:?     'vol2' (readonly highp int)\r
 0:?     'qualim1' (layout(r32i ) coherent readonly uniform highp iimage2D)\r
 0:?     'qualim2' (layout(r32i ) coherent restrict readonly uniform highp iimage2D)\r
-0:?     'i1bad' (layout(rg8i ) uniform highp uimage2D)\r
-0:?     'i2bad' (layout(rgba32i ) uniform lowp image2D)\r
-0:?     'i3bad' (layout(rgba32f ) uniform highp uimage2D)\r
-0:?     'i4bad' (layout(r8_snorm ) uniform highp iimage2D)\r
-0:?     'i5bad' (layout(rgba32ui ) uniform highp iimage2D)\r
-0:?     'i6bad' (layout(r8ui ) uniform highp iimage2D)\r
+0:?     'i1bad' (layout(rg8i ) readonly uniform highp uimage2D)\r
+0:?     'i2bad' (layout(rgba32i ) readonly uniform lowp image2D)\r
+0:?     'i3bad' (layout(rgba32f ) readonly uniform highp uimage2D)\r
+0:?     'i4bad' (layout(r8_snorm ) readonly uniform highp iimage2D)\r
+0:?     'i5bad' (layout(rgba32ui ) readonly uniform highp iimage2D)\r
+0:?     'i6bad' (layout(r8ui ) readonly uniform highp iimage2D)\r
 0:?     'counter' (layout(binding=0 offset=0 ) uniform highp atomic_uint)\r
 0:?     'counterBad' (layout(binding=1 ) uniform mediump atomic_uint)\r
 0:?     'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)\r
@@ -511,4 +880,13 @@ ERROR: node is still EOpNull!
 0:?     'i2dr' (uniform mediump iimage2DRect)\r
 0:?     'i2dms' (uniform lowp image2DMS)\r
 0:?     'u2dmsa' (uniform mediump uimage2DMSArray)\r
+0:?     'okay1' (layout(r32f ) coherent volatile restrict readonly writeonly uniform lowp image2D)\r
+0:?     'okay2' (layout(r32i ) coherent volatile restrict readonly uniform highp iimage2D)\r
+0:?     'okay3' (layout(r32ui ) coherent volatile restrict writeonly uniform highp uimage2D)\r
+0:?     'okay4' (layout(r32f ) coherent volatile restrict uniform lowp image2D)\r
+0:?     'badQ1' (layout(rgba32f ) coherent volatile restrict uniform lowp image2D)\r
+0:?     'badQ2' (layout(rgba8i ) coherent volatile restrict uniform highp iimage2D)\r
+0:?     'badQ3' (layout(rgba16ui ) coherent volatile restrict uniform highp uimage2D)\r
+0:?     'wo' (layout(column_major shared ) writeonly buffer block{layout(column_major shared ) buffer highp int value, layout(column_major shared ) buffer implicitly-sized array of highp float values})\r
+0:?     'multio' (layout(column_major shared ) buffer block{layout(column_major shared ) readonly buffer highp int value, layout(column_major shared ) writeonly buffer implicitly-sized array of highp float values})\r
 \r
index 388d4a7..ae7da92 100644 (file)
@@ -22,7 +22,7 @@ MaxComputeWorkGroupCountX 65535
 MaxComputeWorkGroupCountY 65535\r
 MaxComputeWorkGroupCountZ 65535\r
 MaxComputeWorkGroupSizeX 1024\r
-MaxComputeWorkGroupSizeX 1024\r
+MaxComputeWorkGroupSizeY 1024\r
 MaxComputeWorkGroupSizeZ 64\r
 MaxComputeUniformComponents 1024\r
 MaxComputeTextureImageUnits 16\r
index cf4265f..883337d 100644 (file)
@@ -187,10 +187,8 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT
 //
 // Returns the added node.
 //
-TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc loc)
+TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc)
 {
-    TIntermTyped* child = childNode->getAsTyped();
-
     if (child->getType().getBasicType() == EbtBlock)
         return 0;
 
index b19e1e4..f25ea46 100644 (file)
@@ -678,6 +678,34 @@ void TParseContext::checkIoArrayConsistency(TSourceLoc loc, int requiredSize, co
     }
 }
 
+// Handle seeing a binary node with a math operation.
+TIntermTyped* TParseContext::handleBinaryMath(TSourceLoc loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right)
+{
+    rValueErrorCheck(loc, str, left->getAsTyped());
+    rValueErrorCheck(loc, str, right->getAsTyped());
+
+    TIntermTyped* result = intermediate.addBinaryMath(op, left, right, loc);
+    if (! result)
+        binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
+
+    return result;
+}
+
+// Handle seeing a unary node with a math operation.
+TIntermTyped* TParseContext::handleUnaryMath(TSourceLoc loc, const char* str, TOperator op, TIntermTyped* childNode)
+{
+    rValueErrorCheck(loc, str, childNode);
+
+    TIntermTyped* result = intermediate.addUnaryMath(op, childNode, loc);
+
+    if (result)
+        return result;
+    else
+        unaryOpError(loc, str, childNode->getCompleteString());
+        
+    return childNode;
+}
+
 //
 // Handle seeing a base.field dereference in the grammar.
 //
@@ -1540,7 +1568,6 @@ void TParseContext::variableCheck(TIntermTyped*& nodePtr)
 //
 bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermTyped* node)
 {
-    TIntermSymbol* symNode = node->getAsSymbolNode();
     TIntermBinary* binaryNode = node->getAsBinaryNode();
 
     if (binaryNode) {
@@ -1582,6 +1609,7 @@ bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermType
 
 
     const char* symbol = 0;
+    TIntermSymbol* symNode = node->getAsSymbolNode();
     if (symNode != 0)
         symbol = symNode->getName().c_str();
 
@@ -1644,6 +1672,32 @@ bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermType
     return true;
 }
 
+// Test for and give an error if the node can't be read from.
+void TParseContext::rValueErrorCheck(TSourceLoc loc, const char* op, TIntermTyped* node)
+{
+    if (! node)
+        return;
+
+    TIntermBinary* binaryNode = node->getAsBinaryNode();
+    if (binaryNode) {
+        switch(binaryNode->getOp()) {
+        case EOpIndexDirect:
+        case EOpIndexIndirect:
+        case EOpIndexDirectStruct:
+        case EOpVectorSwizzle:
+            rValueErrorCheck(loc, op, binaryNode->getLeft());
+        default:
+            break;
+        }
+
+        return;
+    }
+
+    TIntermSymbol* symNode = node->getAsSymbolNode();
+    if (symNode && symNode->getQualifier().writeonly)
+        error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
+}
+
 //
 // Both test, and if necessary spit out an error, to see if the node is really
 // a constant.
@@ -3530,6 +3584,15 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type)
                 error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
             if (type.getSampler().type == EbtUint && qualifier.layoutFormat < ElfIntGuard)
                 error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
+
+            if (profile == EEsProfile) {
+                // "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must 
+                // specify either memory qualifier readonly or the memory qualifier writeonly."
+                if (! (qualifier.layoutFormat == ElfR32f || qualifier.layoutFormat == ElfR32i || qualifier.layoutFormat == ElfR32ui)) {
+                    if (! qualifier.readonly && ! qualifier.writeonly)
+                        error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
+                }
+            }
         }
     } else if (type.isImage() && ! qualifier.writeonly)
         error(loc, "image variables not declared 'writeonly' must have a format layout qualifier", "", "");
@@ -3828,7 +3891,9 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
     if (voidErrorCheck(loc, identifier, type.getBasicType()))
         return 0;
 
-    if (! initializer)
+    if (initializer)        
+        rValueErrorCheck(loc, "initializer", initializer);
+    else
         nonInitConstCheck(loc, identifier, type);
 
     invariantCheck(loc, type, identifier);
@@ -4118,8 +4183,9 @@ TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType&
 //
 TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, const TType& type, TOperator op)
 {
-    if (node == 0)
+    if (node == 0 || node->getAsTyped() == 0)
         return 0;
+    rValueErrorCheck(loc, "constructor", node->getAsTyped());
 
     TIntermAggregate* aggrNode = node->getAsAggregate();
 
@@ -4150,7 +4216,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
         else if (op == EOpConstructStruct)
             newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLoc());
         else
-            newNode = constructBuiltIn(type, op, node, node->getLoc(), false);
+            newNode = constructBuiltIn(type, op, node->getAsTyped(), node->getLoc(), false);
 
         if (newNode && (type.isArray() || op == EOpConstructStruct))
             newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
@@ -4178,7 +4244,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
         else if (op == EOpConstructStruct)
             newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
         else
-            newNode = constructBuiltIn(type, op, *p, node->getLoc(), true);
+            newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true);
 
         if (newNode)
             *p = newNode;
@@ -4198,7 +4264,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
 //
 // Returns 0 for an error or the constructed node.
 //
-TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermNode* node, TSourceLoc loc, bool subset)
+TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, TSourceLoc loc, bool subset)
 {
     TIntermTyped* newNode;
     TOperator basicOp;
index 0d1f018..5fc676d 100644 (file)
@@ -95,6 +95,8 @@ public:
     int getIoArrayImplicitSize() const;
     void checkIoArrayConsistency(TSourceLoc, int requiredSize, const char* feature, TType&, const TString&);
 
+    TIntermTyped* handleBinaryMath(TSourceLoc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
+    TIntermTyped* handleUnaryMath(TSourceLoc, const char* str, TOperator op, TIntermTyped* childNode);
     TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field);
     TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function, bool prototype);
     TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&);
@@ -111,6 +113,7 @@ public:
     void binaryOpError(TSourceLoc, const char* op, TString left, TString right);
     void variableCheck(TIntermTyped*& nodePtr);
     bool lValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*);
+    void rValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*);
     void constantValueCheck(TIntermTyped* node, const char* token);
     void integerCheck(const TIntermTyped* node, const char* token);
     void globalCheck(TSourceLoc, const char* token);
@@ -170,7 +173,7 @@ public:
     TIntermNode* declareVariable(TSourceLoc, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
     TIntermTyped* addConstructor(TSourceLoc, TIntermNode*, const TType&, TOperator);
     TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
-    TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
+    TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, TSourceLoc, bool subset);
     void declareBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
     void fixBlockLocations(TSourceLoc, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
     void fixBlockXfbOffsets(TSourceLoc, TQualifier&, TTypeList&);
index 1d7c417..cb01d08 100644 (file)
@@ -677,8 +677,7 @@ int TScanContext::tokenizeIdentifier()
         if (parseContext.profile == EEsProfile && parseContext.version >= 310 ||
             parseContext.extensionsTurnedOn(1, &GL_ARB_shader_atomic_counters))
             return keyword;
-        else
-            return es30ReservedFromGLSL(420);
+        return es30ReservedFromGLSL(420);
 
     case COHERENT:
     case RESTRICT:
@@ -686,10 +685,11 @@ int TScanContext::tokenizeIdentifier()
     case WRITEONLY:
         if (parseContext.profile == EEsProfile && parseContext.version >= 310)
             return keyword;
-        else
-            return es30ReservedFromGLSL(parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store) ? 130 : 420);
+        return es30ReservedFromGLSL(parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store) ? 130 : 420);
 
     case VOLATILE:
+        if (parseContext.profile == EEsProfile && parseContext.version >= 310)
+            return keyword;
         if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile || (parseContext.version < 420 && ! parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store))))
             reservedWord();
         return keyword;
index f2e25b3..5966940 100644 (file)
@@ -265,20 +265,12 @@ postfix_expression
     | postfix_expression INC_OP {\r
         parseContext.variableCheck($1);\r
         parseContext.lValueErrorCheck($2.loc, "++", $1);\r
-        $$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.unaryOpError($2.loc, "++", $1->getCompleteString());\r
-            $$ = $1;\r
-        }\r
+        $$ = parseContext.handleUnaryMath($2.loc, "++", EOpPostIncrement, $1);\r
     }\r
     | postfix_expression DEC_OP {\r
         parseContext.variableCheck($1);\r
         parseContext.lValueErrorCheck($2.loc, "--", $1);\r
-        $$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.unaryOpError($2.loc, "--", $1->getCompleteString());\r
-            $$ = $1;\r
-        }\r
+        $$ = parseContext.handleUnaryMath($2.loc, "--", EOpPostDecrement, $1);\r
     }\r
     ;\r
 \r
@@ -391,34 +383,22 @@ unary_expression
     }\r
     | INC_OP unary_expression {\r
         parseContext.lValueErrorCheck($1.loc, "++", $2);\r
-        $$ = parseContext.intermediate.addUnaryMath(EOpPreIncrement, $2, $1.loc);\r
-        if ($$ == 0) {\r
-            parseContext.unaryOpError($1.loc, "++", $2->getCompleteString());\r
-            $$ = $2;\r
-        }\r
+        $$ = parseContext.handleUnaryMath($1.loc, "++", EOpPreIncrement, $2);\r
     }\r
     | DEC_OP unary_expression {\r
         parseContext.lValueErrorCheck($1.loc, "--", $2);\r
-        $$ = parseContext.intermediate.addUnaryMath(EOpPreDecrement, $2, $1.loc);\r
-        if ($$ == 0) {\r
-            parseContext.unaryOpError($1.loc, "--", $2->getCompleteString());\r
-            $$ = $2;\r
-        }\r
+        $$ = parseContext.handleUnaryMath($1.loc, "--", EOpPreDecrement, $2);\r
     }\r
     | unary_operator unary_expression {\r
         if ($1.op != EOpNull) {\r
-            $$ = parseContext.intermediate.addUnaryMath($1.op, $2, $1.loc);\r
-            if ($$ == 0) {\r
-                char errorOp[2] = {0, 0};\r
-                switch($1.op) {\r
-                case EOpNegative:   errorOp[0] = '-'; break;\r
-                case EOpLogicalNot: errorOp[0] = '!'; break;\r
-                case EOpBitwiseNot: errorOp[0] = '~'; break;\r
-                default: break; // some compilers want this\r
-                }\r
-                parseContext.unaryOpError($1.loc, errorOp, $2->getCompleteString());\r
-                $$ = $2;\r
+            char errorOp[2] = {0, 0};\r
+            switch($1.op) {\r
+            case EOpNegative:   errorOp[0] = '-'; break;\r
+            case EOpLogicalNot: errorOp[0] = '!'; break;\r
+            case EOpBitwiseNot: errorOp[0] = '~'; break;\r
+            default: break; // some compilers want this\r
             }\r
+            $$ = parseContext.handleUnaryMath($1.loc, errorOp, $1.op, $2);\r
         } else {\r
             $$ = $2;\r
             if ($$->getAsConstantUnion())\r
@@ -440,44 +420,34 @@ unary_operator
 multiplicative_expression\r
     : unary_expression { $$ = $1; }\r
     | multiplicative_expression STAR unary_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "*", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "*", EOpMul, $1, $3);\r
+        if ($$ == 0)\r
             $$ = $1;\r
-        }\r
     }\r
     | multiplicative_expression SLASH unary_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "/", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "/", EOpDiv, $1, $3);\r
+        if ($$ == 0)\r
             $$ = $1;\r
-        }\r
     }\r
     | multiplicative_expression PERCENT unary_expression {\r
         parseContext.fullIntegerCheck($2.loc, "%");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "%", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "%", EOpMod, $1, $3);\r
+        if ($$ == 0)\r
             $$ = $1;\r
-        }\r
     }\r
     ;\r
 \r
 additive_expression\r
     : multiplicative_expression { $$ = $1; }\r
     | additive_expression PLUS multiplicative_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpAdd, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "+", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "+", EOpAdd, $1, $3);\r
+        if ($$ == 0)\r
             $$ = $1;\r
-        }\r
     }\r
     | additive_expression DASH multiplicative_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpSub, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "-", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "-", EOpSub, $1, $3);\r
+        if ($$ == 0)\r
             $$ = $1;\r
-        }\r
     }\r
     ;\r
 \r
@@ -485,51 +455,39 @@ shift_expression
     : additive_expression { $$ = $1; }\r
     | shift_expression LEFT_OP additive_expression {\r
         parseContext.fullIntegerCheck($2.loc, "bit shift left");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "<<", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "<<", EOpLeftShift, $1, $3);\r
+        if ($$ == 0)\r
             $$ = $1;\r
-        }\r
     }\r
     | shift_expression RIGHT_OP additive_expression {\r
         parseContext.fullIntegerCheck($2.loc, "bit shift right");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, ">>", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, ">>", EOpRightShift, $1, $3);\r
+        if ($$ == 0)\r
             $$ = $1;\r
-        }\r
     }\r
     ;\r
 \r
 relational_expression\r
     : shift_expression { $$ = $1; }\r
     | relational_expression LEFT_ANGLE shift_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "<", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "<", EOpLessThan, $1, $3);\r
+        if ($$ == 0)\r
             $$ = parseContext.intermediate.addConstantUnion(false, $2.loc);\r
-        }\r
     }\r
     | relational_expression RIGHT_ANGLE shift_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, ">", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, ">", EOpGreaterThan, $1, $3);\r
+        if ($$ == 0)\r
             $$ = parseContext.intermediate.addConstantUnion(false, $2.loc);\r
-        }\r
     }\r
     | relational_expression LE_OP shift_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "<=", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "<=", EOpLessThanEqual, $1, $3);\r
+        if ($$ == 0)\r
             $$ = parseContext.intermediate.addConstantUnion(false, $2.loc);\r
-        }\r
     }\r
     | relational_expression GE_OP shift_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, ">=", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, ">=", EOpGreaterThanEqual, $1, $3);\r
+        if ($$ == 0)\r
             $$ = parseContext.intermediate.addConstantUnion(false, $2.loc);\r
-        }\r
     }\r
     ;\r
 \r
@@ -538,20 +496,16 @@ equality_expression
     | equality_expression EQ_OP relational_expression  {\r
         parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison");\r
         parseContext.opaqueCheck($2.loc, $1->getType(), "==");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "==", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "==", EOpEqual, $1, $3);\r
+        if ($$ == 0)\r
             $$ = parseContext.intermediate.addConstantUnion(false, $2.loc);\r
-        }\r
     }\r
     | equality_expression NE_OP relational_expression {\r
         parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison");\r
         parseContext.opaqueCheck($2.loc, $1->getType(), "!=");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "!=", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "!=", EOpNotEqual, $1, $3);\r
+        if ($$ == 0)\r
             $$ = parseContext.intermediate.addConstantUnion(false, $2.loc);\r
-        }\r
     }\r
     ;\r
 \r
@@ -559,11 +513,9 @@ and_expression
     : equality_expression { $$ = $1; }\r
     | and_expression AMPERSAND equality_expression {\r
         parseContext.fullIntegerCheck($2.loc, "bitwise and");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "&", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "&", EOpAnd, $1, $3);\r
+        if ($$ == 0)\r
             $$ = $1;\r
-        }\r
     }\r
     ;\r
 \r
@@ -571,11 +523,9 @@ exclusive_or_expression
     : and_expression { $$ = $1; }\r
     | exclusive_or_expression CARET and_expression {\r
         parseContext.fullIntegerCheck($2.loc, "bitwise exclusive or");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "^", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "^", EOpExclusiveOr, $1, $3);\r
+        if ($$ == 0)\r
             $$ = $1;\r
-        }\r
     }\r
     ;\r
 \r
@@ -583,44 +533,36 @@ inclusive_or_expression
     : exclusive_or_expression { $$ = $1; }\r
     | inclusive_or_expression VERTICAL_BAR exclusive_or_expression {\r
         parseContext.fullIntegerCheck($2.loc, "bitwise inclusive or");\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "|", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "|", EOpInclusiveOr, $1, $3);\r
+        if ($$ == 0)\r
             $$ = $1;\r
-        }\r
     }\r
     ;\r
 \r
 logical_and_expression\r
     : inclusive_or_expression { $$ = $1; }\r
     | logical_and_expression AND_OP inclusive_or_expression {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "&&", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "&&", EOpLogicalAnd, $1, $3);\r
+        if ($$ == 0)\r
             $$ = parseContext.intermediate.addConstantUnion(false, $2.loc);\r
-        }\r
     }\r
     ;\r
 \r
 logical_xor_expression\r
     : logical_and_expression { $$ = $1; }\r
     | logical_xor_expression XOR_OP logical_and_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "^^", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "^^", EOpLogicalXor, $1, $3);\r
+        if ($$ == 0)\r
             $$ = parseContext.intermediate.addConstantUnion(false, $2.loc);\r
-        }\r
     }\r
     ;\r
 \r
 logical_or_expression\r
     : logical_xor_expression { $$ = $1; }\r
     | logical_or_expression OR_OP logical_xor_expression  {\r
-        $$ = parseContext.intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.loc);\r
-        if ($$ == 0) {\r
-            parseContext.binaryOpError($2.loc, "||", $1->getCompleteString(), $3->getCompleteString());\r
+        $$ = parseContext.handleBinaryMath($2.loc, "||", EOpLogicalOr, $1, $3);\r
+        if ($$ == 0)\r
             $$ = parseContext.intermediate.addConstantUnion(false, $2.loc);\r
-        }\r
     }\r
     ;\r
 \r
@@ -628,7 +570,9 @@ conditional_expression
     : logical_or_expression { $$ = $1; }\r
     | logical_or_expression QUESTION expression COLON assignment_expression {\r
         parseContext.boolCheck($2.loc, $1);\r
-\r
+        parseContext.rValueErrorCheck($2.loc, "?", $1);\r
+        parseContext.rValueErrorCheck($4.loc, ":", $3);\r
+        parseContext.rValueErrorCheck($4.loc, ":", $5);\r
         $$ = parseContext.intermediate.addSelection($1, $3, $5, $2.loc);\r
         if ($$ == 0) {\r
             parseContext.binaryOpError($2.loc, ":", $3->getCompleteString(), $5->getCompleteString());\r
@@ -643,6 +587,7 @@ assignment_expression
         parseContext.arrayObjectCheck($2.loc, $1->getType(), "array assignment");\r
         parseContext.opaqueCheck($2.loc, $1->getType(), "=");\r
         parseContext.lValueErrorCheck($2.loc, "assign", $1);\r
+        parseContext.rValueErrorCheck($2.loc, "assign", $3);\r
         $$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.loc);\r
         if ($$ == 0) {\r
             parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString());\r
index 1331395..69f4682 100644 (file)
@@ -161,7 +161,7 @@ public:
     TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
     TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
     TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
-    TIntermTyped* addUnaryMath(TOperator, TIntermNode* child, TSourceLoc);
+    TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc);
     TIntermTyped* addBuiltInFunctionCall(TSourceLoc line, TOperator, bool unary, TIntermNode*, const TType& returnType);
     bool canImplicitlyPromote(TBasicType from, TBasicType to) const;
     TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);