\r
void foo(inout float a) {}\r
\r
+int bar()\r
+{\r
+ return 1;\r
+}\r
+\r
void main()\r
{\r
while (ga < gb) { }\r
\r
do { } while (false);\r
- \r
- for ( ga = 0; ; );\r
- for ( bool a = false; ; );\r
- for (float a = 0.0; a == sin(f); );\r
- for ( int a = 0; a < 10; a *= 2);\r
- for ( int a = 0; a <= 20; ++a) --a;\r
+\r
+ for ( ; ; ); // ERROR\r
+ for ( ; ga==gb; ); // ERROR\r
+ for ( ; ; f++); // ERROR\r
+ for ( ga = 0; ; ); // ERROR\r
+ for ( bool a = false; ; ); // ERROR\r
+ for (float a = 0.0; a == sin(f); ); // ERROR\r
+ for ( int a = 0; a < 10; a *= 2); // ERROR\r
+ for ( int a = 0; a <= 20; a++) --a; // ERROR\r
+ for ( int a = 0; a <= 20; a++) { if (ga==0) a = 4; } // ERROR\r
for (float a = 0.0; a <= 20.0; a += 2.0);\r
- for (float a = 0.0; a <= 20.0; a += 2.0) foo(a);\r
+ for (float a = 0.0; a != 20.0; a -= 2.0) { if (ga==0) ga = 4; }\r
+ for (float a = 0.0; a == 20.0; a--) for (float a = 0.0; a == 20.0; a--); // two different 'a's, everything okay\r
+ for (float a = 0.0; a <= 20.0; a += 2.0);\r
+ for (float a = 0.0; a <= 20.0; a += 2.0);\r
+ for (float a = 0.0; a > 2.0 * 20.0; a += v3.y);\r
+ for (float a = 0.0; a >= 20.0; a += 2.0) foo(a); // ERROR\r
\r
int ia[9];\r
\r
- fsa[ga];\r
+ fsa[ga]; // ERROR\r
fua[ga];\r
- am3[ga];\r
- av2[ga];\r
- va[ga];\r
- m2[ga];\r
- v3[ga];\r
- ia[ga];\r
-\r
- for ( int a = 3; a >= 0; --a) {\r
+ am3[ga]; // ERROR\r
+ av2[ga]; // ERROR\r
+ va[2+ga]; // ERROR\r
+ m2[ga]; // ERROR\r
+ v3[ga/2]; // ERROR\r
+ ia[ga]; // ERROR\r
+\r
+ for (int a = 3; a >= 0; a--) {\r
fsa[a];\r
fua[a+2];\r
am3[3*a];\r
m2[a/2];\r
v3[a];\r
ia[a];\r
+ ia[bar()]; // ERROR\r
}\r
\r
+ fsa[2];\r
+ fua[3];\r
+ am3[2];\r
+ av2[1];\r
+ va[1];\r
+ m2[1];\r
+ v3[1];\r
+ ia[3];\r
}\r
0:15 Function Definition: foo(f1; (void)\r
0:15 Function Parameters: \r
0:15 'a' (inout highp float)\r
-0:17 Function Definition: main( (void)\r
+0:17 Function Definition: bar( (highp int)\r
0:17 Function Parameters: \r
0:19 Sequence\r
-0:19 Loop with condition tested first\r
-0:19 Loop Condition\r
-0:19 Compare Less Than (bool)\r
-0:19 'ga' (highp int)\r
-0:19 'gb' (highp int)\r
-0:19 No loop body\r
-0:21 Loop with condition not tested first\r
-0:21 Loop Condition\r
-0:21 Constant:\r
-0:21 false (const bool)\r
-0:21 No loop body\r
-0:23 Sequence\r
-0:23 move second child to first child (highp int)\r
-0:23 'ga' (highp int)\r
-0:23 Constant:\r
-0:23 0 (const int)\r
-0:23 Loop with condition tested first\r
-0:23 No loop condition\r
-0:23 No loop body\r
-0:24 Sequence\r
-0:24 Sequence\r
-0:24 move second child to first child (bool)\r
-0:24 'a' (bool)\r
-0:24 Constant:\r
-0:24 false (const bool)\r
-0:24 Loop with condition tested first\r
-0:24 No loop condition\r
-0:24 No loop body\r
-0:25 Sequence\r
-0:25 Sequence\r
-0:25 move second child to first child (highp float)\r
-0:25 'a' (highp float)\r
-0:25 Constant:\r
-0:25 0.000000\r
-0:25 Loop with condition tested first\r
-0:25 Loop Condition\r
-0:25 Compare Equal (bool)\r
-0:25 'a' (highp float)\r
-0:25 sine (highp float)\r
-0:25 'f' (highp float)\r
-0:25 No loop body\r
-0:26 Sequence\r
-0:26 Sequence\r
-0:26 move second child to first child (highp int)\r
-0:26 'a' (highp int)\r
-0:26 Constant:\r
-0:26 0 (const int)\r
-0:26 Loop with condition tested first\r
-0:26 Loop Condition\r
-0:26 Compare Less Than (bool)\r
-0:26 'a' (highp int)\r
-0:26 Constant:\r
-0:26 10 (const int)\r
-0:26 No loop body\r
-0:26 Loop Terminal Expression\r
-0:26 multiply second child into first child (highp int)\r
-0:26 'a' (highp int)\r
-0:26 Constant:\r
-0:26 2 (const int)\r
-0:27 Sequence\r
-0:27 Sequence\r
-0:27 move second child to first child (highp int)\r
-0:27 'a' (highp int)\r
-0:27 Constant:\r
-0:27 0 (const int)\r
-0:27 Loop with condition tested first\r
-0:27 Loop Condition\r
-0:27 Compare Less Than or Equal (bool)\r
-0:27 'a' (highp int)\r
-0:27 Constant:\r
-0:27 20 (const int)\r
-0:27 Loop Body\r
-0:27 Pre-Decrement (highp int)\r
-0:27 'a' (highp int)\r
-0:27 Loop Terminal Expression\r
-0:27 Pre-Increment (highp int)\r
-0:27 'a' (highp int)\r
+0:19 Branch: Return with expression\r
+0:19 Constant:\r
+0:19 1 (const int)\r
+0:22 Function Definition: main( (void)\r
+0:22 Function Parameters: \r
+0:24 Sequence\r
+0:24 Loop with condition tested first\r
+0:24 Loop Condition\r
+0:24 Compare Less Than (bool)\r
+0:24 'ga' (highp int)\r
+0:24 'gb' (highp int)\r
+0:24 No loop body\r
+0:26 Loop with condition not tested first\r
+0:26 Loop Condition\r
+0:26 Constant:\r
+0:26 false (const bool)\r
+0:26 No loop body\r
0:28 Sequence\r
-0:28 Sequence\r
-0:28 move second child to first child (highp float)\r
-0:28 'a' (highp float)\r
-0:28 Constant:\r
-0:28 0.000000\r
0:28 Loop with condition tested first\r
-0:28 Loop Condition\r
-0:28 Compare Less Than or Equal (bool)\r
-0:28 'a' (highp float)\r
-0:28 Constant:\r
-0:28 20.000000\r
+0:28 No loop condition\r
0:28 No loop body\r
-0:28 Loop Terminal Expression\r
-0:28 add second child into first child (highp float)\r
-0:28 'a' (highp float)\r
-0:28 Constant:\r
-0:28 2.000000\r
0:29 Sequence\r
-0:29 Sequence\r
-0:29 move second child to first child (highp float)\r
-0:29 'a' (highp float)\r
-0:29 Constant:\r
-0:29 0.000000\r
0:29 Loop with condition tested first\r
0:29 Loop Condition\r
-0:29 Compare Less Than or Equal (bool)\r
-0:29 'a' (highp float)\r
-0:29 Constant:\r
-0:29 20.000000\r
-0:29 Loop Body\r
-0:29 Function Call: foo(f1; (void)\r
-0:29 'a' (highp float)\r
-0:29 Loop Terminal Expression\r
-0:29 add second child into first child (highp float)\r
-0:29 'a' (highp float)\r
-0:29 Constant:\r
-0:29 2.000000\r
-0:33 indirect index (uniform lowp sampler2D)\r
-0:33 'fsa' (uniform 3-element array of lowp sampler2D)\r
-0:33 'ga' (highp int)\r
-0:34 indirect index (uniform highp float)\r
-0:34 'fua' (uniform 10-element array of highp float)\r
-0:34 'ga' (highp int)\r
-0:35 indirect index (in highp 3-component vector of float)\r
-0:35 'am3' (in highp 3X3 matrix of float)\r
-0:35 'ga' (highp int)\r
-0:36 indirect index (in highp float)\r
-0:36 'av2' (in highp 2-component vector of float)\r
-0:36 'ga' (highp int)\r
-0:37 indirect index (smooth out highp 4-component vector of float)\r
-0:37 'va' (smooth out 4-element array of highp 4-component vector of float)\r
-0:37 'ga' (highp int)\r
-0:38 indirect index (const highp 2-component vector of float)\r
-0:38 Constant:\r
-0:38 1.000000\r
-0:38 0.000000\r
-0:38 0.000000\r
-0:38 1.000000\r
-0:38 'ga' (highp int)\r
-0:39 indirect index (const highp float)\r
-0:39 Constant:\r
-0:39 2.000000\r
-0:39 2.000000\r
-0:39 2.000000\r
-0:39 'ga' (highp int)\r
-0:40 indirect index (highp int)\r
-0:40 'ia' (9-element array of highp int)\r
-0:40 'ga' (highp int)\r
+0:29 Compare Equal (bool)\r
+0:29 'ga' (highp int)\r
+0:29 'gb' (highp int)\r
+0:29 No loop body\r
+0:30 Sequence\r
+0:30 Loop with condition tested first\r
+0:30 No loop condition\r
+0:30 No loop body\r
+0:30 Loop Terminal Expression\r
+0:30 Post-Increment (highp float)\r
+0:30 'f' (highp float)\r
+0:31 Sequence\r
+0:31 move second child to first child (highp int)\r
+0:31 'ga' (highp int)\r
+0:31 Constant:\r
+0:31 0 (const int)\r
+0:31 Loop with condition tested first\r
+0:31 No loop condition\r
+0:31 No loop body\r
+0:32 Sequence\r
+0:32 Sequence\r
+0:32 move second child to first child (bool)\r
+0:32 'a' (bool)\r
+0:32 Constant:\r
+0:32 false (const bool)\r
+0:32 Loop with condition tested first\r
+0:32 No loop condition\r
+0:32 No loop body\r
+0:33 Sequence\r
+0:33 Sequence\r
+0:33 move second child to first child (highp float)\r
+0:33 'a' (highp float)\r
+0:33 Constant:\r
+0:33 0.000000\r
+0:33 Loop with condition tested first\r
+0:33 Loop Condition\r
+0:33 Compare Equal (bool)\r
+0:33 'a' (highp float)\r
+0:33 sine (highp float)\r
+0:33 'f' (highp float)\r
+0:33 No loop body\r
+0:34 Sequence\r
+0:34 Sequence\r
+0:34 move second child to first child (highp int)\r
+0:34 'a' (highp int)\r
+0:34 Constant:\r
+0:34 0 (const int)\r
+0:34 Loop with condition tested first\r
+0:34 Loop Condition\r
+0:34 Compare Less Than (bool)\r
+0:34 'a' (highp int)\r
+0:34 Constant:\r
+0:34 10 (const int)\r
+0:34 No loop body\r
+0:34 Loop Terminal Expression\r
+0:34 multiply second child into first child (highp int)\r
+0:34 'a' (highp int)\r
+0:34 Constant:\r
+0:34 2 (const int)\r
+0:35 Sequence\r
+0:35 Sequence\r
+0:35 move second child to first child (highp int)\r
+0:35 'a' (highp int)\r
+0:35 Constant:\r
+0:35 0 (const int)\r
+0:35 Loop with condition tested first\r
+0:35 Loop Condition\r
+0:35 Compare Less Than or Equal (bool)\r
+0:35 'a' (highp int)\r
+0:35 Constant:\r
+0:35 20 (const int)\r
+0:35 Loop Body\r
+0:35 Pre-Decrement (highp int)\r
+0:35 'a' (highp int)\r
+0:35 Loop Terminal Expression\r
+0:35 Post-Increment (highp int)\r
+0:35 'a' (highp int)\r
+0:36 Sequence\r
+0:36 Sequence\r
+0:36 move second child to first child (highp int)\r
+0:36 'a' (highp int)\r
+0:36 Constant:\r
+0:36 0 (const int)\r
+0:36 Loop with condition tested first\r
+0:36 Loop Condition\r
+0:36 Compare Less Than or Equal (bool)\r
+0:36 'a' (highp int)\r
+0:36 Constant:\r
+0:36 20 (const int)\r
+0:36 Loop Body\r
+0:36 Sequence\r
+0:36 Test condition and select (void)\r
+0:36 Condition\r
+0:36 Compare Equal (bool)\r
+0:36 'ga' (highp int)\r
+0:36 Constant:\r
+0:36 0 (const int)\r
+0:36 true case\r
+0:36 move second child to first child (highp int)\r
+0:36 'a' (highp int)\r
+0:36 Constant:\r
+0:36 4 (const int)\r
+0:36 Loop Terminal Expression\r
+0:36 Post-Increment (highp int)\r
+0:36 'a' (highp int)\r
+0:37 Sequence\r
+0:37 Sequence\r
+0:37 move second child to first child (highp float)\r
+0:37 'a' (highp float)\r
+0:37 Constant:\r
+0:37 0.000000\r
+0:37 Loop with condition tested first\r
+0:37 Loop Condition\r
+0:37 Compare Less Than or Equal (bool)\r
+0:37 'a' (highp float)\r
+0:37 Constant:\r
+0:37 20.000000\r
+0:37 No loop body\r
+0:37 Loop Terminal Expression\r
+0:37 add second child into first child (highp float)\r
+0:37 'a' (highp float)\r
+0:37 Constant:\r
+0:37 2.000000\r
+0:38 Sequence\r
+0:38 Sequence\r
+0:38 move second child to first child (highp float)\r
+0:38 'a' (highp float)\r
+0:38 Constant:\r
+0:38 0.000000\r
+0:38 Loop with condition tested first\r
+0:38 Loop Condition\r
+0:38 Compare Not Equal (bool)\r
+0:38 'a' (highp float)\r
+0:38 Constant:\r
+0:38 20.000000\r
+0:38 Loop Body\r
+0:38 Sequence\r
+0:38 Test condition and select (void)\r
+0:38 Condition\r
+0:38 Compare Equal (bool)\r
+0:38 'ga' (highp int)\r
+0:38 Constant:\r
+0:38 0 (const int)\r
+0:38 true case\r
+0:38 move second child to first child (highp int)\r
+0:38 'ga' (highp int)\r
+0:38 Constant:\r
+0:38 4 (const int)\r
+0:38 Loop Terminal Expression\r
+0:38 subtract second child into first child (highp float)\r
+0:38 'a' (highp float)\r
+0:38 Constant:\r
+0:38 2.000000\r
+0:39 Sequence\r
+0:39 Sequence\r
+0:39 move second child to first child (highp float)\r
+0:39 'a' (highp float)\r
+0:39 Constant:\r
+0:39 0.000000\r
+0:39 Loop with condition tested first\r
+0:39 Loop Condition\r
+0:39 Compare Equal (bool)\r
+0:39 'a' (highp float)\r
+0:39 Constant:\r
+0:39 20.000000\r
+0:39 Loop Body\r
+0:39 Sequence\r
+0:39 Sequence\r
+0:39 move second child to first child (highp float)\r
+0:39 'a' (highp float)\r
+0:39 Constant:\r
+0:39 0.000000\r
+0:39 Loop with condition tested first\r
+0:39 Loop Condition\r
+0:39 Compare Equal (bool)\r
+0:39 'a' (highp float)\r
+0:39 Constant:\r
+0:39 20.000000\r
+0:39 No loop body\r
+0:39 Loop Terminal Expression\r
+0:39 Post-Decrement (highp float)\r
+0:39 'a' (highp float)\r
+0:39 Loop Terminal Expression\r
+0:39 Post-Decrement (highp float)\r
+0:39 'a' (highp float)\r
+0:40 Sequence\r
+0:40 Sequence\r
+0:40 move second child to first child (highp float)\r
+0:40 'a' (highp float)\r
+0:40 Constant:\r
+0:40 0.000000\r
+0:40 Loop with condition tested first\r
+0:40 Loop Condition\r
+0:40 Compare Less Than or Equal (bool)\r
+0:40 'a' (highp float)\r
+0:40 Constant:\r
+0:40 20.000000\r
+0:40 No loop body\r
+0:40 Loop Terminal Expression\r
+0:40 add second child into first child (highp float)\r
+0:40 'a' (highp float)\r
+0:40 Constant:\r
+0:40 2.000000\r
+0:41 Sequence\r
+0:41 Sequence\r
+0:41 move second child to first child (highp float)\r
+0:41 'a' (highp float)\r
+0:41 Constant:\r
+0:41 0.000000\r
+0:41 Loop with condition tested first\r
+0:41 Loop Condition\r
+0:41 Compare Less Than or Equal (bool)\r
+0:41 'a' (highp float)\r
+0:41 Constant:\r
+0:41 20.000000\r
+0:41 No loop body\r
+0:41 Loop Terminal Expression\r
+0:41 add second child into first child (highp float)\r
+0:41 'a' (highp float)\r
+0:41 Constant:\r
+0:41 2.000000\r
0:42 Sequence\r
0:42 Sequence\r
-0:42 move second child to first child (highp int)\r
-0:42 'a' (highp int)\r
+0:42 move second child to first child (highp float)\r
+0:42 'a' (highp float)\r
0:42 Constant:\r
-0:42 3 (const int)\r
+0:42 0.000000\r
0:42 Loop with condition tested first\r
0:42 Loop Condition\r
-0:42 Compare Greater Than or Equal (bool)\r
-0:42 'a' (highp int)\r
+0:42 Compare Greater Than (bool)\r
+0:42 'a' (highp float)\r
0:42 Constant:\r
-0:42 0 (const int)\r
-0:42 Loop Body\r
-0:43 Sequence\r
-0:43 indirect index (uniform lowp sampler2D)\r
-0:43 'fsa' (uniform 3-element array of lowp sampler2D)\r
-0:43 'a' (highp int)\r
-0:44 indirect index (uniform highp float)\r
-0:44 'fua' (uniform 10-element array of highp float)\r
-0:44 add (highp int)\r
-0:44 'a' (highp int)\r
-0:44 Constant:\r
-0:44 2 (const int)\r
-0:45 indirect index (in highp 3-component vector of float)\r
-0:45 'am3' (in highp 3X3 matrix of float)\r
-0:45 component-wise multiply (highp int)\r
-0:45 Constant:\r
-0:45 3 (const int)\r
-0:45 'a' (highp int)\r
-0:46 indirect index (in highp float)\r
-0:46 'av2' (in highp 2-component vector of float)\r
-0:46 component-wise multiply (highp int)\r
-0:46 Constant:\r
-0:46 3 (const int)\r
-0:46 'a' (highp int)\r
-0:47 indirect index (smooth out highp 4-component vector of float)\r
-0:47 'va' (smooth out 4-element array of highp 4-component vector of float)\r
-0:47 subtract (highp int)\r
-0:47 'a' (highp int)\r
-0:47 Constant:\r
-0:47 1 (const int)\r
-0:48 indirect index (const highp 2-component vector of float)\r
-0:48 Constant:\r
-0:48 1.000000\r
-0:48 0.000000\r
-0:48 0.000000\r
-0:48 1.000000\r
-0:48 divide (highp int)\r
-0:48 'a' (highp int)\r
-0:48 Constant:\r
-0:48 2 (const int)\r
-0:49 indirect index (const highp float)\r
-0:49 Constant:\r
-0:49 2.000000\r
-0:49 2.000000\r
-0:49 2.000000\r
-0:49 'a' (highp int)\r
-0:50 indirect index (highp int)\r
-0:50 'ia' (9-element array of highp int)\r
-0:50 'a' (highp int)\r
+0:42 40.000000\r
+0:42 No loop body\r
0:42 Loop Terminal Expression\r
-0:42 Pre-Decrement (highp int)\r
-0:42 'a' (highp int)\r
+0:42 add second child into first child (highp float)\r
+0:42 'a' (highp float)\r
+0:42 Constant:\r
+0:42 2.000000\r
+0:43 Sequence\r
+0:43 Sequence\r
+0:43 move second child to first child (highp float)\r
+0:43 'a' (highp float)\r
+0:43 Constant:\r
+0:43 0.000000\r
+0:43 Loop with condition tested first\r
+0:43 Loop Condition\r
+0:43 Compare Greater Than or Equal (bool)\r
+0:43 'a' (highp float)\r
+0:43 Constant:\r
+0:43 20.000000\r
+0:43 Loop Body\r
+0:43 Function Call: foo(f1; (void)\r
+0:43 'a' (highp float)\r
+0:43 Loop Terminal Expression\r
+0:43 add second child into first child (highp float)\r
+0:43 'a' (highp float)\r
+0:43 Constant:\r
+0:43 2.000000\r
+0:47 indirect index (uniform lowp sampler2D)\r
+0:47 'fsa' (uniform 3-element array of lowp sampler2D)\r
+0:47 'ga' (highp int)\r
+0:48 indirect index (uniform highp float)\r
+0:48 'fua' (uniform 10-element array of highp float)\r
+0:48 'ga' (highp int)\r
+0:49 indirect index (in highp 3-component vector of float)\r
+0:49 'am3' (in highp 3X3 matrix of float)\r
+0:49 'ga' (highp int)\r
+0:50 indirect index (in highp float)\r
+0:50 'av2' (in highp 2-component vector of float)\r
+0:50 'ga' (highp int)\r
+0:51 indirect index (smooth out highp 4-component vector of float)\r
+0:51 'va' (smooth out 4-element array of highp 4-component vector of float)\r
+0:51 add (highp int)\r
+0:51 Constant:\r
+0:51 2 (const int)\r
+0:51 'ga' (highp int)\r
+0:52 indirect index (const highp 2-component vector of float)\r
+0:52 Constant:\r
+0:52 1.000000\r
+0:52 0.000000\r
+0:52 0.000000\r
+0:52 1.000000\r
+0:52 'ga' (highp int)\r
+0:53 indirect index (const highp float)\r
+0:53 Constant:\r
+0:53 2.000000\r
+0:53 2.000000\r
+0:53 2.000000\r
+0:53 divide (highp int)\r
+0:53 'ga' (highp int)\r
+0:53 Constant:\r
+0:53 2 (const int)\r
+0:54 indirect index (highp int)\r
+0:54 'ia' (9-element array of highp int)\r
+0:54 'ga' (highp int)\r
+0:56 Sequence\r
+0:56 Sequence\r
+0:56 move second child to first child (highp int)\r
+0:56 'a' (highp int)\r
+0:56 Constant:\r
+0:56 3 (const int)\r
+0:56 Loop with condition tested first\r
+0:56 Loop Condition\r
+0:56 Compare Greater Than or Equal (bool)\r
+0:56 'a' (highp int)\r
+0:56 Constant:\r
+0:56 0 (const int)\r
+0:56 Loop Body\r
+0:57 Sequence\r
+0:57 indirect index (uniform lowp sampler2D)\r
+0:57 'fsa' (uniform 3-element array of lowp sampler2D)\r
+0:57 'a' (highp int)\r
+0:58 indirect index (uniform highp float)\r
+0:58 'fua' (uniform 10-element array of highp float)\r
+0:58 add (highp int)\r
+0:58 'a' (highp int)\r
+0:58 Constant:\r
+0:58 2 (const int)\r
+0:59 indirect index (in highp 3-component vector of float)\r
+0:59 'am3' (in highp 3X3 matrix of float)\r
+0:59 component-wise multiply (highp int)\r
+0:59 Constant:\r
+0:59 3 (const int)\r
+0:59 'a' (highp int)\r
+0:60 indirect index (in highp float)\r
+0:60 'av2' (in highp 2-component vector of float)\r
+0:60 component-wise multiply (highp int)\r
+0:60 Constant:\r
+0:60 3 (const int)\r
+0:60 'a' (highp int)\r
+0:61 indirect index (smooth out highp 4-component vector of float)\r
+0:61 'va' (smooth out 4-element array of highp 4-component vector of float)\r
+0:61 subtract (highp int)\r
+0:61 'a' (highp int)\r
+0:61 Constant:\r
+0:61 1 (const int)\r
+0:62 indirect index (const highp 2-component vector of float)\r
+0:62 Constant:\r
+0:62 1.000000\r
+0:62 0.000000\r
+0:62 0.000000\r
+0:62 1.000000\r
+0:62 divide (highp int)\r
+0:62 'a' (highp int)\r
+0:62 Constant:\r
+0:62 2 (const int)\r
+0:63 indirect index (const highp float)\r
+0:63 Constant:\r
+0:63 2.000000\r
+0:63 2.000000\r
+0:63 2.000000\r
+0:63 'a' (highp int)\r
+0:64 indirect index (highp int)\r
+0:64 'ia' (9-element array of highp int)\r
+0:64 'a' (highp int)\r
+0:65 indirect index (highp int)\r
+0:65 'ia' (9-element array of highp int)\r
+0:65 Function Call: bar( (highp int)\r
+0:56 Loop Terminal Expression\r
+0:56 Post-Decrement (highp int)\r
+0:56 'a' (highp int)\r
+0:68 direct index (uniform lowp sampler2D)\r
+0:68 'fsa' (uniform 3-element array of lowp sampler2D)\r
+0:68 Constant:\r
+0:68 2 (const int)\r
+0:69 direct index (uniform highp float)\r
+0:69 'fua' (uniform 10-element array of highp float)\r
+0:69 Constant:\r
+0:69 3 (const int)\r
+0:70 direct index (in highp 3-component vector of float)\r
+0:70 'am3' (in highp 3X3 matrix of float)\r
+0:70 Constant:\r
+0:70 2 (const int)\r
+0:71 direct index (in highp float)\r
+0:71 'av2' (in highp 2-component vector of float)\r
+0:71 Constant:\r
+0:71 1 (const int)\r
+0:72 direct index (smooth out highp 4-component vector of float)\r
+0:72 'va' (smooth out 4-element array of highp 4-component vector of float)\r
+0:72 Constant:\r
+0:72 1 (const int)\r
+0:73 Constant:\r
+0:73 0.000000\r
+0:73 1.000000\r
+0:74 Constant:\r
+0:74 2.000000\r
+0:75 direct index (highp int)\r
+0:75 'ia' (9-element array of highp int)\r
+0:75 Constant:\r
+0:75 3 (const int)\r
0:? Linker Objects\r
0:? 'ga' (highp int)\r
0:? 'gb' (highp int)\r
-ERROR: 0:19: 'limitation' : while loops not available \r
-ERROR: 0:21: 'limitation' : do-while loops not available \r
-ERROR: 2 compilation errors. No code generated.\r
+ERROR: 0:24: 'limitation' : while loops not available \r
+ERROR: 0:26: 'limitation' : do-while loops not available \r
+ERROR: 0:28: 'limitations' : inductive-loop init-declaration requires the form "type-specifier loop-index = constant-expression" \r
+ERROR: 0:29: 'limitations' : inductive-loop init-declaration requires the form "type-specifier loop-index = constant-expression" \r
+ERROR: 0:30: 'limitations' : inductive-loop init-declaration requires the form "type-specifier loop-index = constant-expression" \r
+ERROR: 0:31: 'limitations' : inductive-loop init-declaration requires the form "type-specifier loop-index = constant-expression" \r
+ERROR: 0:32: 'limitations' : inductive loop requires a scalar 'int' or 'float' loop index \r
+ERROR: 0:33: 'limitations' : inductive-loop condition requires the form "loop-index <comparison-op> constant-expression" \r
+ERROR: 0:34: 'limitations' : inductive-loop termination requires the form "loop-index++, loop-index--, loop-index += constant-expression, or loop-index -= constant-expression" \r
+ERROR: 0:35: 'limitations' : inductive loop index modified \r
+ERROR: 0:36: 'limitations' : inductive loop index modified \r
+ERROR: 0:43: 'limitations' : inductive loop index modified \r
+ERROR: 0:47: 'limitations' : Non-constant-index-expression \r
+ERROR: 0:49: 'limitations' : Non-constant-index-expression \r
+ERROR: 0:50: 'limitations' : Non-constant-index-expression \r
+ERROR: 0:51: 'limitations' : Non-constant-index-expression \r
+ERROR: 0:52: 'limitations' : Non-constant-index-expression \r
+ERROR: 0:53: 'limitations' : Non-constant-index-expression \r
+ERROR: 0:54: 'limitations' : Non-constant-index-expression \r
+ERROR: 0:65: 'limitations' : Non-constant-index-expression \r
+ERROR: 20 compilation errors. No code generated.\r
\r
\r
</ClCompile>\r
<ClCompile Include="glslang\MachineIndependent\InfoSink.cpp" />\r
<ClCompile Include="glslang\MachineIndependent\Initialize.cpp" />\r
+ <ClCompile Include="glslang\MachineIndependent\limits.cpp" />\r
<ClCompile Include="glslang\MachineIndependent\preprocessor\Pp.cpp" />\r
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpAtom.cpp" />\r
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpMemory.cpp" />\r
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpContext.cpp">\r
<Filter>Machine Independent\Preprocessor</Filter>\r
</ClCompile>\r
+ <ClCompile Include="glslang\MachineIndependent\limits.cpp">\r
+ <Filter>Machine Independent</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="glslang\MachineIndependent\Initialize.h">\r
};
class TIntermTraverser;
+class TIntermOperator;
class TIntermAggregate;
class TIntermUnary;
class TIntermBinary;
virtual glslang::TSourceLoc getLoc() const { return loc; }
virtual void setLoc(glslang::TSourceLoc l) { loc = l; }
virtual void traverse(glslang::TIntermTraverser*) = 0;
- virtual glslang::TIntermTyped* getAsTyped() { return 0; }
- virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return 0; }
- virtual glslang::TIntermAggregate* getAsAggregate() { return 0; }
- virtual glslang::TIntermUnary* getAsUnaryNode() { return 0; }
- virtual glslang::TIntermBinary* getAsBinaryNode() { return 0; }
- virtual glslang::TIntermSelection* getAsSelectionNode() { return 0; }
- virtual glslang::TIntermSwitch* getAsSwitchNode() { return 0; }
- virtual glslang::TIntermMethod* getAsMethodNode() { return 0; }
- virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; }
- virtual glslang::TIntermBranch* getAsBranchNode() { return 0; }
+ virtual glslang::TIntermTyped* getAsTyped() { return 0; }
+ virtual glslang::TIntermOperator* getAsOperator() { return 0; }
+ virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return 0; }
+ virtual glslang::TIntermAggregate* getAsAggregate() { return 0; }
+ virtual glslang::TIntermUnary* getAsUnaryNode() { return 0; }
+ virtual glslang::TIntermBinary* getAsBinaryNode() { return 0; }
+ virtual glslang::TIntermSelection* getAsSelectionNode() { return 0; }
+ virtual glslang::TIntermSwitch* getAsSwitchNode() { return 0; }
+ virtual glslang::TIntermMethod* getAsMethodNode() { return 0; }
+ virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; }
+ virtual glslang::TIntermBranch* getAsBranchNode() { return 0; }
virtual ~TIntermNode() { }
protected:
glslang::TSourceLoc loc;
TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), unionArray(ua) { }
const TConstUnionArray& getConstArray() const { return unionArray; }
virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
- virtual void traverse(TIntermTraverser* );
+ virtual void traverse(TIntermTraverser*);
virtual TIntermTyped* fold(TOperator, TIntermTyped*);
virtual TIntermTyped* fold(TOperator, const TType&);
protected:
//
class TIntermOperator : public TIntermTyped {
public:
+ TIntermOperator* getAsOperator() { return this; }
TOperator getOp() { return op; }
bool modifiesState() const;
bool isConstructor() const;
TConstUnionArray unionArray(aggrNode->getType().getObjectSize());
if (aggrNode->getSequence().size() == 1)
- error = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true);
+ error = parseConstTree(aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true);
else
- error = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType());
+ error = parseConstTree(aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType());
if (error)
return aggrNode;
//
// Create loop nodes.
//
-TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc loc)
+TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc loc)
{
- TIntermNode* node = new TIntermLoop(body, test, terminal, testFirst);
+ TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
node->setLoc(loc);
-
+
return node;
}
OBJECTS= Initialize.o IntermTraverse.o \
Intermediate.o ParseHelper.o PoolAlloc.o QualifierAlive.o \
RemoveTree.o ShaderLang.o intermOut.o parseConst.o SymbolTable.o \
- InfoSink.o Versions.o Constant.o Scan.o
+ InfoSink.o Versions.o Constant.o Scan.o limits.o
SRCS= gen_glslang_tab.cpp Initialize.cpp IntermTraverse.cpp \
Intermediate.cpp ParseHelper.cpp PoolAlloc.cp QualifierAlive.cpp \
InfoSink.o: ../Include/InfoSink.h
Versions.o: ParseHelper.h Versions.h ../Include/ShHandle.h SymbolTable.h localintermediate.h
Constant.o: localintermediate.h ../Include/intermediate.h ../Public/ShaderLang.h SymbolTable.h Versions.h
+limits.o: ParseHelper.h
return true;
}
+ anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing ||
+ ! limits.generalConstantMatrixVectorIndexing ||
+ ! limits.generalSamplerIndexing ||
+ ! limits.generalUniformIndexing ||
+ ! limits.generalVariableIndexing ||
+ ! limits.generalVaryingIndexing;
+
yyparse((void*)this);
+ finalize();
+
return numErrors == 0;
}
newType.getQualifier().storage = EvqConst;
newType.dereference();
result->setType(newType);
+
+ if (anyIndexLimits) {
+ // for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms
+ if ((! limits.generalSamplerIndexing && base->getBasicType() == EbtSampler) ||
+ (! limits.generalUniformIndexing && base->getQualifier().isUniform() && language != EShLangVertex) ||
+ (! limits.generalAttributeMatrixVectorIndexing && base->getQualifier().isPipeInput() && language == EShLangVertex && (base->getType().isMatrix() || base->getType().isVector())) ||
+ (! limits.generalConstantMatrixVectorIndexing && base->getAsConstantUnion()) ||
+ (! limits.generalVariableIndexing && ! base->getType().getQualifier().isUniform() &&
+ ! base->getType().getQualifier().isPipeInput() &&
+ ! base->getType().getQualifier().isPipeOutput() &&
+ base->getType().getQualifier().storage != EvqConst) ||
+ (! limits.generalVaryingIndexing && (base->getType().getQualifier().isPipeInput() ||
+ base->getType().getQualifier().isPipeOutput()))) {
+ // it's too early to know what the inductive variables are, save it for post processing
+ needsIndexLimitationChecking.push_back(index);
+ }
+ }
}
return result;
}
//
+// See if this loop satisfies the limitations for ES 2.0 (version 100) for loops in Appendex A:
+//
+// "The loop index has type int or float.
+//
+// "The for statement has the form:
+// for ( init-declaration ; condition ; expression )
+// init-declaration has the form: type-specifier identifier = constant-expression
+// condition has the form: loop-index relational_operator constant-expression
+// where relational_operator is one of: > >= < <= == or !=
+// expression [sic] has one of the following forms:
+// loop-index++
+// loop-index--
+// loop-index += constant-expression
+// loop-index -= constant-expression
+//
+// The body is handled in an AST traversal.
+//
+void TParseContext::inductiveLoopCheck(TSourceLoc loc, TIntermNode* init, TIntermLoop* loop)
+{
+ // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration
+ bool badInit = false;
+ if (! init || ! init->getAsAggregate() || ! init->getAsAggregate()->getSequence().size() == 1)
+ badInit = true;
+ TIntermBinary* binaryInit;
+ if (! badInit) {
+ // get the declaration assignment
+ binaryInit = init->getAsAggregate()->getSequence()[0]->getAsBinaryNode();
+ if (! binaryInit)
+ badInit = true;
+ }
+ if (badInit) {
+ error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
+ return;
+ }
+
+ // loop index must be type int or float
+ if (! binaryInit->getType().isScalar() || (binaryInit->getBasicType() != EbtInt && binaryInit->getBasicType() != EbtFloat)) {
+ error(loc, "inductive loop requires a scalar 'int' or 'float' loop index", "limitations", "");
+ return;
+ }
+
+ // init is the form "loop-index = constant"
+ if (binaryInit->getOp() != EOpAssign || ! binaryInit->getLeft()->getAsSymbolNode() || ! binaryInit->getRight()->getAsConstantUnion()) {
+ error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
+ return;
+ }
+
+ // get the unique id of the loop index
+ int loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId();
+ inductiveLoopIds.insert(loopIndex);
+
+ // condition's form must be "loop-index relational-operator constant-expression"
+ bool badCond = ! loop->getTest();
+ if (! badCond) {
+ TIntermBinary* binaryCond = loop->getTest()->getAsBinaryNode();
+ badCond = ! binaryCond;
+ if (! badCond) {
+ switch (binaryCond->getOp()) {
+ case EOpGreaterThan:
+ case EOpGreaterThanEqual:
+ case EOpLessThan:
+ case EOpLessThanEqual:
+ case EOpEqual:
+ case EOpNotEqual:
+ break;
+ default:
+ badCond = true;
+ }
+ }
+ if (binaryCond && (! binaryCond->getLeft()->getAsSymbolNode() ||
+ binaryCond->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
+ ! binaryCond->getRight()->getAsConstantUnion()))
+ badCond = true;
+ }
+ if (badCond) {
+ error(loc, "inductive-loop condition requires the form \"loop-index <comparison-op> constant-expression\"", "limitations", "");
+ return;
+ }
+
+ // loop-index++
+ // loop-index--
+ // loop-index += constant-expression
+ // loop-index -= constant-expression
+ bool badTerminal = ! loop->getTerminal();
+ if (! badTerminal) {
+ TIntermUnary* unaryTerminal = loop->getTerminal()->getAsUnaryNode();
+ TIntermBinary* binaryTerminal = loop->getTerminal()->getAsBinaryNode();
+ if (unaryTerminal || binaryTerminal) {
+ switch(loop->getTerminal()->getAsOperator()->getOp()) {
+ case EOpPostDecrement:
+ case EOpPostIncrement:
+ case EOpAddAssign:
+ case EOpSubAssign:
+ break;
+ default:
+ badTerminal = true;
+ }
+ } else
+ badTerminal = true;
+ if (binaryTerminal && (! binaryTerminal->getLeft()->getAsSymbolNode() ||
+ binaryTerminal->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
+ ! binaryTerminal->getRight()->getAsConstantUnion()))
+ badTerminal = true;
+ if (unaryTerminal && (! unaryTerminal->getOperand()->getAsSymbolNode() ||
+ unaryTerminal->getOperand()->getAsSymbolNode()->getId() != loopIndex))
+ badTerminal = true;
+ }
+ if (badTerminal) {
+ error(loc, "inductive-loop termination requires the form \"loop-index++, loop-index--, loop-index += constant-expression, or loop-index -= constant-expression\"", "limitations", "");
+ return;
+ }
+
+ // the body
+ inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable);
+}
+
+//
+// Do any additional error checking, etc., once we know the parsing is done.
+//
+void TParseContext::finalize()
+{
+ // Check on array indexes for ES 2.0 (version 100) limitations.
+ for (size_t i = 0; i < needsIndexLimitationChecking.size(); ++i)
+ constantIndexExpressionCheck(needsIndexLimitationChecking[i]);
+}
+
+//
// Layout qualifier stuff.
//
class TScanContext;
class TPpContext;
+typedef std::set<int> TIdSetType;
+
//
// The following are extra variables needed during parsing, grouped together so
// they can be passed to the parser without needing a global.
void nestedBlockCheck(TSourceLoc);
void nestedStructCheck(TSourceLoc);
void arrayObjectCheck(TSourceLoc, const TType&, const char* op);
+ void inductiveLoopCheck(TSourceLoc, TIntermNode* init, TIntermLoop* loop);
+ void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&);
+ void constantIndexExpressionCheck(TIntermNode*);
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
void declareArray(TSourceLoc, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration);
TIntermNode* executeInitializer(TSourceLoc, TString& identifier, TIntermTyped* initializer, TVariable* variable);
TOperator mapTypeToConstructorOp(const TType&);
+ void finalize();
public:
//
TQualifier globalInputDefaults;
TQualifier globalOutputDefaults;
TString currentCaller;
+ TIdSetType inductiveLoopIds;
+ bool anyIndexLimits;
+ TVector<TIntermTyped*> needsIndexLimitationChecking;
// TODO: desktop functionality: track use of gl_FragDepth before redeclaration
};
for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {\r
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);\r
$$ = parseContext.intermediate.makeAggregate($4, $2.loc);\r
- $$ = parseContext.intermediate.growAggregate(\r
- $$,\r
- parseContext.intermediate.addLoop($7, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), true, $1.loc),\r
- $1.loc);\r
+ TIntermLoop* forLoop = parseContext.intermediate.addLoop($7, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), true, $1.loc);\r
+ if (! parseContext.limits.nonInductiveForLoops)\r
+ parseContext.inductiveLoopCheck($1.loc, $4, forLoop);\r
+ $$ = parseContext.intermediate.growAggregate($$, forLoop, $1.loc);\r
$$->getAsAggregate()->setOperator(EOpSequence);\r
--parseContext.loopNestingLevel;\r
}\r
--- /dev/null
+//\r
+//Copyright (C) 2013 LunarG, Inc.\r
+//\r
+//All rights reserved.\r
+//\r
+//Redistribution and use in source and binary forms, with or without\r
+//modification, are permitted provided that the following conditions\r
+//are met:\r
+//\r
+// Redistributions of source code must retain the above copyright\r
+// notice, this list of conditions and the following disclaimer.\r
+//\r
+// Redistributions in binary form must reproduce the above\r
+// copyright notice, this list of conditions and the following\r
+// disclaimer in the documentation and/or other materials provided\r
+// with the distribution.\r
+//\r
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its\r
+// contributors may be used to endorse or promote products derived\r
+// from this software without specific prior written permission.\r
+//\r
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+//POSSIBILITY OF SUCH DAMAGE.\r
+//\r
+\r
+//\r
+// Do sub tree walks for\r
+// 1) inductive loop bodies to see if the inductive variable is modified\r
+// 2) array-index expressions to see if they are "constant-index-expression"\r
+//\r
+// These are per Appendix A of ES 2.0:\r
+//\r
+// "Within the body of the loop, the loop index is not statically assigned to nor is it used as the\r
+// argument to a function out or inout parameter."\r
+//\r
+// "The following are constant-index-expressions:\r
+// - Constant expressions\r
+// - Loop indices as defined in section 4\r
+// - Expressions composed of both of the above"\r
+//\r
+// N.B.: assuming the last rule excludes function calls\r
+//\r
+\r
+#include "ParseHelper.h"\r
+\r
+namespace glslang {\r
+\r
+//\r
+// The inductive loop-body traverser.\r
+//\r
+// Just look at things that might modify the loop index.\r
+//\r
+\r
+class TInductiveTraverser : public TIntermTraverser {\r
+public:\r
+ TInductiveTraverser(int id, TSymbolTable& st) : loopId(id), symbolTable(st), bad(false) { }\r
+ int loopId; // unique ID of the symbol that's the loop inductive variable\r
+ TSymbolTable& symbolTable;\r
+ bool bad;\r
+ TSourceLoc badLoc;\r
+};\r
+\r
+// check binary operations for those modifying the loop index\r
+bool InductiveBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)\r
+{\r
+ TInductiveTraverser* oit = static_cast<TInductiveTraverser*>(it);\r
+\r
+ if (node->modifiesState() && node->getLeft()->getAsSymbolNode() && \r
+ node->getLeft()->getAsSymbolNode()->getId() == oit->loopId) {\r
+ oit->bad = true;\r
+ oit->badLoc = node->getLoc();\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+// check unary operations for those modifying the loop index\r
+bool InductiveUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)\r
+{\r
+ TInductiveTraverser* oit = static_cast<TInductiveTraverser*>(it);\r
+\r
+ if (node->modifiesState() && node->getOperand()->getAsSymbolNode() && \r
+ node->getOperand()->getAsSymbolNode()->getId() == oit->loopId) {\r
+ oit->bad = true;\r
+ oit->badLoc = node->getLoc();\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+// check function calls for arguments modifying the loop index\r
+bool InductiveAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)\r
+{\r
+ TInductiveTraverser* oit = static_cast<TInductiveTraverser*>(it);\r
+\r
+ if (node->getOp() == EOpFunctionCall) {\r
+ // see if an out or inout argument is the loop index\r
+ const TIntermSequence& args = node->getSequence();\r
+ for (size_t i = 0; i < args.size(); ++i) {\r
+ if (args[i]->getAsSymbolNode() && args[i]->getAsSymbolNode()->getId() == oit->loopId) {\r
+ TSymbol* function = oit->symbolTable.find(node->getName());\r
+ const TType* type = (*function->getAsFunction())[i].type;\r
+ if (type->getQualifier().storage == EvqOut ||\r
+ type->getQualifier().storage == EvqInOut) {\r
+ oit->bad = true;\r
+ oit->badLoc = node->getLoc();\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+//\r
+// External function to call for loop check.\r
+//\r
+void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbolTable& symbolTable)\r
+{\r
+ TInductiveTraverser it(loopId, symbolTable);\r
+\r
+ if (! body)\r
+ return;\r
+\r
+ it.visitAggregate = InductiveAggregate;\r
+ it.visitBinary = InductiveBinary;\r
+ it.visitUnary = InductiveUnary;\r
+\r
+ body->traverse(&it);\r
+\r
+ if (it.bad)\r
+ error(it.badLoc, "inductive loop index modified", "limitations", "");\r
+}\r
+\r
+//\r
+// The "constant-index-expression" tranverser.\r
+//\r
+// Just look at things that can form an index. \r
+//\r
+\r
+class TIndexTraverser : public TIntermTraverser {\r
+public:\r
+ TIndexTraverser(const TIdSetType& ids) : inductiveLoopIds(ids), bad(false) { }\r
+ const TIdSetType& inductiveLoopIds;\r
+ bool bad;\r
+ TSourceLoc badLoc;\r
+};\r
+\r
+// make sure symbols are inductive-loop indexes\r
+void IndexSymbol(TIntermSymbol* symbol, TIntermTraverser* it)\r
+{\r
+ TIndexTraverser* oit = static_cast<TIndexTraverser*>(it);\r
+\r
+ if (oit->inductiveLoopIds.find(symbol->getId()) == oit->inductiveLoopIds.end()) {\r
+ oit->bad = true;\r
+ oit->badLoc = symbol->getLoc();\r
+ }\r
+}\r
+\r
+// check for function calls, assuming they are bad; spec. doesn't really say\r
+bool IndexAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)\r
+{\r
+ TIndexTraverser* oit = static_cast<TIndexTraverser*>(it);\r
+\r
+ if (node->getOp() == EOpFunctionCall) {\r
+ oit->bad = true;\r
+ oit->badLoc = node->getLoc();\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+//\r
+// External function to call for loop check.\r
+//\r
+void TParseContext::constantIndexExpressionCheck(TIntermNode* index)\r
+{\r
+ TIndexTraverser it(inductiveLoopIds);\r
+\r
+ it.visitSymbol = IndexSymbol;\r
+ it.visitAggregate = IndexAggregate;\r
+\r
+ index->traverse(&it);\r
+\r
+ if (it.bad)\r
+ error(it.badLoc, "Non-constant-index-expression", "limitations", "");\r
+}\r
+\r
+} // end namespace glslang\r
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, TSourceLoc);
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, TSourceLoc);
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
- bool parseConstTree(TSourceLoc, TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
- TIntermNode* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
+ bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
+ TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
TIntermBranch* addBranch(TOperator, TSourceLoc);
TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
public:
TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t) : unionArray(cUnion), type(t),
constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false),
- matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull;}
+ matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull; }
int index;
TConstUnionArray unionArray;
TOperator tOp;
}
}
-bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam)
+bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam)
{
if (root == 0)
return false;