Intel SPMD Program Compiler  1.12.0
parse.yy
Go to the documentation of this file.
1 /*
2  Copyright (c) 2010-2013, Intel Corporation
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8 
9  * Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11 
12  * Redistributions in binary form must reproduce the above copyright
13  notice, this list of conditions and the following disclaimer in the
14  documentation and/or other materials provided with the distribution.
15 
16  * Neither the name of Intel Corporation nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19 
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 %locations
35 
36 /* supress shift-reduces conflict message for dangling else */
37 /* one for 'if', one for 'cif' */
38 %expect 2
39 
40 %error-verbose
41 
42 %code requires {
43 
44 #define yytnamerr lYYTNameErr
45 
46 
47 #define YYLTYPE SourcePos
48 
49 # define YYLLOC_DEFAULT(Current, Rhs, N) \
50  do \
51  if (N) \
52  { \
53  (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
54  (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
55  (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
56  (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
57  (Current).name = YYRHSLOC (Rhs, 1).name ; \
58  } \
59  else \
60  { /* empty RHS */ \
61  (Current).first_line = (Current).last_line = \
62  YYRHSLOC (Rhs, 0).last_line; \
63  (Current).first_column = (Current).last_column = \
64  YYRHSLOC (Rhs, 0).last_column; \
65  (Current).name = NULL; /* new */ \
66  } \
67  while (0)
68 
69 struct ForeachDimension;
70 
71 }
72 
73 
74 %{
75 
76 #include "ispc.h"
77 #include "type.h"
78 #include "module.h"
79 #include "decl.h"
80 #include "expr.h"
81 #include "sym.h"
82 #include "stmt.h"
83 #include "util.h"
84 
85 #include <stdio.h>
86 #if ISPC_LLVM_VERSION == ISPC_LLVM_3_2
87  #include <llvm/Constants.h>
88 #else
89  #include <llvm/IR/Constants.h>
90 #endif
91 
92 #define UNIMPLEMENTED \
93  Error(yylloc, "Unimplemented parser functionality %s:%d", \
94  __FILE__, __LINE__);
95 
96 union YYSTYPE;
97 extern int yylex();
98 
99 extern char *yytext;
100 
101 void yyerror(const char *s);
102 
103 static int lYYTNameErr(char *yyres, const char *yystr);
104 
105 static void lSuggestBuiltinAlternates();
106 static void lSuggestParamListAlternates();
107 
108 static void lAddDeclaration(DeclSpecs *ds, Declarator *decl);
109 static void lAddFunctionParams(Declarator *decl);
110 static void lAddMaskToSymbolTable(SourcePos pos);
111 static void lAddThreadIndexCountToSymbolTable(SourcePos pos);
112 static std::string lGetAlternates(std::vector<std::string> &alternates);
113 static const char *lGetStorageClassString(StorageClass sc);
114 static bool lGetConstantInt(Expr *expr, int *value, SourcePos pos, const char *usage);
115 static EnumType *lCreateEnumType(const char *name, std::vector<Symbol *> *enums,
116  SourcePos pos);
117 static void lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
118  const EnumType *enumType);
119 
120 static const char *lBuiltinTokens[] = {
121  "assert", "bool", "break", "case", "cdo",
122  "cfor", "cif", "cwhile", "const", "continue", "default",
123  "do", "delete", "double", "else", "enum", "export", "extern", "false",
124  "float", "for", "foreach", "foreach_active", "foreach_tiled",
125  "foreach_unique", "goto", "if", "in", "inline",
126  "int", "int8", "int16", "int32", "int64", "launch", "new", "NULL",
127  "print", "return", "signed", "sizeof", "static", "struct", "switch",
128  "sync", "task", "true", "typedef", "uniform", "unmasked", "unsigned",
129  "varying", "void", "while", NULL
130 };
131 
132 static const char *lParamListTokens[] = {
133  "bool", "const", "double", "enum", "false", "float", "int",
134  "int8", "int16", "int32", "int64", "signed", "struct", "true",
135  "uniform", "unsigned", "varying", "void", NULL
136 };
137 
138 struct ForeachDimension {
139  ForeachDimension(Symbol *s = NULL, Expr *b = NULL, Expr *e = NULL) {
140  sym = s;
141  beginExpr = b;
142  endExpr = e;
143  }
144  Symbol *sym;
145  Expr *beginExpr, *endExpr;
146 };
147 
148 %}
149 
150 %union {
151  uint64_t intVal;
152  float floatVal;
153  double doubleVal;
154  std::string *stringVal;
155  const char *constCharPtr;
156 
157  Expr *expr;
158  ExprList *exprList;
159  const Type *type;
160  std::vector<std::pair<const Type *, SourcePos> > *typeList;
161  const AtomicType *atomicType;
162  int typeQualifier;
163  StorageClass storageClass;
164  Stmt *stmt;
165  DeclSpecs *declSpecs;
166  Declaration *declaration;
167  std::vector<Declarator *> *declarators;
168  std::vector<Declaration *> *declarationList;
169  Declarator *declarator;
170  std::vector<Declarator *> *structDeclaratorList;
171  StructDeclaration *structDeclaration;
172  std::vector<StructDeclaration *> *structDeclarationList;
173  const EnumType *enumType;
174  Symbol *symbol;
175  std::vector<Symbol *> *symbolList;
176  ForeachDimension *foreachDimension;
177  std::vector<ForeachDimension *> *foreachDimensionList;
178  std::pair<std::string, SourcePos> *declspecPair;
179  std::vector<std::pair<std::string, SourcePos> > *declspecList;
180 }
181 
182 
183 %token TOKEN_INT8_CONSTANT TOKEN_UINT8_CONSTANT
184 %token TOKEN_INT16_CONSTANT TOKEN_UINT16_CONSTANT
185 %token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT
186 %token TOKEN_INT64_CONSTANT TOKEN_UINT64_CONSTANT
187 %token TOKEN_INT32DOTDOTDOT_CONSTANT TOKEN_UINT32DOTDOTDOT_CONSTANT
188 %token TOKEN_INT64DOTDOTDOT_CONSTANT TOKEN_UINT64DOTDOTDOT_CONSTANT
189 %token TOKEN_FLOAT_CONSTANT TOKEN_DOUBLE_CONSTANT TOKEN_STRING_C_LITERAL
190 %token TOKEN_IDENTIFIER TOKEN_STRING_LITERAL TOKEN_TYPE_NAME TOKEN_NULL
191 %token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP
192 %token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP
193 %token TOKEN_AND_OP TOKEN_OR_OP TOKEN_MUL_ASSIGN TOKEN_DIV_ASSIGN TOKEN_MOD_ASSIGN
194 %token TOKEN_ADD_ASSIGN TOKEN_SUB_ASSIGN TOKEN_LEFT_ASSIGN TOKEN_RIGHT_ASSIGN
195 %token TOKEN_AND_ASSIGN TOKEN_OR_ASSIGN TOKEN_XOR_ASSIGN
196 %token TOKEN_SIZEOF TOKEN_NEW TOKEN_DELETE TOKEN_IN
197 
198 %token TOKEN_EXTERN TOKEN_EXPORT TOKEN_STATIC TOKEN_INLINE TOKEN_NOINLINE TOKEN_TASK TOKEN_DECLSPEC
199 %token TOKEN_UNIFORM TOKEN_VARYING TOKEN_TYPEDEF TOKEN_SOA TOKEN_UNMASKED
200 %token TOKEN_CHAR TOKEN_INT TOKEN_SIGNED TOKEN_UNSIGNED TOKEN_FLOAT TOKEN_DOUBLE
201 %token TOKEN_INT8 TOKEN_INT16 TOKEN_INT64 TOKEN_CONST TOKEN_VOID TOKEN_BOOL
202 %token TOKEN_ENUM TOKEN_STRUCT TOKEN_TRUE TOKEN_FALSE
203 
204 %token TOKEN_CASE TOKEN_DEFAULT TOKEN_IF TOKEN_ELSE TOKEN_SWITCH
205 %token TOKEN_WHILE TOKEN_DO TOKEN_LAUNCH TOKEN_FOREACH TOKEN_FOREACH_TILED
206 %token TOKEN_FOREACH_UNIQUE TOKEN_FOREACH_ACTIVE TOKEN_DOTDOTDOT
207 %token TOKEN_FOR TOKEN_GOTO TOKEN_CONTINUE TOKEN_BREAK TOKEN_RETURN
208 %token TOKEN_CIF TOKEN_CDO TOKEN_CFOR TOKEN_CWHILE
209 %token TOKEN_SYNC TOKEN_PRINT TOKEN_ASSERT
210 
211 %type <expr> primary_expression postfix_expression integer_dotdotdot
212 %type <expr> unary_expression cast_expression funcall_expression launch_expression
213 %type <expr> multiplicative_expression additive_expression shift_expression
214 %type <expr> relational_expression equality_expression and_expression
215 %type <expr> exclusive_or_expression inclusive_or_expression
216 %type <expr> logical_and_expression logical_or_expression new_expression
217 %type <expr> conditional_expression assignment_expression expression
218 %type <expr> initializer constant_expression for_test
219 %type <exprList> argument_expression_list initializer_list
220 
221 %type <stmt> statement labeled_statement compound_statement for_init_statement
222 %type <stmt> expression_statement selection_statement iteration_statement
223 %type <stmt> jump_statement statement_list declaration_statement print_statement
224 %type <stmt> assert_statement sync_statement delete_statement unmasked_statement
225 
226 %type <declaration> declaration parameter_declaration
227 %type <declarators> init_declarator_list
228 %type <declarationList> parameter_list parameter_type_list
229 %type <declarator> declarator pointer reference
230 %type <declarator> init_declarator direct_declarator struct_declarator
231 %type <declarator> abstract_declarator direct_abstract_declarator
232 
233 %type <structDeclaratorList> struct_declarator_list
234 %type <structDeclaration> struct_declaration
235 %type <structDeclarationList> struct_declaration_list
236 
237 %type <symbolList> enumerator_list
238 %type <symbol> enumerator foreach_identifier foreach_active_identifier
239 %type <enumType> enum_specifier
240 
241 %type <type> specifier_qualifier_list struct_or_union_specifier
242 %type <type> struct_or_union_and_name
243 %type <type> type_specifier type_name rate_qualified_type_specifier
244 %type <type> short_vec_specifier
245 %type <typeList> type_specifier_list
246 %type <atomicType> atomic_var_type_specifier
247 
248 %type <typeQualifier> type_qualifier type_qualifier_list
249 %type <storageClass> storage_class_specifier
250 %type <declSpecs> declaration_specifiers
251 
252 %type <stringVal> string_constant
253 %type <constCharPtr> struct_or_union_name enum_identifier goto_identifier
254 %type <constCharPtr> foreach_unique_identifier
255 
256 %type <intVal> int_constant soa_width_specifier rate_qualified_new
257 
258 %type <foreachDimension> foreach_dimension_specifier
259 %type <foreachDimensionList> foreach_dimension_list
260 
261 %type <declspecPair> declspec_item
262 %type <declspecList> declspec_specifier declspec_list
263 
264 %start translation_unit
265 %%
266 
267 string_constant
268  : TOKEN_STRING_LITERAL { $$ = new std::string(*yylval.stringVal); }
269  | string_constant TOKEN_STRING_LITERAL
270  {
271  std::string s = *((std::string *)$1);
272  s += *yylval.stringVal;
273  $$ = new std::string(s);
274  }
275  ;
276 
277 primary_expression
278  : TOKEN_IDENTIFIER {
279  const char *name = yylval.stringVal->c_str();
280  Symbol *s = m->symbolTable->LookupVariable(name);
281  $$ = NULL;
282  if (s)
283  $$ = new SymbolExpr(s, @1);
284  else {
285  std::vector<Symbol *> funs;
286  m->symbolTable->LookupFunction(name, &funs);
287  if (funs.size() > 0)
288  $$ = new FunctionSymbolExpr(name, funs, @1);
289  }
290  if ($$ == NULL) {
291  std::vector<std::string> alternates =
292  m->symbolTable->ClosestVariableOrFunctionMatch(name);
293  std::string alts = lGetAlternates(alternates);
294  Error(@1, "Undeclared symbol \"%s\".%s", name, alts.c_str());
295  }
296  }
297  | TOKEN_INT8_CONSTANT {
298  $$ = new ConstExpr(AtomicType::UniformInt8->GetAsConstType(),
299  (int8_t)yylval.intVal, @1);
300  }
301  | TOKEN_UINT8_CONSTANT {
302  $$ = new ConstExpr(AtomicType::UniformUInt8->GetAsConstType(),
303  (uint8_t)yylval.intVal, @1);
304  }
305  | TOKEN_INT16_CONSTANT {
306  $$ = new ConstExpr(AtomicType::UniformInt16->GetAsConstType(),
307  (int16_t)yylval.intVal, @1);
308  }
309  | TOKEN_UINT16_CONSTANT {
310  $$ = new ConstExpr(AtomicType::UniformUInt16->GetAsConstType(),
311  (uint16_t)yylval.intVal, @1);
312  }
313  | TOKEN_INT32_CONSTANT {
314  $$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
315  (int32_t)yylval.intVal, @1);
316  }
317  | TOKEN_UINT32_CONSTANT {
318  $$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
319  (uint32_t)yylval.intVal, @1);
320  }
321  | TOKEN_INT64_CONSTANT {
322  $$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
323  (int64_t)yylval.intVal, @1);
324  }
325  | TOKEN_UINT64_CONSTANT {
326  $$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
327  (uint64_t)yylval.intVal, @1);
328  }
329  | TOKEN_FLOAT_CONSTANT {
330  $$ = new ConstExpr(AtomicType::UniformFloat->GetAsConstType(),
331  yylval.floatVal, @1);
332  }
333  | TOKEN_DOUBLE_CONSTANT {
334  $$ = new ConstExpr(AtomicType::UniformDouble->GetAsConstType(),
335  yylval.doubleVal, @1);
336  }
337  | TOKEN_TRUE {
338  $$ = new ConstExpr(AtomicType::UniformBool->GetAsConstType(), true, @1);
339  }
340  | TOKEN_FALSE {
341  $$ = new ConstExpr(AtomicType::UniformBool->GetAsConstType(), false, @1);
342  }
343  | TOKEN_NULL {
344  $$ = new NullPointerExpr(@1);
345  }
346 /* | TOKEN_STRING_LITERAL
347  { UNIMPLEMENTED }*/
348  | '(' expression ')' { $$ = $2; }
349  | '(' error ')' { $$ = NULL; }
350  ;
351 
352 launch_expression
353  : TOKEN_LAUNCH postfix_expression '(' argument_expression_list ')'
354  {
355  ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @2);
356  Expr *launchCount[3] = {oneExpr, oneExpr, oneExpr};
357  $$ = new FunctionCallExpr($2, $4, Union(@2, @5), true, launchCount);
358  }
359  | TOKEN_LAUNCH postfix_expression '(' ')'
360  {
361  ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @2);
362  Expr *launchCount[3] = {oneExpr, oneExpr, oneExpr};
363  $$ = new FunctionCallExpr($2, new ExprList(Union(@3,@4)), Union(@2, @4), true, launchCount);
364  }
365 
366  | TOKEN_LAUNCH '[' assignment_expression ']' postfix_expression '(' argument_expression_list ')'
367  {
368  ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @5);
369  Expr *launchCount[3] = {$3, oneExpr, oneExpr};
370  $$ = new FunctionCallExpr($5, $7, Union(@5,@8), true, launchCount);
371  }
372  | TOKEN_LAUNCH '[' assignment_expression ']' postfix_expression '(' ')'
373  {
374  ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @5);
375  Expr *launchCount[3] = {$3, oneExpr, oneExpr};
376  $$ = new FunctionCallExpr($5, new ExprList(Union(@5,@6)), Union(@5,@7), true, launchCount);
377  }
378 
379  | TOKEN_LAUNCH '[' assignment_expression ',' assignment_expression ']' postfix_expression '(' argument_expression_list ')'
380  {
381  ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @7);
382  Expr *launchCount[3] = {$3, $5, oneExpr};
383  $$ = new FunctionCallExpr($7, $9, Union(@7,@10), true, launchCount);
384  }
385  | TOKEN_LAUNCH '[' assignment_expression ',' assignment_expression ']' postfix_expression '(' ')'
386  {
387  ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @7);
388  Expr *launchCount[3] = {$3, $5, oneExpr};
389  $$ = new FunctionCallExpr($7, new ExprList(Union(@7,@8)), Union(@7,@9), true, launchCount);
390  }
391  | TOKEN_LAUNCH '[' assignment_expression ']' '[' assignment_expression ']' postfix_expression '(' argument_expression_list ')'
392  {
393  ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @8);
394  Expr *launchCount[3] = {$6, $3, oneExpr};
395  $$ = new FunctionCallExpr($8, $10, Union(@8,@11), true, launchCount);
396  }
397  | TOKEN_LAUNCH '[' assignment_expression ']' '[' assignment_expression ']' postfix_expression '(' ')'
398  {
399  ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @8);
400  Expr *launchCount[3] = {$6, $3, oneExpr};
401  $$ = new FunctionCallExpr($8, new ExprList(Union(@8,@9)), Union(@8,@10), true, launchCount);
402  }
403 
404  | TOKEN_LAUNCH '[' assignment_expression ',' assignment_expression ',' assignment_expression ']' postfix_expression '(' argument_expression_list ')'
405  {
406  Expr *launchCount[3] = {$3, $5, $7};
407  $$ = new FunctionCallExpr($9, $11, Union(@9,@12), true, launchCount);
408  }
409  | TOKEN_LAUNCH '[' assignment_expression ',' assignment_expression ',' assignment_expression ']' postfix_expression '(' ')'
410  {
411  Expr *launchCount[3] = {$3, $5, $7};
412  $$ = new FunctionCallExpr($9, new ExprList(Union(@9,@10)), Union(@9,@11), true, launchCount);
413  }
414  | TOKEN_LAUNCH '[' assignment_expression ']' '[' assignment_expression ']' '[' assignment_expression ']' postfix_expression '(' argument_expression_list ')'
415  {
416  Expr *launchCount[3] = {$9, $6, $3};
417  $$ = new FunctionCallExpr($11, $13, Union(@11,@14), true, launchCount);
418  }
419  | TOKEN_LAUNCH '[' assignment_expression ']' '[' assignment_expression ']' '[' assignment_expression ']' postfix_expression '(' ')'
420  {
421  Expr *launchCount[3] = {$9, $6, $3};
422  $$ = new FunctionCallExpr($11, new ExprList(Union(@11,@12)), Union(@11,@13), true, launchCount);
423  }
424 
425 
426  | TOKEN_LAUNCH '<' postfix_expression '(' argument_expression_list ')' '>'
427  {
428  Error(Union(@2, @7), "\"launch\" expressions no longer take '<' '>' "
429  "around function call expression.");
430  $$ = NULL;
431  }
432  | TOKEN_LAUNCH '<' postfix_expression '(' ')' '>'
433  {
434  Error(Union(@2, @6), "\"launch\" expressions no longer take '<' '>' "
435  "around function call expression.");
436  $$ = NULL;
437  }
438  | TOKEN_LAUNCH '[' assignment_expression ']' '<' postfix_expression '(' argument_expression_list ')' '>'
439  {
440  Error(Union(@5, @10), "\"launch\" expressions no longer take '<' '>' "
441  "around function call expression.");
442  $$ = NULL;
443  }
444  | TOKEN_LAUNCH '[' assignment_expression ']' '<' postfix_expression '(' ')' '>'
445  {
446  Error(Union(@5, @9), "\"launch\" expressions no longer take '<' '>' "
447  "around function call expression.");
448  $$ = NULL;
449  }
450  ;
451 
452 postfix_expression
453  : primary_expression
454  | postfix_expression '[' expression ']'
455  { $$ = new IndexExpr($1, $3, Union(@1,@4)); }
456  | postfix_expression '[' error ']'
457  { $$ = NULL; }
458  | launch_expression
459  | postfix_expression '.' TOKEN_IDENTIFIER
460  { $$ = MemberExpr::create($1, yytext, Union(@1,@3), @3, false); }
461  | postfix_expression TOKEN_PTR_OP TOKEN_IDENTIFIER
462  { $$ = MemberExpr::create($1, yytext, Union(@1,@3), @3, true); }
463  | postfix_expression TOKEN_INC_OP
464  { $$ = new UnaryExpr(UnaryExpr::PostInc, $1, Union(@1,@2)); }
465  | postfix_expression TOKEN_DEC_OP
466  { $$ = new UnaryExpr(UnaryExpr::PostDec, $1, Union(@1,@2)); }
467  ;
468 
469 funcall_expression
470  : postfix_expression
471  | postfix_expression '(' ')'
472  { $$ = new FunctionCallExpr($1, new ExprList(Union(@1,@2)), Union(@1,@3)); }
473  | postfix_expression '(' argument_expression_list ')'
474  { $$ = new FunctionCallExpr($1, $3, Union(@1,@4)); }
475  | postfix_expression '(' error ')'
476  { $$ = NULL; }
477  ;
478 
479 argument_expression_list
480  : assignment_expression { $$ = new ExprList($1, @1); }
481  | argument_expression_list ',' assignment_expression
482  {
483  ExprList *argList = llvm::dyn_cast<ExprList>($1);
484  if (argList == NULL) {
485  AssertPos(@1, m->errorCount > 0);
486  argList = new ExprList(@3);
487  }
488  argList->exprs.push_back($3);
489  argList->pos = Union(argList->pos, @3);
490  $$ = argList;
491  }
492  ;
493 
494 unary_expression
495  : funcall_expression
496  | TOKEN_INC_OP unary_expression
497  { $$ = new UnaryExpr(UnaryExpr::PreInc, $2, Union(@1, @2)); }
498  | TOKEN_DEC_OP unary_expression
499  { $$ = new UnaryExpr(UnaryExpr::PreDec, $2, Union(@1, @2)); }
500  | '&' unary_expression
501  { $$ = new AddressOfExpr($2, Union(@1, @2)); }
502  | '*' unary_expression
503  { $$ = new PtrDerefExpr($2, Union(@1, @2)); }
504  | '+' cast_expression
505  { $$ = $2; }
506  | '-' cast_expression
507  { $$ = new UnaryExpr(UnaryExpr::Negate, $2, Union(@1, @2)); }
508  | '~' cast_expression
509  { $$ = new UnaryExpr(UnaryExpr::BitNot, $2, Union(@1, @2)); }
510  | '!' cast_expression
511  { $$ = new UnaryExpr(UnaryExpr::LogicalNot, $2, Union(@1, @2)); }
512  | TOKEN_SIZEOF unary_expression
513  { $$ = new SizeOfExpr($2, Union(@1, @2)); }
514  | TOKEN_SIZEOF '(' type_name ')'
515  { $$ = new SizeOfExpr($3, Union(@1, @4)); }
516  ;
517 
518 cast_expression
519  : unary_expression
520  | '(' type_name ')' cast_expression
521  {
522  $$ = new TypeCastExpr($2, $4, Union(@1,@4));
523  }
524  ;
525 
526 multiplicative_expression
527  : cast_expression
528  | multiplicative_expression '*' cast_expression
529  { $$ = MakeBinaryExpr(BinaryExpr::Mul, $1, $3, Union(@1, @3)); }
530  | multiplicative_expression '/' cast_expression
531  { $$ = MakeBinaryExpr(BinaryExpr::Div, $1, $3, Union(@1, @3)); }
532  | multiplicative_expression '%' cast_expression
533  { $$ = MakeBinaryExpr(BinaryExpr::Mod, $1, $3, Union(@1, @3)); }
534  ;
535 
536 additive_expression
537  : multiplicative_expression
538  | additive_expression '+' multiplicative_expression
539  { $$ = MakeBinaryExpr(BinaryExpr::Add, $1, $3, Union(@1, @3)); }
540  | additive_expression '-' multiplicative_expression
541  { $$ = MakeBinaryExpr(BinaryExpr::Sub, $1, $3, Union(@1, @3)); }
542  ;
543 
544 shift_expression
545  : additive_expression
546  | shift_expression TOKEN_LEFT_OP additive_expression
547  { $$ = MakeBinaryExpr(BinaryExpr::Shl, $1, $3, Union(@1, @3)); }
548  | shift_expression TOKEN_RIGHT_OP additive_expression
549  { $$ = MakeBinaryExpr(BinaryExpr::Shr, $1, $3, Union(@1, @3)); }
550  ;
551 
552 relational_expression
553  : shift_expression
554  | relational_expression '<' shift_expression
555  { $$ = new BinaryExpr(BinaryExpr::Lt, $1, $3, Union(@1, @3)); }
556  | relational_expression '>' shift_expression
557  { $$ = new BinaryExpr(BinaryExpr::Gt, $1, $3, Union(@1, @3)); }
558  | relational_expression TOKEN_LE_OP shift_expression
559  { $$ = new BinaryExpr(BinaryExpr::Le, $1, $3, Union(@1, @3)); }
560  | relational_expression TOKEN_GE_OP shift_expression
561  { $$ = new BinaryExpr(BinaryExpr::Ge, $1, $3, Union(@1, @3)); }
562  ;
563 
564 equality_expression
565  : relational_expression
566  | equality_expression TOKEN_EQ_OP relational_expression
567  { $$ = new BinaryExpr(BinaryExpr::Equal, $1, $3, Union(@1,@3)); }
568  | equality_expression TOKEN_NE_OP relational_expression
569  { $$ = new BinaryExpr(BinaryExpr::NotEqual, $1, $3, Union(@1,@3)); }
570  ;
571 
572 and_expression
573  : equality_expression
574  | and_expression '&' equality_expression
575  { $$ = new BinaryExpr(BinaryExpr::BitAnd, $1, $3, Union(@1, @3)); }
576  ;
577 
578 exclusive_or_expression
579  : and_expression
580  | exclusive_or_expression '^' and_expression
581  { $$ = new BinaryExpr(BinaryExpr::BitXor, $1, $3, Union(@1, @3)); }
582  ;
583 
584 inclusive_or_expression
585  : exclusive_or_expression
586  | inclusive_or_expression '|' exclusive_or_expression
587  { $$ = new BinaryExpr(BinaryExpr::BitOr, $1, $3, Union(@1, @3)); }
588  ;
589 
590 logical_and_expression
591  : inclusive_or_expression
592  | logical_and_expression TOKEN_AND_OP inclusive_or_expression
593  { $$ = new BinaryExpr(BinaryExpr::LogicalAnd, $1, $3, Union(@1, @3)); }
594  ;
595 
596 logical_or_expression
597  : logical_and_expression
598  | logical_or_expression TOKEN_OR_OP logical_and_expression
599  { $$ = new BinaryExpr(BinaryExpr::LogicalOr, $1, $3, Union(@1, @3)); }
600  ;
601 
602 conditional_expression
603  : logical_or_expression
604  | logical_or_expression '?' expression ':' conditional_expression
605  { $$ = new SelectExpr($1, $3, $5, Union(@1,@5)); }
606  ;
607 
608 rate_qualified_new
609  : TOKEN_NEW { $$ = 0; }
610  | TOKEN_UNIFORM TOKEN_NEW { $$ = TYPEQUAL_UNIFORM; }
611  | TOKEN_VARYING TOKEN_NEW { $$ = TYPEQUAL_VARYING; }
612  ;
613 
614 rate_qualified_type_specifier
615  : type_specifier { $$ = $1; }
616  | TOKEN_UNIFORM type_specifier
617  {
618  if ($2 == NULL)
619  $$ = NULL;
620  else if ($2->IsVoidType()) {
621  Error(@1, "\"uniform\" qualifier is illegal with \"void\" type.");
622  $$ = NULL;
623  }
624  else
625  $$ = $2->GetAsUniformType();
626  }
627  | TOKEN_VARYING type_specifier
628  {
629  if ($2 == NULL)
630  $$ = NULL;
631  else if ($2->IsVoidType()) {
632  Error(@1, "\"varying\" qualifier is illegal with \"void\" type.");
633  $$ = NULL;
634  }
635  else
636  $$ = $2->GetAsVaryingType();
637  }
638  | soa_width_specifier type_specifier
639  {
640  if ($2 == NULL)
641  $$ = NULL;
642  else {
643  int soaWidth = (int)$1;
644  const StructType *st = CastType<StructType>($2);
645  if (st == NULL) {
646  Error(@1, "\"soa\" qualifier is illegal with non-struct type \"%s\".",
647  $2->GetString().c_str());
648  $$ = NULL;
649  }
650  else if (soaWidth <= 0 || (soaWidth & (soaWidth - 1)) != 0) {
651  Error(@1, "soa<%d> width illegal. Value must be positive power "
652  "of two.", soaWidth);
653  $$ = NULL;
654  }
655  else
656  $$ = st->GetAsSOAType(soaWidth);
657  }
658  }
659  ;
660 
661 new_expression
662  : conditional_expression
663  | rate_qualified_new rate_qualified_type_specifier
664  {
665  $$ = new NewExpr((int32_t)$1, $2, NULL, NULL, @1, Union(@1, @2));
666  }
667  | rate_qualified_new rate_qualified_type_specifier '(' initializer_list ')'
668  {
669  $$ = new NewExpr((int32_t)$1, $2, $4, NULL, @1, Union(@1, @2));
670  }
671  | rate_qualified_new rate_qualified_type_specifier '[' expression ']'
672  {
673  $$ = new NewExpr((int32_t)$1, $2, NULL, $4, @1, Union(@1, @4));
674  }
675  ;
676 
677 assignment_expression
678  : new_expression
679  | unary_expression '=' assignment_expression
680  { $$ = new AssignExpr(AssignExpr::Assign, $1, $3, Union(@1, @3)); }
681  | unary_expression TOKEN_MUL_ASSIGN assignment_expression
682  { $$ = new AssignExpr(AssignExpr::MulAssign, $1, $3, Union(@1, @3)); }
683  | unary_expression TOKEN_DIV_ASSIGN assignment_expression
684  { $$ = new AssignExpr(AssignExpr::DivAssign, $1, $3, Union(@1, @3)); }
685  | unary_expression TOKEN_MOD_ASSIGN assignment_expression
686  { $$ = new AssignExpr(AssignExpr::ModAssign, $1, $3, Union(@1, @3)); }
687  | unary_expression TOKEN_ADD_ASSIGN assignment_expression
688  { $$ = new AssignExpr(AssignExpr::AddAssign, $1, $3, Union(@1, @3)); }
689  | unary_expression TOKEN_SUB_ASSIGN assignment_expression
690  { $$ = new AssignExpr(AssignExpr::SubAssign, $1, $3, Union(@1, @3)); }
691  | unary_expression TOKEN_LEFT_ASSIGN assignment_expression
692  { $$ = new AssignExpr(AssignExpr::ShlAssign, $1, $3, Union(@1, @3)); }
693  | unary_expression TOKEN_RIGHT_ASSIGN assignment_expression
694  { $$ = new AssignExpr(AssignExpr::ShrAssign, $1, $3, Union(@1, @3)); }
695  | unary_expression TOKEN_AND_ASSIGN assignment_expression
696  { $$ = new AssignExpr(AssignExpr::AndAssign, $1, $3, Union(@1, @3)); }
697  | unary_expression TOKEN_XOR_ASSIGN assignment_expression
698  { $$ = new AssignExpr(AssignExpr::XorAssign, $1, $3, Union(@1, @3)); }
699  | unary_expression TOKEN_OR_ASSIGN assignment_expression
700  { $$ = new AssignExpr(AssignExpr::OrAssign, $1, $3, Union(@1, @3)); }
701  ;
702 
703 expression
704  : assignment_expression
705  | expression ',' assignment_expression
706  { $$ = new BinaryExpr(BinaryExpr::Comma, $1, $3, Union(@1, @3)); }
707  ;
708 
709 constant_expression
710  : conditional_expression
711  ;
712 
713 declaration_statement
714  : declaration
715  {
716  if ($1 == NULL) {
717  AssertPos(@1, m->errorCount > 0);
718  $$ = NULL;
719  }
720  else if ($1->declSpecs->storageClass == SC_TYPEDEF) {
721  for (unsigned int i = 0; i < $1->declarators.size(); ++i) {
722  if ($1->declarators[i] == NULL)
723  AssertPos(@1, m->errorCount > 0);
724  else
725  m->AddTypeDef($1->declarators[i]->name,
726  $1->declarators[i]->type,
727  $1->declarators[i]->pos);
728  }
729  $$ = NULL;
730  }
731  else {
732  $1->DeclareFunctions();
733  std::vector<VariableDeclaration> vars = $1->GetVariableDeclarations();
734  $$ = new DeclStmt(vars, @1);
735  }
736  }
737  ;
738 
739 declaration
740  : declaration_specifiers ';'
741  {
742  $$ = new Declaration($1);
743  }
744  | declaration_specifiers init_declarator_list ';'
745  {
746  $$ = new Declaration($1, $2);
747  }
748  ;
749 
750 soa_width_specifier
751  : TOKEN_SOA '<' int_constant '>'
752  { $$ = $3; }
753  ;
754 
755 declspec_item
756  : TOKEN_IDENTIFIER
757  {
758  std::pair<std::string, SourcePos> *p = new std::pair<std::string, SourcePos>;
759  p->first = *(yylval.stringVal);
760  p->second = @1;
761  $$ = p;
762  }
763  ;
764 
765 declspec_list
766  : declspec_item
767  {
768  $$ = new std::vector<std::pair<std::string, SourcePos> >;
769  $$->push_back(*$1);
770  }
771  | declspec_list ',' declspec_item
772  {
773  if ($1 != NULL)
774  $1->push_back(*$3);
775  $$ = $1;
776  }
777  ;
778 
779 declspec_specifier
780  : TOKEN_DECLSPEC '(' declspec_list ')'
781  {
782  $$ = $3;
783  }
784  ;
785 
786 declaration_specifiers
787  : storage_class_specifier
788  {
789  $$ = new DeclSpecs(NULL, $1);
790  }
791  | storage_class_specifier declaration_specifiers
792  {
793  DeclSpecs *ds = (DeclSpecs *)$2;
794  if (ds != NULL) {
795  if (ds->storageClass != SC_NONE)
796  Error(@1, "Multiple storage class specifiers in a declaration are illegal. "
797  "(Have provided both \"%s\" and \"%s\".)",
798  lGetStorageClassString(ds->storageClass),
799  lGetStorageClassString($1));
800  else
801  ds->storageClass = $1;
802  }
803  $$ = ds;
804  }
805  | declspec_specifier
806  {
807  $$ = new DeclSpecs;
808  if ($1 != NULL)
809  $$->declSpecList = *$1;
810  }
811  | declspec_specifier declaration_specifiers
812  {
813  DeclSpecs *ds = (DeclSpecs *)$2;
814  std::vector<std::pair<std::string, SourcePos> > *declSpecList = $1;
815  if (ds != NULL && declSpecList != NULL) {
816  for (int i = 0; i < (int)declSpecList->size(); ++i)
817  ds->declSpecList.push_back((*declSpecList)[i]);
818  }
819  $$ = ds;
820  }
821  | soa_width_specifier
822  {
823  DeclSpecs *ds = new DeclSpecs;
824  ds->soaWidth = (int32_t)$1;
825  $$ = ds;
826  }
827  | soa_width_specifier declaration_specifiers
828  {
829  DeclSpecs *ds = (DeclSpecs *)$2;
830  if (ds != NULL) {
831  if (ds->soaWidth != 0)
832  Error(@1, "soa<> qualifier supplied multiple times in declaration.");
833  else
834  ds->soaWidth = (int32_t)$1;
835  }
836  $$ = ds;
837  }
838  | type_specifier
839  {
840  $$ = new DeclSpecs($1);
841  }
842  | type_specifier '<' int_constant '>'
843  {
844  DeclSpecs *ds = new DeclSpecs($1);
845  ds->vectorSize = (int32_t)$3;
846  $$ = ds;
847  }
848  | type_specifier declaration_specifiers
849  {
850  DeclSpecs *ds = (DeclSpecs *)$2;
851  if (ds != NULL) {
852  if (ds->baseType != NULL)
853  Error(@1, "Multiple types provided for declaration.");
854  ds->baseType = $1;
855  }
856  $$ = ds;
857  }
858  | type_qualifier
859  {
860  $$ = new DeclSpecs(NULL, SC_NONE, $1);
861  }
862  | type_qualifier declaration_specifiers
863  {
864  DeclSpecs *ds = (DeclSpecs *)$2;
865  if (ds != NULL)
866  ds->typeQualifiers |= $1;
867  $$ = ds;
868  }
869  ;
870 
871 init_declarator_list
872  : init_declarator
873  {
874  std::vector<Declarator *> *dl = new std::vector<Declarator *>;
875  if ($1 != NULL)
876  dl->push_back($1);
877  $$ = dl;
878  }
879  | init_declarator_list ',' init_declarator
880  {
881  std::vector<Declarator *> *dl = (std::vector<Declarator *> *)$1;
882  if (dl == NULL) {
883  AssertPos(@1, m->errorCount > 0);
884  dl = new std::vector<Declarator *>;
885  }
886  if ($3 != NULL)
887  dl->push_back($3);
888  $$ = dl;
889  }
890  ;
891 
892 init_declarator
893  : declarator
894  | declarator '=' initializer
895  {
896  if ($1 != NULL)
897  $1->initExpr = $3;
898  $$ = $1;
899  }
900  ;
901 
902 storage_class_specifier
903  : TOKEN_TYPEDEF { $$ = SC_TYPEDEF; }
904  | TOKEN_EXTERN { $$ = SC_EXTERN; }
905  | TOKEN_EXTERN TOKEN_STRING_C_LITERAL { $$ = SC_EXTERN_C; }
906  | TOKEN_STATIC { $$ = SC_STATIC; }
907  ;
908 
909 type_specifier
910  : atomic_var_type_specifier { $$ = $1; }
911  | TOKEN_TYPE_NAME
912  {
913  const Type *t = m->symbolTable->LookupType(yytext);
914  $$ = t;
915  }
916  | struct_or_union_specifier { $$ = $1; }
917  | enum_specifier { $$ = $1; }
918  ;
919 
920 type_specifier_list
921  : type_specifier
922  {
923  if ($1 == NULL)
924  $$ = NULL;
925  else {
926  std::vector<std::pair<const Type *, SourcePos> > *vec =
927  new std::vector<std::pair<const Type *, SourcePos> >;
928  vec->push_back(std::make_pair($1, @1));
929  $$ = vec;
930  }
931  }
932  | type_specifier_list ',' type_specifier
933  {
934  $$ = $1;
935  if ($1 == NULL)
936  Assert(m->errorCount > 0);
937  else
938  $$->push_back(std::make_pair($3, @3));
939  }
940  ;
941 
942 atomic_var_type_specifier
943  : TOKEN_VOID { $$ = AtomicType::Void; }
944  | TOKEN_BOOL { $$ = AtomicType::UniformBool->GetAsUnboundVariabilityType(); }
945  | TOKEN_INT8 { $$ = AtomicType::UniformInt8->GetAsUnboundVariabilityType(); }
946  | TOKEN_INT16 { $$ = AtomicType::UniformInt16->GetAsUnboundVariabilityType(); }
947  | TOKEN_INT { $$ = AtomicType::UniformInt32->GetAsUnboundVariabilityType(); }
948  | TOKEN_FLOAT { $$ = AtomicType::UniformFloat->GetAsUnboundVariabilityType(); }
949  | TOKEN_DOUBLE { $$ = AtomicType::UniformDouble->GetAsUnboundVariabilityType(); }
950  | TOKEN_INT64 { $$ = AtomicType::UniformInt64->GetAsUnboundVariabilityType(); }
951  ;
952 
953 short_vec_specifier
954  : atomic_var_type_specifier '<' int_constant '>'
955  {
956  $$ = $1 ? new VectorType($1, (int32_t)$3) : NULL;
957  }
958  ;
959 
960 struct_or_union_name
961  : TOKEN_IDENTIFIER { $$ = strdup(yytext); }
962  | TOKEN_TYPE_NAME { $$ = strdup(yytext); }
963  ;
964 
965 struct_or_union_and_name
966  : struct_or_union struct_or_union_name
967  {
968  const Type *st = m->symbolTable->LookupType($2);
969  if (st == NULL) {
970  st = new UndefinedStructType($2, Variability::Unbound, false, @2);
971  m->symbolTable->AddType($2, st, @2);
972  $$ = st;
973  }
974  else {
975  if (CastType<StructType>(st) == NULL &&
976  CastType<UndefinedStructType>(st) == NULL) {
977  Error(@2, "Type \"%s\" is not a struct type! (%s)", $2,
978  st->GetString().c_str());
979  $$ = NULL;
980  }
981  else
982  $$ = st;
983  }
984  }
985  ;
986 
987 struct_or_union_specifier
988  : struct_or_union_and_name
989  | struct_or_union_and_name '{' struct_declaration_list '}'
990  {
991  if ($3 != NULL) {
992  llvm::SmallVector<const Type *, 8> elementTypes;
993  llvm::SmallVector<std::string, 8> elementNames;
994  llvm::SmallVector<SourcePos, 8> elementPositions;
995  GetStructTypesNamesPositions(*$3, &elementTypes, &elementNames,
996  &elementPositions);
997  const std::string &name = CastType<StructType>($1) ?
998  CastType<StructType>($1)->GetStructName() :
999  CastType<UndefinedStructType>($1)->GetStructName();
1000  StructType *st = new StructType(name, elementTypes, elementNames,
1001  elementPositions, false, Variability::Unbound, @1);
1002  m->symbolTable->AddType(name.c_str(), st, @1);
1003  $$ = st;
1004  }
1005  else
1006  $$ = NULL;
1007  }
1008  | struct_or_union '{' struct_declaration_list '}'
1009  {
1010  if ($3 != NULL) {
1011  llvm::SmallVector<const Type *, 8> elementTypes;
1012  llvm::SmallVector<std::string, 8> elementNames;
1013  llvm::SmallVector<SourcePos, 8> elementPositions;
1014  GetStructTypesNamesPositions(*$3, &elementTypes, &elementNames,
1015  &elementPositions);
1016  $$ = new StructType("", elementTypes, elementNames, elementPositions,
1017  false, Variability::Unbound, @1);
1018  }
1019  else
1020  $$ = NULL;
1021  }
1022  | struct_or_union '{' '}'
1023  {
1024  llvm::SmallVector<const Type *, 8> elementTypes;
1025  llvm::SmallVector<std::string, 8> elementNames;
1026  llvm::SmallVector<SourcePos, 8> elementPositions;
1027  $$ = new StructType("", elementTypes, elementNames, elementPositions,
1028  false, Variability::Unbound, @1);
1029  }
1030  | struct_or_union_and_name '{' '}'
1031  {
1032  llvm::SmallVector<const Type *, 8> elementTypes;
1033  llvm::SmallVector<std::string, 8> elementNames;
1034  llvm::SmallVector<SourcePos, 8> elementPositions;
1035  const std::string &name = CastType<StructType>($1) ?
1036  CastType<StructType>($1)->GetStructName() :
1037  CastType<UndefinedStructType>($1)->GetStructName();
1038  StructType *st = new StructType(name, elementTypes,
1039  elementNames, elementPositions,
1040  false, Variability::Unbound, @1);
1041  m->symbolTable->AddType(name.c_str(), st, @2);
1042  $$ = st;
1043  }
1044  ;
1045 
1046 struct_or_union
1047  : TOKEN_STRUCT
1048  ;
1049 
1050 struct_declaration_list
1051  : struct_declaration
1052  {
1053  std::vector<StructDeclaration *> *sdl = new std::vector<StructDeclaration *>;
1054  if ($1 != NULL)
1055  sdl->push_back($1);
1056  $$ = sdl;
1057  }
1058  | struct_declaration_list struct_declaration
1059  {
1060  std::vector<StructDeclaration *> *sdl = (std::vector<StructDeclaration *> *)$1;
1061  if (sdl == NULL) {
1062  AssertPos(@1, m->errorCount > 0);
1063  sdl = new std::vector<StructDeclaration *>;
1064  }
1065  if ($2 != NULL)
1066  sdl->push_back($2);
1067  $$ = sdl;
1068  }
1069  ;
1070 
1071 struct_declaration
1072  : specifier_qualifier_list struct_declarator_list ';'
1073  { $$ = ($1 != NULL && $2 != NULL) ? new StructDeclaration($1, $2) : NULL; }
1074  ;
1075 
1076 specifier_qualifier_list
1077  : type_specifier specifier_qualifier_list
1078  | type_specifier
1079  | short_vec_specifier
1080  | type_qualifier specifier_qualifier_list
1081  {
1082  if ($2 != NULL) {
1083  if ($1 == TYPEQUAL_UNIFORM) {
1084  if ($2->IsVoidType()) {
1085  Error(@1, "\"uniform\" qualifier is illegal with \"void\" type.");
1086  $$ = NULL;
1087  }
1088  else
1089  $$ = $2->GetAsUniformType();
1090  }
1091  else if ($1 == TYPEQUAL_VARYING) {
1092  if ($2->IsVoidType()) {
1093  Error(@1, "\"varying\" qualifier is illegal with \"void\" type.");
1094  $$ = NULL;
1095  }
1096  else
1097  $$ = $2->GetAsVaryingType();
1098  }
1099  else if ($1 == TYPEQUAL_CONST)
1100  $$ = $2->GetAsConstType();
1101  else if ($1 == TYPEQUAL_SIGNED) {
1102  if ($2->IsIntType() == false) {
1103  Error(@1, "Can't apply \"signed\" qualifier to \"%s\" type.",
1104  $2->ResolveUnboundVariability(Variability::Varying)->GetString().c_str());
1105  $$ = $2;
1106  }
1107  }
1108  else if ($1 == TYPEQUAL_UNSIGNED) {
1109  const Type *t = $2->GetAsUnsignedType();
1110  if (t)
1111  $$ = t;
1112  else {
1113  Error(@1, "Can't apply \"unsigned\" qualifier to \"%s\" type. Ignoring.",
1114  $2->ResolveUnboundVariability(Variability::Varying)->GetString().c_str());
1115  $$ = $2;
1116  }
1117  }
1118  else if ($1 == TYPEQUAL_INLINE) {
1119  Error(@1, "\"inline\" qualifier is illegal outside of "
1120  "function declarations.");
1121  $$ = $2;
1122  }
1123  else if ($1 == TYPEQUAL_NOINLINE) {
1124  Error(@1, "\"noinline\" qualifier is illegal outside of "
1125  "function declarations.");
1126  $$ = $2;
1127  }
1128  else if ($1 == TYPEQUAL_TASK) {
1129  Error(@1, "\"task\" qualifier is illegal outside of "
1130  "function declarations.");
1131  $$ = $2;
1132  }
1133  else if ($1 == TYPEQUAL_UNMASKED) {
1134  Error(@1, "\"unmasked\" qualifier is illegal outside of "
1135  "function declarations.");
1136  $$ = $2;
1137  }
1138  else if ($1 == TYPEQUAL_EXPORT) {
1139  Error(@1, "\"export\" qualifier is illegal outside of "
1140  "function declarations.");
1141  $$ = $2;
1142  }
1143  else
1144  FATAL("Unhandled type qualifier in parser.");
1145  }
1146  else {
1147  if (m->errorCount == 0)
1148  Error(@1, "Lost type qualifier in parser.");
1149  $$ = NULL;
1150  }
1151  }
1152  ;
1153 
1154 
1155 struct_declarator_list
1156  : struct_declarator
1157  {
1158  std::vector<Declarator *> *sdl = new std::vector<Declarator *>;
1159  if ($1 != NULL)
1160  sdl->push_back($1);
1161  $$ = sdl;
1162  }
1163  | struct_declarator_list ',' struct_declarator
1164  {
1165  std::vector<Declarator *> *sdl = (std::vector<Declarator *> *)$1;
1166  if (sdl == NULL) {
1167  AssertPos(@1, m->errorCount > 0);
1168  sdl = new std::vector<Declarator *>;
1169  }
1170  if ($3 != NULL)
1171  sdl->push_back($3);
1172  $$ = sdl;
1173  }
1174  ;
1175 
1176 struct_declarator
1177  : declarator { $$ = $1; }
1178 /* bitfields
1179  | ':' constant_expression
1180  | declarator ':' constant_expression
1181 */
1182  ;
1183 
1184 enum_identifier
1185  : TOKEN_IDENTIFIER { $$ = strdup(yytext); }
1186 
1187 enum_specifier
1188  : TOKEN_ENUM '{' enumerator_list '}'
1189  {
1190  $$ = lCreateEnumType(NULL, $3, @1);
1191  }
1192  | TOKEN_ENUM enum_identifier '{' enumerator_list '}'
1193  {
1194  $$ = lCreateEnumType($2, $4, @2);
1195  }
1196  | TOKEN_ENUM '{' enumerator_list ',' '}'
1197  {
1198  $$ = lCreateEnumType(NULL, $3, @1);
1199  }
1200  | TOKEN_ENUM enum_identifier '{' enumerator_list ',' '}'
1201  {
1202  $$ = lCreateEnumType($2, $4, @2);
1203  }
1204  | TOKEN_ENUM enum_identifier
1205  {
1206  const Type *type = m->symbolTable->LookupType($2);
1207  if (type == NULL) {
1208  std::vector<std::string> alternates = m->symbolTable->ClosestEnumTypeMatch($2);
1209  std::string alts = lGetAlternates(alternates);
1210  Error(@2, "Enum type \"%s\" unknown.%s", $2, alts.c_str());
1211  $$ = NULL;
1212  }
1213  else {
1214  const EnumType *enumType = CastType<EnumType>(type);
1215  if (enumType == NULL) {
1216  Error(@2, "Type \"%s\" is not an enum type (%s).", $2,
1217  type->GetString().c_str());
1218  $$ = NULL;
1219  }
1220  else
1221  $$ = enumType;
1222  }
1223  }
1224  ;
1225 
1226 enumerator_list
1227  : enumerator
1228  {
1229  if ($1 == NULL)
1230  $$ = NULL;
1231  else {
1232  std::vector<Symbol *> *el = new std::vector<Symbol *>;
1233  el->push_back($1);
1234  $$ = el;
1235  }
1236  }
1237  | enumerator_list ',' enumerator
1238  {
1239  std::vector<Symbol *> *symList = $1;
1240  if (symList == NULL) {
1241  AssertPos(@1, m->errorCount > 0);
1242  symList = new std::vector<Symbol *>;
1243  }
1244  if ($3 != NULL)
1245  symList->push_back($3);
1246  $$ = symList;
1247  }
1248  ;
1249 
1250 enumerator
1251  : enum_identifier
1252  {
1253  $$ = new Symbol($1, @1);
1254  }
1255  | enum_identifier '=' constant_expression
1256  {
1257  int value;
1258  if ($1 != NULL && $3 != NULL &&
1259  lGetConstantInt($3, &value, @3, "Enumerator value")) {
1260  Symbol *sym = new Symbol($1, @1);
1261  sym->constValue = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
1262  (uint32_t)value, @3);
1263  $$ = sym;
1264  }
1265  else
1266  $$ = NULL;
1267  }
1268  ;
1269 
1270 type_qualifier
1271  : TOKEN_CONST { $$ = TYPEQUAL_CONST; }
1272  | TOKEN_UNIFORM { $$ = TYPEQUAL_UNIFORM; }
1273  | TOKEN_VARYING { $$ = TYPEQUAL_VARYING; }
1274  | TOKEN_TASK { $$ = TYPEQUAL_TASK; }
1275  | TOKEN_UNMASKED { $$ = TYPEQUAL_UNMASKED; }
1276  | TOKEN_EXPORT { $$ = TYPEQUAL_EXPORT; }
1277  | TOKEN_INLINE { $$ = TYPEQUAL_INLINE; }
1278  | TOKEN_NOINLINE { $$ = TYPEQUAL_NOINLINE; }
1279  | TOKEN_SIGNED { $$ = TYPEQUAL_SIGNED; }
1280  | TOKEN_UNSIGNED { $$ = TYPEQUAL_UNSIGNED; }
1281  ;
1282 
1283 type_qualifier_list
1284  : type_qualifier
1285  {
1286  $$ = $1;
1287  }
1288  | type_qualifier_list type_qualifier
1289  {
1290  $$ = $1 | $2;
1291  }
1292  ;
1293 
1294 declarator
1295  : pointer direct_declarator
1296  {
1297  if ($1 != NULL) {
1298  Declarator *tail = $1;
1299  while (tail->child != NULL)
1300  tail = tail->child;
1301  tail->child = $2;
1302  $$ = $1;
1303  }
1304  else
1305  $$ = NULL;
1306  }
1307  | reference direct_declarator
1308  {
1309  if ($1 != NULL) {
1310  Declarator *tail = $1;
1311  while (tail->child != NULL)
1312  tail = tail->child;
1313  tail->child = $2;
1314  $$ = $1;
1315  }
1316  else
1317  $$ = NULL;
1318  }
1319  | direct_declarator
1320  ;
1321 
1322 int_constant
1323  : TOKEN_INT8_CONSTANT { $$ = yylval.intVal; }
1324  | TOKEN_INT16_CONSTANT { $$ = yylval.intVal; }
1325  | TOKEN_INT32_CONSTANT { $$ = yylval.intVal; }
1326  | TOKEN_INT64_CONSTANT { $$ = yylval.intVal; }
1327  ;
1328 
1329 direct_declarator
1330  : TOKEN_IDENTIFIER
1331  {
1332  Declarator *d = new Declarator(DK_BASE, @1);
1333  d->name = yytext;
1334  $$ = d;
1335  }
1336  | '(' declarator ')'
1337  {
1338  $$ = $2;
1339  }
1340  | direct_declarator '[' constant_expression ']'
1341  {
1342  int size;
1343  if ($1 != NULL && lGetConstantInt($3, &size, @3, "Array dimension")) {
1344  if (size < 0) {
1345  Error(@3, "Array dimension must be non-negative.");
1346  $$ = NULL;
1347  }
1348  else {
1349  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @4));
1350  d->arraySize = size;
1351  d->child = $1;
1352  $$ = d;
1353  }
1354  }
1355  else
1356  $$ = NULL;
1357  }
1358  | direct_declarator '[' ']'
1359  {
1360  if ($1 != NULL) {
1361  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @3));
1362  d->arraySize = 0; // unsize
1363  d->child = $1;
1364  $$ = d;
1365  }
1366  else
1367  $$ = NULL;
1368  }
1369  | direct_declarator '[' error ']'
1370  {
1371  $$ = NULL;
1372  }
1373  | direct_declarator '(' parameter_type_list ')'
1374  {
1375  if ($1 != NULL) {
1376  Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @4));
1377  d->child = $1;
1378  if ($3 != NULL)
1379  d->functionParams = *$3;
1380  $$ = d;
1381  }
1382  else
1383  $$ = NULL;
1384  }
1385  | direct_declarator '(' ')'
1386  {
1387  if ($1 != NULL) {
1388  Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @3));
1389  d->child = $1;
1390  $$ = d;
1391  }
1392  else
1393  $$ = NULL;
1394  }
1395  | direct_declarator '(' error ')'
1396  {
1397  $$ = NULL;
1398  }
1399  ;
1400 
1401 
1402 pointer
1403  : '*'
1404  {
1405  $$ = new Declarator(DK_POINTER, @1);
1406  }
1407  | '*' type_qualifier_list
1408  {
1409  Declarator *d = new Declarator(DK_POINTER, Union(@1, @2));
1410  d->typeQualifiers = $2;
1411  $$ = d;
1412  }
1413  | '*' pointer
1414  {
1415  Declarator *d = new Declarator(DK_POINTER, Union(@1, @2));
1416  d->child = $2;
1417  $$ = d;
1418  }
1419  | '*' type_qualifier_list pointer
1420  {
1421  Declarator *d = new Declarator(DK_POINTER, Union(@1, @3));
1422  d->typeQualifiers = $2;
1423  d->child = $3;
1424  $$ = d;
1425  }
1426  ;
1427 
1428 
1429 reference
1430  : '&'
1431  {
1432  $$ = new Declarator(DK_REFERENCE, @1);
1433  }
1434  ;
1435 
1436 
1437 parameter_type_list
1438  : parameter_list { $$ = $1; }
1439  ;
1440 
1441 parameter_list
1442  : parameter_declaration
1443  {
1444  std::vector<Declaration *> *dl = new std::vector<Declaration *>;
1445  if ($1 != NULL)
1446  dl->push_back($1);
1447  $$ = dl;
1448  }
1449  | parameter_list ',' parameter_declaration
1450  {
1451  std::vector<Declaration *> *dl = (std::vector<Declaration *> *)$1;
1452  if (dl == NULL)
1453  dl = new std::vector<Declaration *>;
1454  if ($3 != NULL)
1455  dl->push_back($3);
1456  $$ = dl;
1457  }
1458  | error ','
1459  {
1460  lSuggestParamListAlternates();
1461  $$ = NULL;
1462  }
1463  ;
1464 
1465 parameter_declaration
1466  : declaration_specifiers declarator
1467  {
1468  $$ = new Declaration($1, $2);
1469  }
1470  | declaration_specifiers declarator '=' initializer
1471  {
1472  if ($1 != NULL && $2 != NULL) {
1473  $2->initExpr = $4;
1474  $$ = new Declaration($1, $2);
1475  }
1476  else
1477  $$ = NULL;
1478  }
1479  | declaration_specifiers abstract_declarator
1480  {
1481  if ($1 != NULL && $2 != NULL)
1482  $$ = new Declaration($1, $2);
1483  else
1484  $$ = NULL;
1485  }
1486  | declaration_specifiers
1487  {
1488  if ($1 == NULL)
1489  $$ = NULL;
1490  else
1491  $$ = new Declaration($1);
1492  }
1493  ;
1494 
1495 /* K&R?
1496 identifier_list
1497  : IDENTIFIER
1498  | identifier_list ',' IDENTIFIER
1499  ;
1500 */
1501 
1502 type_name
1503  : specifier_qualifier_list
1504  | specifier_qualifier_list abstract_declarator
1505  {
1506  if ($1 == NULL || $2 == NULL)
1507  $$ = NULL;
1508  else {
1509  $2->InitFromType($1, NULL);
1510  $$ = $2->type;
1511  }
1512  }
1513  ;
1514 
1515 abstract_declarator
1516  : pointer
1517  {
1518  $$ = $1;
1519  }
1520  | direct_abstract_declarator
1521  | pointer direct_abstract_declarator
1522  {
1523  if ($2 == NULL)
1524  $$ = NULL;
1525  else {
1526  Declarator *d = new Declarator(DK_POINTER, Union(@1, @2));
1527  d->child = $2;
1528  $$ = d;
1529  }
1530  }
1531  | reference
1532  {
1533  $$ = new Declarator(DK_REFERENCE, @1);
1534  }
1535  | reference direct_abstract_declarator
1536  {
1537  if ($2 == NULL)
1538  $$ = NULL;
1539  else {
1540  Declarator *d = new Declarator(DK_REFERENCE, Union(@1, @2));
1541  d->child = $2;
1542  $$ = d;
1543  }
1544  }
1545  ;
1546 
1547 direct_abstract_declarator
1548  : '(' abstract_declarator ')'
1549  { $$ = $2; }
1550  | '[' ']'
1551  {
1552  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @2));
1553  d->arraySize = 0;
1554  $$ = d;
1555  }
1556  | '[' constant_expression ']'
1557  {
1558  int size;
1559  if ($2 != NULL && lGetConstantInt($2, &size, @2, "Array dimension")) {
1560  if (size < 0) {
1561  Error(@2, "Array dimension must be non-negative.");
1562  $$ = NULL;
1563  }
1564  else {
1565  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @3));
1566  d->arraySize = size;
1567  $$ = d;
1568  }
1569  }
1570  else
1571  $$ = NULL;
1572  }
1573  | direct_abstract_declarator '[' ']'
1574  {
1575  if ($1 == NULL)
1576  $$ = NULL;
1577  else {
1578  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @3));
1579  d->arraySize = 0;
1580  d->child = $1;
1581  $$ = d;
1582  }
1583  }
1584  | direct_abstract_declarator '[' constant_expression ']'
1585  {
1586  int size;
1587  if ($1 != NULL && $3 != NULL && lGetConstantInt($3, &size, @3, "Array dimension")) {
1588  if (size < 0) {
1589  Error(@3, "Array dimension must be non-negative.");
1590  $$ = NULL;
1591  }
1592  else {
1593  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @4));
1594  d->arraySize = size;
1595  d->child = $1;
1596  $$ = d;
1597  }
1598  }
1599  else
1600  $$ = NULL;
1601  }
1602  | '(' ')'
1603  { $$ = new Declarator(DK_FUNCTION, Union(@1, @2)); }
1604  | '(' parameter_type_list ')'
1605  {
1606  Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @3));
1607  if ($2 != NULL) d->functionParams = *$2;
1608  $$ = d;
1609  }
1610  | direct_abstract_declarator '(' ')'
1611  {
1612  if ($1 == NULL)
1613  $$ = NULL;
1614  else {
1615  Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @3));
1616  d->child = $1;
1617  $$ = d;
1618  }
1619  }
1620  | direct_abstract_declarator '(' parameter_type_list ')'
1621  {
1622  if ($1 == NULL)
1623  $$ = NULL;
1624  else {
1625  Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @4));
1626  d->child = $1;
1627  if ($3 != NULL) d->functionParams = *$3;
1628  $$ = d;
1629  }
1630  }
1631  ;
1632 
1633 initializer
1634  : assignment_expression
1635  | '{' initializer_list '}' { $$ = $2; }
1636  | '{' initializer_list ',' '}' { $$ = $2; }
1637  ;
1638 
1639 initializer_list
1640  : initializer
1641  { $$ = new ExprList($1, @1); }
1642  | initializer_list ',' initializer
1643  {
1644  ExprList *exprList = $1;
1645  if (exprList == NULL) {
1646  AssertPos(@1, m->errorCount > 0);
1647  exprList = new ExprList(@3);
1648  }
1649  exprList->exprs.push_back($3);
1650  exprList->pos = Union(exprList->pos, @3);
1651  $$ = exprList;
1652  }
1653  ;
1654 
1655 statement
1656  : labeled_statement
1657  | compound_statement
1658  | expression_statement
1659  | selection_statement
1660  | iteration_statement
1661  | jump_statement
1662  | declaration_statement
1663  | print_statement
1664  | assert_statement
1665  | sync_statement
1666  | delete_statement
1667  | unmasked_statement
1668  | error ';'
1669  {
1670  lSuggestBuiltinAlternates();
1671  $$ = NULL;
1672  }
1673  ;
1674 
1675 labeled_statement
1676  : goto_identifier ':' statement
1677  {
1678  $$ = new LabeledStmt($1, $3, @1);
1679  }
1680  | TOKEN_CASE constant_expression ':' statement
1681  {
1682  int value;
1683  if ($2 != NULL &&
1684  lGetConstantInt($2, &value, @2, "Case statement value")) {
1685  $$ = new CaseStmt(value, $4, Union(@1, @2));
1686  }
1687  else
1688  $$ = NULL;
1689  }
1690  | TOKEN_DEFAULT ':' statement
1691  { $$ = new DefaultStmt($3, @1); }
1692  ;
1693 
1694 start_scope
1695  : '{' { m->symbolTable->PushScope(); }
1696  ;
1697 
1698 end_scope
1699  : '}' { m->symbolTable->PopScope(); }
1700  ;
1701 
1702 compound_statement
1703  : '{' '}' { $$ = NULL; }
1704  | start_scope statement_list end_scope { $$ = $2; }
1705  ;
1706 
1707 statement_list
1708  : statement
1709  {
1710  StmtList *sl = new StmtList(@1);
1711  sl->Add($1);
1712  $$ = sl;
1713  }
1714  | statement_list statement
1715  {
1716  StmtList *sl = (StmtList *)$1;
1717  if (sl == NULL) {
1718  AssertPos(@1, m->errorCount > 0);
1719  sl = new StmtList(@2);
1720  }
1721  sl->Add($2);
1722  $$ = sl;
1723  }
1724  ;
1725 
1726 expression_statement
1727  : ';' { $$ = NULL; }
1728  | expression ';' { $$ = $1 ? new ExprStmt($1, @1) : NULL; }
1729  ;
1730 
1731 selection_statement
1732  : TOKEN_IF '(' expression ')' statement
1733  { $$ = new IfStmt($3, $5, NULL, false, @1); }
1734  | TOKEN_IF '(' expression ')' statement TOKEN_ELSE statement
1735  { $$ = new IfStmt($3, $5, $7, false, @1); }
1736  | TOKEN_CIF '(' expression ')' statement
1737  { $$ = new IfStmt($3, $5, NULL, true, @1); }
1738  | TOKEN_CIF '(' expression ')' statement TOKEN_ELSE statement
1739  { $$ = new IfStmt($3, $5, $7, true, @1); }
1740  | TOKEN_SWITCH '(' expression ')' statement
1741  { $$ = new SwitchStmt($3, $5, @1); }
1742  ;
1743 
1744 for_test
1745  : ';'
1746  { $$ = NULL; }
1747  | expression ';'
1748  { $$ = $1; }
1749  ;
1750 
1751 for_init_statement
1752  : expression_statement
1753  | declaration_statement
1754  ;
1755 
1756 for_scope
1757  : TOKEN_FOR { m->symbolTable->PushScope(); }
1758  ;
1759 
1760 cfor_scope
1761  : TOKEN_CFOR { m->symbolTable->PushScope(); }
1762  ;
1763 
1764 foreach_scope
1765  : TOKEN_FOREACH { m->symbolTable->PushScope(); }
1766  ;
1767 
1768 foreach_tiled_scope
1769  : TOKEN_FOREACH_TILED { m->symbolTable->PushScope(); }
1770  ;
1771 
1772 foreach_identifier
1773  : TOKEN_IDENTIFIER
1774  {
1775  $$ = new Symbol(yytext, @1, AtomicType::VaryingInt32->GetAsConstType());
1776  }
1777  ;
1778 
1779 foreach_active_scope
1780  : TOKEN_FOREACH_ACTIVE { m->symbolTable->PushScope(); }
1781  ;
1782 
1783 foreach_active_identifier
1784  : TOKEN_IDENTIFIER
1785  {
1786  $$ = new Symbol(yytext, @1, AtomicType::UniformInt64->GetAsConstType());
1787  }
1788  ;
1789 
1790 integer_dotdotdot
1791  : TOKEN_INT32DOTDOTDOT_CONSTANT {
1792  $$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
1793  (int32_t)yylval.intVal, @1);
1794  }
1795  | TOKEN_UINT32DOTDOTDOT_CONSTANT {
1796  $$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
1797  (uint32_t)yylval.intVal, @1);
1798  }
1799  | TOKEN_INT64DOTDOTDOT_CONSTANT {
1800  $$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
1801  (int64_t)yylval.intVal, @1);
1802  }
1803  | TOKEN_UINT64DOTDOTDOT_CONSTANT {
1804  $$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
1805  (uint64_t)yylval.intVal, @1);
1806  }
1807  ;
1808 
1809 foreach_dimension_specifier
1810  : foreach_identifier '=' assignment_expression TOKEN_DOTDOTDOT assignment_expression
1811  {
1812  $$ = new ForeachDimension($1, $3, $5);
1813  }
1814  | foreach_identifier '=' integer_dotdotdot assignment_expression
1815  {
1816  $$ = new ForeachDimension($1, $3, $4);
1817  }
1818  ;
1819 
1820 foreach_dimension_list
1821  : foreach_dimension_specifier
1822  {
1823  $$ = new std::vector<ForeachDimension *>;
1824  $$->push_back($1);
1825  }
1826  | foreach_dimension_list ',' foreach_dimension_specifier
1827  {
1828  std::vector<ForeachDimension *> *dv = $1;
1829  if (dv == NULL) {
1830  AssertPos(@1, m->errorCount > 0);
1831  dv = new std::vector<ForeachDimension *>;
1832  }
1833  if ($3 != NULL)
1834  dv->push_back($3);
1835  $$ = dv;
1836  }
1837  ;
1838 
1839 foreach_unique_scope
1840  : TOKEN_FOREACH_UNIQUE { m->symbolTable->PushScope(); }
1841  ;
1842 
1843 foreach_unique_identifier
1844  : TOKEN_IDENTIFIER { $$ = yylval.stringVal->c_str(); }
1845  ;
1846 
1847 iteration_statement
1848  : TOKEN_WHILE '(' expression ')' statement
1849  { $$ = new ForStmt(NULL, $3, NULL, $5, false, @1); }
1850  | TOKEN_CWHILE '(' expression ')' statement
1851  { $$ = new ForStmt(NULL, $3, NULL, $5, true, @1); }
1852  | TOKEN_DO statement TOKEN_WHILE '(' expression ')' ';'
1853  { $$ = new DoStmt($5, $2, false, @1); }
1854  | TOKEN_CDO statement TOKEN_WHILE '(' expression ')' ';'
1855  { $$ = new DoStmt($5, $2, true, @1); }
1856  | for_scope '(' for_init_statement for_test ')' statement
1857  { $$ = new ForStmt($3, $4, NULL, $6, false, @1);
1858  m->symbolTable->PopScope();
1859  }
1860  | for_scope '(' for_init_statement for_test expression ')' statement
1861  { $$ = new ForStmt($3, $4, new ExprStmt($5, @5), $7, false, @1);
1862  m->symbolTable->PopScope();
1863  }
1864  | cfor_scope '(' for_init_statement for_test ')' statement
1865  { $$ = new ForStmt($3, $4, NULL, $6, true, @1);
1866  m->symbolTable->PopScope();
1867  }
1868  | cfor_scope '(' for_init_statement for_test expression ')' statement
1869  { $$ = new ForStmt($3, $4, new ExprStmt($5, @5), $7, true, @1);
1870  m->symbolTable->PopScope();
1871  }
1872  | foreach_scope '(' foreach_dimension_list ')'
1873  {
1874  std::vector<ForeachDimension *> *dims = $3;
1875  if (dims == NULL) {
1876  AssertPos(@3, m->errorCount > 0);
1877  dims = new std::vector<ForeachDimension *>;
1878  }
1879  for (unsigned int i = 0; i < dims->size(); ++i)
1880  m->symbolTable->AddVariable((*dims)[i]->sym);
1881  }
1882  statement
1883  {
1884  std::vector<ForeachDimension *> *dims = $3;
1885  if (dims == NULL) {
1886  AssertPos(@3, m->errorCount > 0);
1887  dims = new std::vector<ForeachDimension *>;
1888  }
1889 
1890  std::vector<Symbol *> syms;
1891  std::vector<Expr *> begins, ends;
1892  for (unsigned int i = 0; i < dims->size(); ++i) {
1893  syms.push_back((*dims)[i]->sym);
1894  begins.push_back((*dims)[i]->beginExpr);
1895  ends.push_back((*dims)[i]->endExpr);
1896  }
1897  $$ = new ForeachStmt(syms, begins, ends, $6, false, @1);
1898  m->symbolTable->PopScope();
1899  }
1900  | foreach_tiled_scope '(' foreach_dimension_list ')'
1901  {
1902  std::vector<ForeachDimension *> *dims = $3;
1903  if (dims == NULL) {
1904  AssertPos(@3, m->errorCount > 0);
1905  dims = new std::vector<ForeachDimension *>;
1906  }
1907 
1908  for (unsigned int i = 0; i < dims->size(); ++i)
1909  m->symbolTable->AddVariable((*dims)[i]->sym);
1910  }
1911  statement
1912  {
1913  std::vector<ForeachDimension *> *dims = $3;
1914  if (dims == NULL) {
1915  AssertPos(@1, m->errorCount > 0);
1916  dims = new std::vector<ForeachDimension *>;
1917  }
1918 
1919  std::vector<Symbol *> syms;
1920  std::vector<Expr *> begins, ends;
1921  for (unsigned int i = 0; i < dims->size(); ++i) {
1922  syms.push_back((*dims)[i]->sym);
1923  begins.push_back((*dims)[i]->beginExpr);
1924  ends.push_back((*dims)[i]->endExpr);
1925  }
1926  $$ = new ForeachStmt(syms, begins, ends, $6, true, @1);
1927  m->symbolTable->PopScope();
1928  }
1929  | foreach_active_scope '(' foreach_active_identifier ')'
1930  {
1931  if ($3 != NULL)
1932  m->symbolTable->AddVariable($3);
1933  }
1934  statement
1935  {
1936  $$ = new ForeachActiveStmt($3, $6, Union(@1, @4));
1937  m->symbolTable->PopScope();
1938  }
1939  | foreach_unique_scope '(' foreach_unique_identifier TOKEN_IN
1940  expression ')'
1941  {
1942  Expr *expr = $5;
1943  const Type *type;
1944  if (expr != NULL &&
1945  (expr = TypeCheck(expr)) != NULL &&
1946  (type = expr->GetType()) != NULL) {
1947  const Type *iterType = type->GetAsUniformType()->GetAsConstType();
1948  Symbol *sym = new Symbol($3, @3, iterType);
1949  m->symbolTable->AddVariable(sym);
1950  }
1951  }
1952  statement
1953  {
1954  $$ = new ForeachUniqueStmt($3, $5, $8, @1);
1955  m->symbolTable->PopScope();
1956  }
1957  ;
1958 
1959 goto_identifier
1960  : TOKEN_IDENTIFIER { $$ = yylval.stringVal->c_str(); }
1961  ;
1962 
1963 jump_statement
1964  : TOKEN_GOTO goto_identifier ';'
1965  { $$ = new GotoStmt($2, @1, @2); }
1966  | TOKEN_CONTINUE ';'
1967  { $$ = new ContinueStmt(@1); }
1968  | TOKEN_BREAK ';'
1969  { $$ = new BreakStmt(@1); }
1970  | TOKEN_RETURN ';'
1971  { $$ = new ReturnStmt(NULL, @1); }
1972  | TOKEN_RETURN expression ';'
1973  { $$ = new ReturnStmt($2, @1); }
1974  ;
1975 
1976 sync_statement
1977  : TOKEN_SYNC ';'
1978  { $$ = new ExprStmt(new SyncExpr(@1), @1); }
1979  ;
1980 
1981 delete_statement
1982  : TOKEN_DELETE expression ';'
1983  {
1984  $$ = new DeleteStmt($2, Union(@1, @2));
1985  }
1986  ;
1987 
1988 unmasked_statement
1989  : TOKEN_UNMASKED '{' statement_list '}'
1990  {
1991  $$ = new UnmaskedStmt($3, @1);
1992  }
1993  ;
1994 
1995 print_statement
1996  : TOKEN_PRINT '(' string_constant ')' ';'
1997  {
1998  $$ = new PrintStmt(*$3, NULL, @1);
1999  }
2000  | TOKEN_PRINT '(' string_constant ',' argument_expression_list ')' ';'
2001  {
2002  $$ = new PrintStmt(*$3, $5, @1);
2003  }
2004  ;
2005 
2006 assert_statement
2007  : TOKEN_ASSERT '(' string_constant ',' expression ')' ';'
2008  {
2009  $$ = new AssertStmt(*$3, $5, @1);
2010  }
2011  ;
2012 
2013 translation_unit
2014  : external_declaration
2015  | translation_unit external_declaration
2016  | error ';'
2017  ;
2018 
2019 external_declaration
2020  : function_definition
2021  | TOKEN_EXTERN TOKEN_STRING_C_LITERAL '{' declaration '}'
2022  | TOKEN_EXPORT '{' type_specifier_list '}' ';'
2023  {
2024  if ($3 != NULL)
2025  m->AddExportedTypes(*$3);
2026  }
2027  | declaration
2028  {
2029  if ($1 != NULL)
2030  for (unsigned int i = 0; i < $1->declarators.size(); ++i)
2031  lAddDeclaration($1->declSpecs, $1->declarators[i]);
2032  }
2033  | ';'
2034  ;
2035 
2036 function_definition
2037  : declaration_specifiers declarator
2038  {
2039  lAddDeclaration($1, $2);
2040  lAddFunctionParams($2);
2041  lAddMaskToSymbolTable(@2);
2042  if ($1->typeQualifiers & TYPEQUAL_TASK)
2043  lAddThreadIndexCountToSymbolTable(@2);
2044  }
2045  compound_statement
2046  {
2047  if ($2 != NULL) {
2048  $2->InitFromDeclSpecs($1);
2049  const FunctionType *funcType = CastType<FunctionType>($2->type);
2050  if (funcType == NULL)
2051  AssertPos(@1, m->errorCount > 0);
2052  else if ($1->storageClass == SC_TYPEDEF)
2053  Error(@1, "Illegal \"typedef\" provided with function definition.");
2054  else {
2055  Stmt *code = $4;
2056  if (code == NULL) code = new StmtList(@4);
2057  m->AddFunctionDefinition($2->name, funcType, code);
2058  }
2059  }
2060  m->symbolTable->PopScope(); // push in lAddFunctionParams();
2061  }
2062 /* function with no declared return type??
2063 func(...)
2064  | declarator { lAddFunctionParams($1); } compound_statement
2065  {
2066  m->AddFunction(new DeclSpecs(XXX, $1, $3);
2067  m->symbolTable->PopScope(); // push in lAddFunctionParams();
2068  }
2069 */
2070  ;
2071 
2072 %%
2073 
2074 
2075 void yyerror(const char *s) {
2076  if (strlen(yytext) == 0)
2077  Error(yylloc, "Premature end of file: %s.", s);
2078  else
2079  Error(yylloc, "%s.", s);
2080 }
2081 
2082 
2083 static int
2084 lYYTNameErr (char *yyres, const char *yystr)
2085 {
2086  extern std::map<std::string, std::string> tokenNameRemap;
2087  Assert(tokenNameRemap.size() > 0);
2088  if (tokenNameRemap.find(yystr) != tokenNameRemap.end()) {
2089  std::string n = tokenNameRemap[yystr];
2090  if (yyres == NULL)
2091  return n.size();
2092  else
2093  return yystpcpy(yyres, n.c_str()) - yyres;
2094  }
2095 
2096  if (*yystr == '"')
2097  {
2098  YYSIZE_T yyn = 0;
2099  char const *yyp = yystr;
2100 
2101  for (;;)
2102  switch (*++yyp)
2103  {
2104  case '\'':
2105  case ',':
2106  goto do_not_strip_quotes;
2107 
2108  case '\\':
2109  if (*++yyp != '\\')
2110  goto do_not_strip_quotes;
2111  /* Fall through. */
2112  default:
2113  if (yyres)
2114  yyres[yyn] = *yyp;
2115  yyn++;
2116  break;
2117 
2118  case '"':
2119  if (yyres)
2120  yyres[yyn] = '\0';
2121  return yyn;
2122  }
2123  do_not_strip_quotes: ;
2124  }
2125 
2126  if (! yyres)
2127  return yystrlen (yystr);
2128 
2129  return yystpcpy (yyres, yystr) - yyres;
2130 }
2131 
2132 static void
2133 lSuggestBuiltinAlternates() {
2134  std::vector<std::string> builtinTokens;
2135  const char **token = lBuiltinTokens;
2136  while (*token) {
2137  builtinTokens.push_back(*token);
2138  ++token;
2139  }
2140  std::vector<std::string> alternates = MatchStrings(yytext, builtinTokens);
2141  std::string alts = lGetAlternates(alternates);
2142  if (alts.size() > 0)
2143  Error(yylloc, "%s", alts.c_str());
2144 }
2145 
2146 
2147 static void
2148 lSuggestParamListAlternates() {
2149  std::vector<std::string> builtinTokens;
2150  const char **token = lParamListTokens;
2151  while (*token) {
2152  builtinTokens.push_back(*token);
2153  ++token;
2154  }
2155  std::vector<std::string> alternates = MatchStrings(yytext, builtinTokens);
2156  std::string alts = lGetAlternates(alternates);
2157  if (alts.size() > 0)
2158  Error(yylloc, "%s", alts.c_str());
2159 }
2160 
2161 
2162 static void
2163 lAddDeclaration(DeclSpecs *ds, Declarator *decl) {
2164  if (ds == NULL || decl == NULL)
2165  // Error happened earlier during parsing
2166  return;
2167 
2168  decl->InitFromDeclSpecs(ds);
2169  if (ds->storageClass == SC_TYPEDEF)
2170  m->AddTypeDef(decl->name, decl->type, decl->pos);
2171  else {
2172  if (decl->type == NULL) {
2173  Assert(m->errorCount > 0);
2174  return;
2175  }
2176 
2177  decl->type = decl->type->ResolveUnboundVariability(Variability::Varying);
2178 
2179  const FunctionType *ft = CastType<FunctionType>(decl->type);
2180  if (ft != NULL) {
2181  bool isInline = (ds->typeQualifiers & TYPEQUAL_INLINE);
2182  bool isNoInline = (ds->typeQualifiers & TYPEQUAL_NOINLINE);
2183  m->AddFunctionDeclaration(decl->name, ft, ds->storageClass,
2184  isInline, isNoInline, decl->pos);
2185  }
2186  else {
2187  bool isConst = (ds->typeQualifiers & TYPEQUAL_CONST) != 0;
2188  m->AddGlobalVariable(decl->name, decl->type, decl->initExpr,
2189  isConst, decl->storageClass, decl->pos);
2190  }
2191  }
2192 }
2193 
2194 
2195 /** We're about to start parsing the body of a function; add all of the
2196  parameters to the symbol table so that they're available.
2197 */
2198 static void
2199 lAddFunctionParams(Declarator *decl) {
2200  m->symbolTable->PushScope();
2201 
2202  if (decl == NULL) {
2203  AssertPos(decl->pos, m->errorCount > 0);
2204  return;
2205  }
2206 
2207  // walk down to the declarator for the function itself
2208  while (decl->kind != DK_FUNCTION && decl->child != NULL)
2209  decl = decl->child;
2210  if (decl->kind != DK_FUNCTION) {
2211  AssertPos(decl->pos, m->errorCount > 0);
2212  return;
2213  }
2214 
2215  // now loop over its parameters and add them to the symbol table
2216  for (unsigned int i = 0; i < decl->functionParams.size(); ++i) {
2217  Declaration *pdecl = decl->functionParams[i];
2218  Assert(pdecl != NULL && pdecl->declarators.size() == 1);
2219  Declarator *declarator = pdecl->declarators[0];
2220  if (declarator == NULL)
2221  AssertPos(decl->pos, m->errorCount > 0);
2222  else {
2223  Symbol *sym = new Symbol(declarator->name, declarator->pos,
2224  declarator->type, declarator->storageClass);
2225 #ifndef NDEBUG
2226  bool ok = m->symbolTable->AddVariable(sym);
2227  if (ok == false)
2228  AssertPos(decl->pos, m->errorCount > 0);
2229 #else
2230  m->symbolTable->AddVariable(sym);
2231 #endif
2232  }
2233  }
2234 
2235  // The corresponding pop scope happens in function_definition rules
2236  // above...
2237 }
2238 
2239 
2240 /** Add a symbol for the built-in mask variable to the symbol table */
2241 static void lAddMaskToSymbolTable(SourcePos pos) {
2242  const Type *t = NULL;
2243  switch (g->target->getMaskBitCount()) {
2244  case 1:
2245  t = AtomicType::VaryingBool;
2246  break;
2247  case 8:
2248  t = AtomicType::VaryingUInt8;
2249  break;
2250  case 16:
2251  t = AtomicType::VaryingUInt16;
2252  break;
2253  case 32:
2254  t = AtomicType::VaryingUInt32;
2255  break;
2256  case 64:
2257  t = AtomicType::VaryingUInt64;
2258  break;
2259  default:
2260  FATAL("Unhandled mask bitsize in lAddMaskToSymbolTable");
2261  }
2262 
2263  t = t->GetAsConstType();
2264  Symbol *maskSymbol = new Symbol("__mask", pos, t);
2265  m->symbolTable->AddVariable(maskSymbol);
2266 }
2267 
2268 
2269 /** Add the thread index and thread count variables to the symbol table
2270  (this should only be done for 'task'-qualified functions. */
2271 static void lAddThreadIndexCountToSymbolTable(SourcePos pos) {
2272  const Type *type = AtomicType::UniformUInt32->GetAsConstType();
2273 
2274  Symbol *threadIndexSym = new Symbol("threadIndex", pos, type);
2275  m->symbolTable->AddVariable(threadIndexSym);
2276 
2277  Symbol *threadCountSym = new Symbol("threadCount", pos, type);
2278  m->symbolTable->AddVariable(threadCountSym);
2279 
2280  Symbol *taskIndexSym = new Symbol("taskIndex", pos, type);
2281  m->symbolTable->AddVariable(taskIndexSym);
2282 
2283  Symbol *taskCountSym = new Symbol("taskCount", pos, type);
2284  m->symbolTable->AddVariable(taskCountSym);
2285 
2286  Symbol *taskIndexSym0 = new Symbol("taskIndex0", pos, type);
2287  m->symbolTable->AddVariable(taskIndexSym0);
2288  Symbol *taskIndexSym1 = new Symbol("taskIndex1", pos, type);
2289  m->symbolTable->AddVariable(taskIndexSym1);
2290  Symbol *taskIndexSym2 = new Symbol("taskIndex2", pos, type);
2291  m->symbolTable->AddVariable(taskIndexSym2);
2292 
2293 
2294  Symbol *taskCountSym0 = new Symbol("taskCount0", pos, type);
2295  m->symbolTable->AddVariable(taskCountSym0);
2296  Symbol *taskCountSym1 = new Symbol("taskCount1", pos, type);
2297  m->symbolTable->AddVariable(taskCountSym1);
2298  Symbol *taskCountSym2 = new Symbol("taskCount2", pos, type);
2299  m->symbolTable->AddVariable(taskCountSym2);
2300 }
2301 
2302 
2303 /** Small utility routine to construct a string for error messages that
2304  suggests alternate tokens for possibly-misspelled ones... */
2305 static std::string lGetAlternates(std::vector<std::string> &alternates) {
2306  std::string alts;
2307  if (alternates.size()) {
2308  alts += " Did you mean ";
2309  for (unsigned int i = 0; i < alternates.size(); ++i) {
2310  alts += std::string("\"") + alternates[i] + std::string("\"");
2311  if (i < alternates.size() - 1) alts += ", or ";
2312  }
2313  alts += "?";
2314  }
2315  return alts;
2316 }
2317 
2318 static const char *
2319 lGetStorageClassString(StorageClass sc) {
2320  switch (sc) {
2321  case SC_NONE:
2322  return "";
2323  case SC_EXTERN:
2324  return "extern";
2325  case SC_STATIC:
2326  return "static";
2327  case SC_TYPEDEF:
2328  return "typedef";
2329  case SC_EXTERN_C:
2330  return "extern \"C\"";
2331  default:
2332  Assert(!"logic error in lGetStorageClassString()");
2333  return "";
2334  }
2335 }
2336 
2337 
2338 /** Given an expression, see if it is equal to a compile-time constant
2339  integer value. If so, return true and return the value in *value.
2340  If the expression isn't a compile-time constant or isn't an integer
2341  type, return false.
2342 */
2343 static bool
2344 lGetConstantInt(Expr *expr, int *value, SourcePos pos, const char *usage) {
2345  if (expr == NULL)
2346  return false;
2347  expr = TypeCheck(expr);
2348  if (expr == NULL)
2349  return false;
2350  expr = Optimize(expr);
2351  if (expr == NULL)
2352  return false;
2353 
2354  llvm::Constant *cval = expr->GetConstant(expr->GetType());
2355  if (cval == NULL) {
2356  Error(pos, "%s must be a compile-time constant.", usage);
2357  return false;
2358  }
2359  else {
2360  llvm::ConstantInt *ci = llvm::dyn_cast<llvm::ConstantInt>(cval);
2361  if (ci == NULL) {
2362  Error(pos, "%s must be a compile-time integer constant.", usage);
2363  return false;
2364  }
2365  if ((int64_t)((int32_t)ci->getSExtValue()) != ci->getSExtValue()) {
2366  Error(pos, "%s must be representable with a 32-bit integer.", usage);
2367  return false;
2368  }
2369  const Type *type = expr->GetType();
2370  if (type->IsUnsignedType())
2371  *value = (int)ci->getZExtValue();
2372  else
2373  *value = (int)ci->getSExtValue();
2374  return true;
2375  }
2376 }
2377 
2378 
2379 static EnumType *
2380 lCreateEnumType(const char *name, std::vector<Symbol *> *enums, SourcePos pos) {
2381  if (enums == NULL)
2382  return NULL;
2383 
2384  EnumType *enumType = name ? new EnumType(name, pos) : new EnumType(pos);
2385  if (name != NULL)
2386  m->symbolTable->AddType(name, enumType, pos);
2387 
2388  lFinalizeEnumeratorSymbols(*enums, enumType);
2389  for (unsigned int i = 0; i < enums->size(); ++i)
2390  m->symbolTable->AddVariable((*enums)[i]);
2391  enumType->SetEnumerators(*enums);
2392  return enumType;
2393 }
2394 
2395 
2396 /** Given an array of enumerator symbols, make sure each of them has a
2397  ConstExpr * in their Symbol::constValue member that stores their
2398  unsigned integer value. Symbols that had values explicitly provided
2399  in the source file will already have ConstExpr * set; we just need
2400  to set the values for the others here.
2401 */
2402 static void
2403 lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
2404  const EnumType *enumType) {
2405  enumType = enumType->GetAsConstType();
2406  enumType = enumType->GetAsUniformType();
2407 
2408  /* nextVal tracks the value for the next enumerant. It starts from
2409  zero and goes up with each successive enumerant. If any of them
2410  has a value specified, then nextVal is ignored for that one and is
2411  set to one plus that one's value for the default value for the next
2412  one. */
2413  uint32_t nextVal = 0;
2414 
2415  for (unsigned int i = 0; i < enums.size(); ++i) {
2416  enums[i]->type = enumType;
2417  if (enums[i]->constValue != NULL) {
2418  /* Already has a value, so first update nextVal with it. */
2419  int count = enums[i]->constValue->GetValues(&nextVal);
2420  AssertPos(enums[i]->pos, count == 1);
2421  ++nextVal;
2422 
2423  /* When the source file as being parsed, the ConstExpr for any
2424  enumerant with a specified value was set to have unsigned
2425  int32 type, since we haven't created the parent EnumType
2426  by then. Therefore, add a little type cast from uint32 to
2427  the actual enum type here and optimize it, which will have
2428  us end up with a ConstExpr with the desired EnumType... */
2429  Expr *castExpr = new TypeCastExpr(enumType, enums[i]->constValue,
2430  enums[i]->pos);
2431  castExpr = Optimize(castExpr);
2432  enums[i]->constValue = llvm::dyn_cast<ConstExpr>(castExpr);
2433  AssertPos(enums[i]->pos, enums[i]->constValue != NULL);
2434  }
2435  else {
2436  enums[i]->constValue = new ConstExpr(enumType, nextVal++,
2437  enums[i]->pos);
2438  }
2439  }
2440 }