Intel SPMD Program Compiler  1.9.1
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_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_TASK) {
1124  Error(@1, "\"task\" qualifier is illegal outside of "
1125  "function declarations.");
1126  $$ = $2;
1127  }
1128  else if ($1 == TYPEQUAL_UNMASKED) {
1129  Error(@1, "\"unmasked\" qualifier is illegal outside of "
1130  "function declarations.");
1131  $$ = $2;
1132  }
1133  else if ($1 == TYPEQUAL_EXPORT) {
1134  Error(@1, "\"export\" qualifier is illegal outside of "
1135  "function declarations.");
1136  $$ = $2;
1137  }
1138  else
1139  FATAL("Unhandled type qualifier in parser.");
1140  }
1141  else {
1142  if (m->errorCount == 0)
1143  Error(@1, "Lost type qualifier in parser.");
1144  $$ = NULL;
1145  }
1146  }
1147  ;
1148 
1149 
1150 struct_declarator_list
1151  : struct_declarator
1152  {
1153  std::vector<Declarator *> *sdl = new std::vector<Declarator *>;
1154  if ($1 != NULL)
1155  sdl->push_back($1);
1156  $$ = sdl;
1157  }
1158  | struct_declarator_list ',' struct_declarator
1159  {
1160  std::vector<Declarator *> *sdl = (std::vector<Declarator *> *)$1;
1161  if (sdl == NULL) {
1162  AssertPos(@1, m->errorCount > 0);
1163  sdl = new std::vector<Declarator *>;
1164  }
1165  if ($3 != NULL)
1166  sdl->push_back($3);
1167  $$ = sdl;
1168  }
1169  ;
1170 
1171 struct_declarator
1172  : declarator { $$ = $1; }
1173 /* bitfields
1174  | ':' constant_expression
1175  | declarator ':' constant_expression
1176 */
1177  ;
1178 
1179 enum_identifier
1180  : TOKEN_IDENTIFIER { $$ = strdup(yytext); }
1181 
1182 enum_specifier
1183  : TOKEN_ENUM '{' enumerator_list '}'
1184  {
1185  $$ = lCreateEnumType(NULL, $3, @1);
1186  }
1187  | TOKEN_ENUM enum_identifier '{' enumerator_list '}'
1188  {
1189  $$ = lCreateEnumType($2, $4, @2);
1190  }
1191  | TOKEN_ENUM '{' enumerator_list ',' '}'
1192  {
1193  $$ = lCreateEnumType(NULL, $3, @1);
1194  }
1195  | TOKEN_ENUM enum_identifier '{' enumerator_list ',' '}'
1196  {
1197  $$ = lCreateEnumType($2, $4, @2);
1198  }
1199  | TOKEN_ENUM enum_identifier
1200  {
1201  const Type *type = m->symbolTable->LookupType($2);
1202  if (type == NULL) {
1203  std::vector<std::string> alternates = m->symbolTable->ClosestEnumTypeMatch($2);
1204  std::string alts = lGetAlternates(alternates);
1205  Error(@2, "Enum type \"%s\" unknown.%s", $2, alts.c_str());
1206  $$ = NULL;
1207  }
1208  else {
1209  const EnumType *enumType = CastType<EnumType>(type);
1210  if (enumType == NULL) {
1211  Error(@2, "Type \"%s\" is not an enum type (%s).", $2,
1212  type->GetString().c_str());
1213  $$ = NULL;
1214  }
1215  else
1216  $$ = enumType;
1217  }
1218  }
1219  ;
1220 
1221 enumerator_list
1222  : enumerator
1223  {
1224  if ($1 == NULL)
1225  $$ = NULL;
1226  else {
1227  std::vector<Symbol *> *el = new std::vector<Symbol *>;
1228  el->push_back($1);
1229  $$ = el;
1230  }
1231  }
1232  | enumerator_list ',' enumerator
1233  {
1234  std::vector<Symbol *> *symList = $1;
1235  if (symList == NULL) {
1236  AssertPos(@1, m->errorCount > 0);
1237  symList = new std::vector<Symbol *>;
1238  }
1239  if ($3 != NULL)
1240  symList->push_back($3);
1241  $$ = symList;
1242  }
1243  ;
1244 
1245 enumerator
1246  : enum_identifier
1247  {
1248  $$ = new Symbol($1, @1);
1249  }
1250  | enum_identifier '=' constant_expression
1251  {
1252  int value;
1253  if ($1 != NULL && $3 != NULL &&
1254  lGetConstantInt($3, &value, @3, "Enumerator value")) {
1255  Symbol *sym = new Symbol($1, @1);
1256  sym->constValue = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
1257  (uint32_t)value, @3);
1258  $$ = sym;
1259  }
1260  else
1261  $$ = NULL;
1262  }
1263  ;
1264 
1265 type_qualifier
1266  : TOKEN_CONST { $$ = TYPEQUAL_CONST; }
1267  | TOKEN_UNIFORM { $$ = TYPEQUAL_UNIFORM; }
1268  | TOKEN_VARYING { $$ = TYPEQUAL_VARYING; }
1269  | TOKEN_TASK { $$ = TYPEQUAL_TASK; }
1270  | TOKEN_UNMASKED { $$ = TYPEQUAL_UNMASKED; }
1271  | TOKEN_EXPORT { $$ = TYPEQUAL_EXPORT; }
1272  | TOKEN_INLINE { $$ = TYPEQUAL_INLINE; }
1273  | TOKEN_SIGNED { $$ = TYPEQUAL_SIGNED; }
1274  | TOKEN_UNSIGNED { $$ = TYPEQUAL_UNSIGNED; }
1275  ;
1276 
1277 type_qualifier_list
1278  : type_qualifier
1279  {
1280  $$ = $1;
1281  }
1282  | type_qualifier_list type_qualifier
1283  {
1284  $$ = $1 | $2;
1285  }
1286  ;
1287 
1288 declarator
1289  : pointer direct_declarator
1290  {
1291  if ($1 != NULL) {
1292  Declarator *tail = $1;
1293  while (tail->child != NULL)
1294  tail = tail->child;
1295  tail->child = $2;
1296  $$ = $1;
1297  }
1298  else
1299  $$ = NULL;
1300  }
1301  | reference direct_declarator
1302  {
1303  if ($1 != NULL) {
1304  Declarator *tail = $1;
1305  while (tail->child != NULL)
1306  tail = tail->child;
1307  tail->child = $2;
1308  $$ = $1;
1309  }
1310  else
1311  $$ = NULL;
1312  }
1313  | direct_declarator
1314  ;
1315 
1316 int_constant
1317  : TOKEN_INT8_CONSTANT { $$ = yylval.intVal; }
1318  | TOKEN_INT16_CONSTANT { $$ = yylval.intVal; }
1319  | TOKEN_INT32_CONSTANT { $$ = yylval.intVal; }
1320  | TOKEN_INT64_CONSTANT { $$ = yylval.intVal; }
1321  ;
1322 
1323 direct_declarator
1324  : TOKEN_IDENTIFIER
1325  {
1326  Declarator *d = new Declarator(DK_BASE, @1);
1327  d->name = yytext;
1328  $$ = d;
1329  }
1330  | '(' declarator ')'
1331  {
1332  $$ = $2;
1333  }
1334  | direct_declarator '[' constant_expression ']'
1335  {
1336  int size;
1337  if ($1 != NULL && lGetConstantInt($3, &size, @3, "Array dimension")) {
1338  if (size < 0) {
1339  Error(@3, "Array dimension must be non-negative.");
1340  $$ = NULL;
1341  }
1342  else {
1343  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @4));
1344  d->arraySize = size;
1345  d->child = $1;
1346  $$ = d;
1347  }
1348  }
1349  else
1350  $$ = NULL;
1351  }
1352  | direct_declarator '[' ']'
1353  {
1354  if ($1 != NULL) {
1355  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @3));
1356  d->arraySize = 0; // unsize
1357  d->child = $1;
1358  $$ = d;
1359  }
1360  else
1361  $$ = NULL;
1362  }
1363  | direct_declarator '[' error ']'
1364  {
1365  $$ = NULL;
1366  }
1367  | direct_declarator '(' parameter_type_list ')'
1368  {
1369  if ($1 != NULL) {
1370  Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @4));
1371  d->child = $1;
1372  if ($3 != NULL)
1373  d->functionParams = *$3;
1374  $$ = d;
1375  }
1376  else
1377  $$ = NULL;
1378  }
1379  | direct_declarator '(' ')'
1380  {
1381  if ($1 != NULL) {
1382  Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @3));
1383  d->child = $1;
1384  $$ = d;
1385  }
1386  else
1387  $$ = NULL;
1388  }
1389  | direct_declarator '(' error ')'
1390  {
1391  $$ = NULL;
1392  }
1393  ;
1394 
1395 
1396 pointer
1397  : '*'
1398  {
1399  $$ = new Declarator(DK_POINTER, @1);
1400  }
1401  | '*' type_qualifier_list
1402  {
1403  Declarator *d = new Declarator(DK_POINTER, Union(@1, @2));
1404  d->typeQualifiers = $2;
1405  $$ = d;
1406  }
1407  | '*' pointer
1408  {
1409  Declarator *d = new Declarator(DK_POINTER, Union(@1, @2));
1410  d->child = $2;
1411  $$ = d;
1412  }
1413  | '*' type_qualifier_list pointer
1414  {
1415  Declarator *d = new Declarator(DK_POINTER, Union(@1, @3));
1416  d->typeQualifiers = $2;
1417  d->child = $3;
1418  $$ = d;
1419  }
1420  ;
1421 
1422 
1423 reference
1424  : '&'
1425  {
1426  $$ = new Declarator(DK_REFERENCE, @1);
1427  }
1428  ;
1429 
1430 
1431 parameter_type_list
1432  : parameter_list { $$ = $1; }
1433  ;
1434 
1435 parameter_list
1436  : parameter_declaration
1437  {
1438  std::vector<Declaration *> *dl = new std::vector<Declaration *>;
1439  if ($1 != NULL)
1440  dl->push_back($1);
1441  $$ = dl;
1442  }
1443  | parameter_list ',' parameter_declaration
1444  {
1445  std::vector<Declaration *> *dl = (std::vector<Declaration *> *)$1;
1446  if (dl == NULL)
1447  dl = new std::vector<Declaration *>;
1448  if ($3 != NULL)
1449  dl->push_back($3);
1450  $$ = dl;
1451  }
1452  | error ','
1453  {
1454  lSuggestParamListAlternates();
1455  $$ = NULL;
1456  }
1457  ;
1458 
1459 parameter_declaration
1460  : declaration_specifiers declarator
1461  {
1462  $$ = new Declaration($1, $2);
1463  }
1464  | declaration_specifiers declarator '=' initializer
1465  {
1466  if ($1 != NULL && $2 != NULL) {
1467  $2->initExpr = $4;
1468  $$ = new Declaration($1, $2);
1469  }
1470  else
1471  $$ = NULL;
1472  }
1473  | declaration_specifiers abstract_declarator
1474  {
1475  if ($1 != NULL && $2 != NULL)
1476  $$ = new Declaration($1, $2);
1477  else
1478  $$ = NULL;
1479  }
1480  | declaration_specifiers
1481  {
1482  if ($1 == NULL)
1483  $$ = NULL;
1484  else
1485  $$ = new Declaration($1);
1486  }
1487  ;
1488 
1489 /* K&R?
1490 identifier_list
1491  : IDENTIFIER
1492  | identifier_list ',' IDENTIFIER
1493  ;
1494 */
1495 
1496 type_name
1497  : specifier_qualifier_list
1498  | specifier_qualifier_list abstract_declarator
1499  {
1500  if ($1 == NULL || $2 == NULL)
1501  $$ = NULL;
1502  else {
1503  $2->InitFromType($1, NULL);
1504  $$ = $2->type;
1505  }
1506  }
1507  ;
1508 
1509 abstract_declarator
1510  : pointer
1511  {
1512  $$ = $1;
1513  }
1514  | direct_abstract_declarator
1515  | pointer direct_abstract_declarator
1516  {
1517  if ($2 == NULL)
1518  $$ = NULL;
1519  else {
1520  Declarator *d = new Declarator(DK_POINTER, Union(@1, @2));
1521  d->child = $2;
1522  $$ = d;
1523  }
1524  }
1525  | reference
1526  {
1527  $$ = new Declarator(DK_REFERENCE, @1);
1528  }
1529  | reference direct_abstract_declarator
1530  {
1531  if ($2 == NULL)
1532  $$ = NULL;
1533  else {
1534  Declarator *d = new Declarator(DK_REFERENCE, Union(@1, @2));
1535  d->child = $2;
1536  $$ = d;
1537  }
1538  }
1539  ;
1540 
1541 direct_abstract_declarator
1542  : '(' abstract_declarator ')'
1543  { $$ = $2; }
1544  | '[' ']'
1545  {
1546  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @2));
1547  d->arraySize = 0;
1548  $$ = d;
1549  }
1550  | '[' constant_expression ']'
1551  {
1552  int size;
1553  if ($2 != NULL && lGetConstantInt($2, &size, @2, "Array dimension")) {
1554  if (size < 0) {
1555  Error(@2, "Array dimension must be non-negative.");
1556  $$ = NULL;
1557  }
1558  else {
1559  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @3));
1560  d->arraySize = size;
1561  $$ = d;
1562  }
1563  }
1564  else
1565  $$ = NULL;
1566  }
1567  | direct_abstract_declarator '[' ']'
1568  {
1569  if ($1 == NULL)
1570  $$ = NULL;
1571  else {
1572  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @3));
1573  d->arraySize = 0;
1574  d->child = $1;
1575  $$ = d;
1576  }
1577  }
1578  | direct_abstract_declarator '[' constant_expression ']'
1579  {
1580  int size;
1581  if ($1 != NULL && $3 != NULL && lGetConstantInt($3, &size, @3, "Array dimension")) {
1582  if (size < 0) {
1583  Error(@3, "Array dimension must be non-negative.");
1584  $$ = NULL;
1585  }
1586  else {
1587  Declarator *d = new Declarator(DK_ARRAY, Union(@1, @4));
1588  d->arraySize = size;
1589  d->child = $1;
1590  $$ = d;
1591  }
1592  }
1593  else
1594  $$ = NULL;
1595  }
1596  | '(' ')'
1597  { $$ = new Declarator(DK_FUNCTION, Union(@1, @2)); }
1598  | '(' parameter_type_list ')'
1599  {
1600  Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @3));
1601  if ($2 != NULL) d->functionParams = *$2;
1602  $$ = d;
1603  }
1604  | direct_abstract_declarator '(' ')'
1605  {
1606  if ($1 == NULL)
1607  $$ = NULL;
1608  else {
1609  Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @3));
1610  d->child = $1;
1611  $$ = d;
1612  }
1613  }
1614  | direct_abstract_declarator '(' parameter_type_list ')'
1615  {
1616  if ($1 == NULL)
1617  $$ = NULL;
1618  else {
1619  Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @4));
1620  d->child = $1;
1621  if ($3 != NULL) d->functionParams = *$3;
1622  $$ = d;
1623  }
1624  }
1625  ;
1626 
1627 initializer
1628  : assignment_expression
1629  | '{' initializer_list '}' { $$ = $2; }
1630  | '{' initializer_list ',' '}' { $$ = $2; }
1631  ;
1632 
1633 initializer_list
1634  : initializer
1635  { $$ = new ExprList($1, @1); }
1636  | initializer_list ',' initializer
1637  {
1638  ExprList *exprList = $1;
1639  if (exprList == NULL) {
1640  AssertPos(@1, m->errorCount > 0);
1641  exprList = new ExprList(@3);
1642  }
1643  exprList->exprs.push_back($3);
1644  exprList->pos = Union(exprList->pos, @3);
1645  $$ = exprList;
1646  }
1647  ;
1648 
1649 statement
1650  : labeled_statement
1651  | compound_statement
1652  | expression_statement
1653  | selection_statement
1654  | iteration_statement
1655  | jump_statement
1656  | declaration_statement
1657  | print_statement
1658  | assert_statement
1659  | sync_statement
1660  | delete_statement
1661  | unmasked_statement
1662  | error ';'
1663  {
1664  lSuggestBuiltinAlternates();
1665  $$ = NULL;
1666  }
1667  ;
1668 
1669 labeled_statement
1670  : goto_identifier ':' statement
1671  {
1672  $$ = new LabeledStmt($1, $3, @1);
1673  }
1674  | TOKEN_CASE constant_expression ':' statement
1675  {
1676  int value;
1677  if ($2 != NULL &&
1678  lGetConstantInt($2, &value, @2, "Case statement value")) {
1679  $$ = new CaseStmt(value, $4, Union(@1, @2));
1680  }
1681  else
1682  $$ = NULL;
1683  }
1684  | TOKEN_DEFAULT ':' statement
1685  { $$ = new DefaultStmt($3, @1); }
1686  ;
1687 
1688 start_scope
1689  : '{' { m->symbolTable->PushScope(); }
1690  ;
1691 
1692 end_scope
1693  : '}' { m->symbolTable->PopScope(); }
1694  ;
1695 
1696 compound_statement
1697  : '{' '}' { $$ = NULL; }
1698  | start_scope statement_list end_scope { $$ = $2; }
1699  ;
1700 
1701 statement_list
1702  : statement
1703  {
1704  StmtList *sl = new StmtList(@1);
1705  sl->Add($1);
1706  $$ = sl;
1707  }
1708  | statement_list statement
1709  {
1710  StmtList *sl = (StmtList *)$1;
1711  if (sl == NULL) {
1712  AssertPos(@1, m->errorCount > 0);
1713  sl = new StmtList(@2);
1714  }
1715  sl->Add($2);
1716  $$ = sl;
1717  }
1718  ;
1719 
1720 expression_statement
1721  : ';' { $$ = NULL; }
1722  | expression ';' { $$ = $1 ? new ExprStmt($1, @1) : NULL; }
1723  ;
1724 
1725 selection_statement
1726  : TOKEN_IF '(' expression ')' statement
1727  { $$ = new IfStmt($3, $5, NULL, false, @1); }
1728  | TOKEN_IF '(' expression ')' statement TOKEN_ELSE statement
1729  { $$ = new IfStmt($3, $5, $7, false, @1); }
1730  | TOKEN_CIF '(' expression ')' statement
1731  { $$ = new IfStmt($3, $5, NULL, true, @1); }
1732  | TOKEN_CIF '(' expression ')' statement TOKEN_ELSE statement
1733  { $$ = new IfStmt($3, $5, $7, true, @1); }
1734  | TOKEN_SWITCH '(' expression ')' statement
1735  { $$ = new SwitchStmt($3, $5, @1); }
1736  ;
1737 
1738 for_test
1739  : ';'
1740  { $$ = NULL; }
1741  | expression ';'
1742  { $$ = $1; }
1743  ;
1744 
1745 for_init_statement
1746  : expression_statement
1747  | declaration_statement
1748  ;
1749 
1750 for_scope
1751  : TOKEN_FOR { m->symbolTable->PushScope(); }
1752  ;
1753 
1754 cfor_scope
1755  : TOKEN_CFOR { m->symbolTable->PushScope(); }
1756  ;
1757 
1758 foreach_scope
1759  : TOKEN_FOREACH { m->symbolTable->PushScope(); }
1760  ;
1761 
1762 foreach_tiled_scope
1763  : TOKEN_FOREACH_TILED { m->symbolTable->PushScope(); }
1764  ;
1765 
1766 foreach_identifier
1767  : TOKEN_IDENTIFIER
1768  {
1769  $$ = new Symbol(yytext, @1, AtomicType::VaryingInt32->GetAsConstType());
1770  }
1771  ;
1772 
1773 foreach_active_scope
1774  : TOKEN_FOREACH_ACTIVE { m->symbolTable->PushScope(); }
1775  ;
1776 
1777 foreach_active_identifier
1778  : TOKEN_IDENTIFIER
1779  {
1780  $$ = new Symbol(yytext, @1, AtomicType::UniformInt64->GetAsConstType());
1781  }
1782  ;
1783 
1784 integer_dotdotdot
1785  : TOKEN_INT32DOTDOTDOT_CONSTANT {
1786  $$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
1787  (int32_t)yylval.intVal, @1);
1788  }
1789  | TOKEN_UINT32DOTDOTDOT_CONSTANT {
1790  $$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
1791  (uint32_t)yylval.intVal, @1);
1792  }
1793  | TOKEN_INT64DOTDOTDOT_CONSTANT {
1794  $$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
1795  (int64_t)yylval.intVal, @1);
1796  }
1797  | TOKEN_UINT64DOTDOTDOT_CONSTANT {
1798  $$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
1799  (uint64_t)yylval.intVal, @1);
1800  }
1801  ;
1802 
1803 foreach_dimension_specifier
1804  : foreach_identifier '=' assignment_expression TOKEN_DOTDOTDOT assignment_expression
1805  {
1806  $$ = new ForeachDimension($1, $3, $5);
1807  }
1808  | foreach_identifier '=' integer_dotdotdot assignment_expression
1809  {
1810  $$ = new ForeachDimension($1, $3, $4);
1811  }
1812  ;
1813 
1814 foreach_dimension_list
1815  : foreach_dimension_specifier
1816  {
1817  $$ = new std::vector<ForeachDimension *>;
1818  $$->push_back($1);
1819  }
1820  | foreach_dimension_list ',' foreach_dimension_specifier
1821  {
1822  std::vector<ForeachDimension *> *dv = $1;
1823  if (dv == NULL) {
1824  AssertPos(@1, m->errorCount > 0);
1825  dv = new std::vector<ForeachDimension *>;
1826  }
1827  if ($3 != NULL)
1828  dv->push_back($3);
1829  $$ = dv;
1830  }
1831  ;
1832 
1833 foreach_unique_scope
1834  : TOKEN_FOREACH_UNIQUE { m->symbolTable->PushScope(); }
1835  ;
1836 
1837 foreach_unique_identifier
1838  : TOKEN_IDENTIFIER { $$ = yylval.stringVal->c_str(); }
1839  ;
1840 
1841 iteration_statement
1842  : TOKEN_WHILE '(' expression ')' statement
1843  { $$ = new ForStmt(NULL, $3, NULL, $5, false, @1); }
1844  | TOKEN_CWHILE '(' expression ')' statement
1845  { $$ = new ForStmt(NULL, $3, NULL, $5, true, @1); }
1846  | TOKEN_DO statement TOKEN_WHILE '(' expression ')' ';'
1847  { $$ = new DoStmt($5, $2, false, @1); }
1848  | TOKEN_CDO statement TOKEN_WHILE '(' expression ')' ';'
1849  { $$ = new DoStmt($5, $2, true, @1); }
1850  | for_scope '(' for_init_statement for_test ')' statement
1851  { $$ = new ForStmt($3, $4, NULL, $6, false, @1);
1852  m->symbolTable->PopScope();
1853  }
1854  | for_scope '(' for_init_statement for_test expression ')' statement
1855  { $$ = new ForStmt($3, $4, new ExprStmt($5, @5), $7, false, @1);
1856  m->symbolTable->PopScope();
1857  }
1858  | cfor_scope '(' for_init_statement for_test ')' statement
1859  { $$ = new ForStmt($3, $4, NULL, $6, true, @1);
1860  m->symbolTable->PopScope();
1861  }
1862  | cfor_scope '(' for_init_statement for_test expression ')' statement
1863  { $$ = new ForStmt($3, $4, new ExprStmt($5, @5), $7, true, @1);
1864  m->symbolTable->PopScope();
1865  }
1866  | foreach_scope '(' foreach_dimension_list ')'
1867  {
1868  std::vector<ForeachDimension *> *dims = $3;
1869  if (dims == NULL) {
1870  AssertPos(@3, m->errorCount > 0);
1871  dims = new std::vector<ForeachDimension *>;
1872  }
1873  for (unsigned int i = 0; i < dims->size(); ++i)
1874  m->symbolTable->AddVariable((*dims)[i]->sym);
1875  }
1876  statement
1877  {
1878  std::vector<ForeachDimension *> *dims = $3;
1879  if (dims == NULL) {
1880  AssertPos(@3, m->errorCount > 0);
1881  dims = new std::vector<ForeachDimension *>;
1882  }
1883 
1884  std::vector<Symbol *> syms;
1885  std::vector<Expr *> begins, ends;
1886  for (unsigned int i = 0; i < dims->size(); ++i) {
1887  syms.push_back((*dims)[i]->sym);
1888  begins.push_back((*dims)[i]->beginExpr);
1889  ends.push_back((*dims)[i]->endExpr);
1890  }
1891  $$ = new ForeachStmt(syms, begins, ends, $6, false, @1);
1892  m->symbolTable->PopScope();
1893  }
1894  | foreach_tiled_scope '(' foreach_dimension_list ')'
1895  {
1896  std::vector<ForeachDimension *> *dims = $3;
1897  if (dims == NULL) {
1898  AssertPos(@3, m->errorCount > 0);
1899  dims = new std::vector<ForeachDimension *>;
1900  }
1901 
1902  for (unsigned int i = 0; i < dims->size(); ++i)
1903  m->symbolTable->AddVariable((*dims)[i]->sym);
1904  }
1905  statement
1906  {
1907  std::vector<ForeachDimension *> *dims = $3;
1908  if (dims == NULL) {
1909  AssertPos(@1, m->errorCount > 0);
1910  dims = new std::vector<ForeachDimension *>;
1911  }
1912 
1913  std::vector<Symbol *> syms;
1914  std::vector<Expr *> begins, ends;
1915  for (unsigned int i = 0; i < dims->size(); ++i) {
1916  syms.push_back((*dims)[i]->sym);
1917  begins.push_back((*dims)[i]->beginExpr);
1918  ends.push_back((*dims)[i]->endExpr);
1919  }
1920  $$ = new ForeachStmt(syms, begins, ends, $6, true, @1);
1921  m->symbolTable->PopScope();
1922  }
1923  | foreach_active_scope '(' foreach_active_identifier ')'
1924  {
1925  if ($3 != NULL)
1926  m->symbolTable->AddVariable($3);
1927  }
1928  statement
1929  {
1930  $$ = new ForeachActiveStmt($3, $6, Union(@1, @4));
1931  m->symbolTable->PopScope();
1932  }
1933  | foreach_unique_scope '(' foreach_unique_identifier TOKEN_IN
1934  expression ')'
1935  {
1936  Expr *expr = $5;
1937  const Type *type;
1938  if (expr != NULL &&
1939  (expr = TypeCheck(expr)) != NULL &&
1940  (type = expr->GetType()) != NULL) {
1941  const Type *iterType = type->GetAsUniformType()->GetAsConstType();
1942  Symbol *sym = new Symbol($3, @3, iterType);
1943  m->symbolTable->AddVariable(sym);
1944  }
1945  }
1946  statement
1947  {
1948  $$ = new ForeachUniqueStmt($3, $5, $8, @1);
1949  m->symbolTable->PopScope();
1950  }
1951  ;
1952 
1953 goto_identifier
1954  : TOKEN_IDENTIFIER { $$ = yylval.stringVal->c_str(); }
1955  ;
1956 
1957 jump_statement
1958  : TOKEN_GOTO goto_identifier ';'
1959  { $$ = new GotoStmt($2, @1, @2); }
1960  | TOKEN_CONTINUE ';'
1961  { $$ = new ContinueStmt(@1); }
1962  | TOKEN_BREAK ';'
1963  { $$ = new BreakStmt(@1); }
1964  | TOKEN_RETURN ';'
1965  { $$ = new ReturnStmt(NULL, @1); }
1966  | TOKEN_RETURN expression ';'
1967  { $$ = new ReturnStmt($2, @1); }
1968  ;
1969 
1970 sync_statement
1971  : TOKEN_SYNC ';'
1972  { $$ = new ExprStmt(new SyncExpr(@1), @1); }
1973  ;
1974 
1975 delete_statement
1976  : TOKEN_DELETE expression ';'
1977  {
1978  $$ = new DeleteStmt($2, Union(@1, @2));
1979  }
1980  ;
1981 
1982 unmasked_statement
1983  : TOKEN_UNMASKED '{' statement_list '}'
1984  {
1985  $$ = new UnmaskedStmt($3, @1);
1986  }
1987  ;
1988 
1989 print_statement
1990  : TOKEN_PRINT '(' string_constant ')' ';'
1991  {
1992  $$ = new PrintStmt(*$3, NULL, @1);
1993  }
1994  | TOKEN_PRINT '(' string_constant ',' argument_expression_list ')' ';'
1995  {
1996  $$ = new PrintStmt(*$3, $5, @1);
1997  }
1998  ;
1999 
2000 assert_statement
2001  : TOKEN_ASSERT '(' string_constant ',' expression ')' ';'
2002  {
2003  $$ = new AssertStmt(*$3, $5, @1);
2004  }
2005  ;
2006 
2007 translation_unit
2008  : external_declaration
2009  | translation_unit external_declaration
2010  | error ';'
2011  ;
2012 
2013 external_declaration
2014  : function_definition
2015  | TOKEN_EXTERN TOKEN_STRING_C_LITERAL '{' declaration '}'
2016  | TOKEN_EXPORT '{' type_specifier_list '}' ';'
2017  {
2018  if ($3 != NULL)
2019  m->AddExportedTypes(*$3);
2020  }
2021  | declaration
2022  {
2023  if ($1 != NULL)
2024  for (unsigned int i = 0; i < $1->declarators.size(); ++i)
2025  lAddDeclaration($1->declSpecs, $1->declarators[i]);
2026  }
2027  | ';'
2028  ;
2029 
2030 function_definition
2031  : declaration_specifiers declarator
2032  {
2033  lAddDeclaration($1, $2);
2034  lAddFunctionParams($2);
2035  lAddMaskToSymbolTable(@2);
2036  if ($1->typeQualifiers & TYPEQUAL_TASK)
2037  lAddThreadIndexCountToSymbolTable(@2);
2038  }
2039  compound_statement
2040  {
2041  if ($2 != NULL) {
2042  $2->InitFromDeclSpecs($1);
2043  const FunctionType *funcType = CastType<FunctionType>($2->type);
2044  if (funcType == NULL)
2045  AssertPos(@1, m->errorCount > 0);
2046  else if ($1->storageClass == SC_TYPEDEF)
2047  Error(@1, "Illegal \"typedef\" provided with function definition.");
2048  else {
2049  Stmt *code = $4;
2050  if (code == NULL) code = new StmtList(@4);
2051  m->AddFunctionDefinition($2->name, funcType, code);
2052  }
2053  }
2054  m->symbolTable->PopScope(); // push in lAddFunctionParams();
2055  }
2056 /* function with no declared return type??
2057 func(...)
2058  | declarator { lAddFunctionParams($1); } compound_statement
2059  {
2060  m->AddFunction(new DeclSpecs(XXX, $1, $3);
2061  m->symbolTable->PopScope(); // push in lAddFunctionParams();
2062  }
2063 */
2064  ;
2065 
2066 %%
2067 
2068 
2069 void yyerror(const char *s) {
2070  if (strlen(yytext) == 0)
2071  Error(yylloc, "Premature end of file: %s.", s);
2072  else
2073  Error(yylloc, "%s.", s);
2074 }
2075 
2076 
2077 static int
2078 lYYTNameErr (char *yyres, const char *yystr)
2079 {
2080  extern std::map<std::string, std::string> tokenNameRemap;
2081  Assert(tokenNameRemap.size() > 0);
2082  if (tokenNameRemap.find(yystr) != tokenNameRemap.end()) {
2083  std::string n = tokenNameRemap[yystr];
2084  if (yyres == NULL)
2085  return n.size();
2086  else
2087  return yystpcpy(yyres, n.c_str()) - yyres;
2088  }
2089 
2090  if (*yystr == '"')
2091  {
2092  YYSIZE_T yyn = 0;
2093  char const *yyp = yystr;
2094 
2095  for (;;)
2096  switch (*++yyp)
2097  {
2098  case '\'':
2099  case ',':
2100  goto do_not_strip_quotes;
2101 
2102  case '\\':
2103  if (*++yyp != '\\')
2104  goto do_not_strip_quotes;
2105  /* Fall through. */
2106  default:
2107  if (yyres)
2108  yyres[yyn] = *yyp;
2109  yyn++;
2110  break;
2111 
2112  case '"':
2113  if (yyres)
2114  yyres[yyn] = '\0';
2115  return yyn;
2116  }
2117  do_not_strip_quotes: ;
2118  }
2119 
2120  if (! yyres)
2121  return yystrlen (yystr);
2122 
2123  return yystpcpy (yyres, yystr) - yyres;
2124 }
2125 
2126 static void
2127 lSuggestBuiltinAlternates() {
2128  std::vector<std::string> builtinTokens;
2129  const char **token = lBuiltinTokens;
2130  while (*token) {
2131  builtinTokens.push_back(*token);
2132  ++token;
2133  }
2134  std::vector<std::string> alternates = MatchStrings(yytext, builtinTokens);
2135  std::string alts = lGetAlternates(alternates);
2136  if (alts.size() > 0)
2137  Error(yylloc, "%s", alts.c_str());
2138 }
2139 
2140 
2141 static void
2142 lSuggestParamListAlternates() {
2143  std::vector<std::string> builtinTokens;
2144  const char **token = lParamListTokens;
2145  while (*token) {
2146  builtinTokens.push_back(*token);
2147  ++token;
2148  }
2149  std::vector<std::string> alternates = MatchStrings(yytext, builtinTokens);
2150  std::string alts = lGetAlternates(alternates);
2151  if (alts.size() > 0)
2152  Error(yylloc, "%s", alts.c_str());
2153 }
2154 
2155 
2156 static void
2157 lAddDeclaration(DeclSpecs *ds, Declarator *decl) {
2158  if (ds == NULL || decl == NULL)
2159  // Error happened earlier during parsing
2160  return;
2161 
2162  decl->InitFromDeclSpecs(ds);
2163  if (ds->storageClass == SC_TYPEDEF)
2164  m->AddTypeDef(decl->name, decl->type, decl->pos);
2165  else {
2166  if (decl->type == NULL) {
2167  Assert(m->errorCount > 0);
2168  return;
2169  }
2170 
2171  decl->type = decl->type->ResolveUnboundVariability(Variability::Varying);
2172 
2173  const FunctionType *ft = CastType<FunctionType>(decl->type);
2174  if (ft != NULL) {
2175  bool isInline = (ds->typeQualifiers & TYPEQUAL_INLINE);
2176  m->AddFunctionDeclaration(decl->name, ft, ds->storageClass,
2177  isInline, decl->pos);
2178  }
2179  else {
2180  bool isConst = (ds->typeQualifiers & TYPEQUAL_CONST) != 0;
2181  m->AddGlobalVariable(decl->name, decl->type, decl->initExpr,
2182  isConst, decl->storageClass, decl->pos);
2183  }
2184  }
2185 }
2186 
2187 
2188 /** We're about to start parsing the body of a function; add all of the
2189  parameters to the symbol table so that they're available.
2190 */
2191 static void
2192 lAddFunctionParams(Declarator *decl) {
2193  m->symbolTable->PushScope();
2194 
2195  if (decl == NULL) {
2196  AssertPos(decl->pos, m->errorCount > 0);
2197  return;
2198  }
2199 
2200  // walk down to the declarator for the function itself
2201  while (decl->kind != DK_FUNCTION && decl->child != NULL)
2202  decl = decl->child;
2203  if (decl->kind != DK_FUNCTION) {
2204  AssertPos(decl->pos, m->errorCount > 0);
2205  return;
2206  }
2207 
2208  // now loop over its parameters and add them to the symbol table
2209  for (unsigned int i = 0; i < decl->functionParams.size(); ++i) {
2210  Declaration *pdecl = decl->functionParams[i];
2211  Assert(pdecl != NULL && pdecl->declarators.size() == 1);
2212  Declarator *declarator = pdecl->declarators[0];
2213  if (declarator == NULL)
2214  AssertPos(decl->pos, m->errorCount > 0);
2215  else {
2216  Symbol *sym = new Symbol(declarator->name, declarator->pos,
2217  declarator->type, declarator->storageClass);
2218 #ifndef NDEBUG
2219  bool ok = m->symbolTable->AddVariable(sym);
2220  if (ok == false)
2221  AssertPos(decl->pos, m->errorCount > 0);
2222 #else
2223  m->symbolTable->AddVariable(sym);
2224 #endif
2225  }
2226  }
2227 
2228  // The corresponding pop scope happens in function_definition rules
2229  // above...
2230 }
2231 
2232 
2233 /** Add a symbol for the built-in mask variable to the symbol table */
2234 static void lAddMaskToSymbolTable(SourcePos pos) {
2235  const Type *t = NULL;
2236  switch (g->target->getMaskBitCount()) {
2237  case 1:
2238  t = AtomicType::VaryingBool;
2239  break;
2240  case 8:
2241  t = AtomicType::VaryingUInt8;
2242  break;
2243  case 16:
2244  t = AtomicType::VaryingUInt16;
2245  break;
2246  case 32:
2247  t = AtomicType::VaryingUInt32;
2248  break;
2249  case 64:
2250  t = AtomicType::VaryingUInt64;
2251  break;
2252  default:
2253  FATAL("Unhandled mask bitsize in lAddMaskToSymbolTable");
2254  }
2255 
2256  t = t->GetAsConstType();
2257  Symbol *maskSymbol = new Symbol("__mask", pos, t);
2258  m->symbolTable->AddVariable(maskSymbol);
2259 }
2260 
2261 
2262 /** Add the thread index and thread count variables to the symbol table
2263  (this should only be done for 'task'-qualified functions. */
2264 static void lAddThreadIndexCountToSymbolTable(SourcePos pos) {
2265  const Type *type = AtomicType::UniformUInt32->GetAsConstType();
2266 
2267  Symbol *threadIndexSym = new Symbol("threadIndex", pos, type);
2268  m->symbolTable->AddVariable(threadIndexSym);
2269 
2270  Symbol *threadCountSym = new Symbol("threadCount", pos, type);
2271  m->symbolTable->AddVariable(threadCountSym);
2272 
2273  Symbol *taskIndexSym = new Symbol("taskIndex", pos, type);
2274  m->symbolTable->AddVariable(taskIndexSym);
2275 
2276  Symbol *taskCountSym = new Symbol("taskCount", pos, type);
2277  m->symbolTable->AddVariable(taskCountSym);
2278 
2279  Symbol *taskIndexSym0 = new Symbol("taskIndex0", pos, type);
2280  m->symbolTable->AddVariable(taskIndexSym0);
2281  Symbol *taskIndexSym1 = new Symbol("taskIndex1", pos, type);
2282  m->symbolTable->AddVariable(taskIndexSym1);
2283  Symbol *taskIndexSym2 = new Symbol("taskIndex2", pos, type);
2284  m->symbolTable->AddVariable(taskIndexSym2);
2285 
2286 
2287  Symbol *taskCountSym0 = new Symbol("taskCount0", pos, type);
2288  m->symbolTable->AddVariable(taskCountSym0);
2289  Symbol *taskCountSym1 = new Symbol("taskCount1", pos, type);
2290  m->symbolTable->AddVariable(taskCountSym1);
2291  Symbol *taskCountSym2 = new Symbol("taskCount2", pos, type);
2292  m->symbolTable->AddVariable(taskCountSym2);
2293 }
2294 
2295 
2296 /** Small utility routine to construct a string for error messages that
2297  suggests alternate tokens for possibly-misspelled ones... */
2298 static std::string lGetAlternates(std::vector<std::string> &alternates) {
2299  std::string alts;
2300  if (alternates.size()) {
2301  alts += " Did you mean ";
2302  for (unsigned int i = 0; i < alternates.size(); ++i) {
2303  alts += std::string("\"") + alternates[i] + std::string("\"");
2304  if (i < alternates.size() - 1) alts += ", or ";
2305  }
2306  alts += "?";
2307  }
2308  return alts;
2309 }
2310 
2311 static const char *
2312 lGetStorageClassString(StorageClass sc) {
2313  switch (sc) {
2314  case SC_NONE:
2315  return "";
2316  case SC_EXTERN:
2317  return "extern";
2318  case SC_STATIC:
2319  return "static";
2320  case SC_TYPEDEF:
2321  return "typedef";
2322  case SC_EXTERN_C:
2323  return "extern \"C\"";
2324  default:
2325  Assert(!"logic error in lGetStorageClassString()");
2326  return "";
2327  }
2328 }
2329 
2330 
2331 /** Given an expression, see if it is equal to a compile-time constant
2332  integer value. If so, return true and return the value in *value.
2333  If the expression isn't a compile-time constant or isn't an integer
2334  type, return false.
2335 */
2336 static bool
2337 lGetConstantInt(Expr *expr, int *value, SourcePos pos, const char *usage) {
2338  if (expr == NULL)
2339  return false;
2340  expr = TypeCheck(expr);
2341  if (expr == NULL)
2342  return false;
2343  expr = Optimize(expr);
2344  if (expr == NULL)
2345  return false;
2346 
2347  llvm::Constant *cval = expr->GetConstant(expr->GetType());
2348  if (cval == NULL) {
2349  Error(pos, "%s must be a compile-time constant.", usage);
2350  return false;
2351  }
2352  else {
2353  llvm::ConstantInt *ci = llvm::dyn_cast<llvm::ConstantInt>(cval);
2354  if (ci == NULL) {
2355  Error(pos, "%s must be a compile-time integer constant.", usage);
2356  return false;
2357  }
2358  if ((int64_t)((int32_t)ci->getSExtValue()) != ci->getSExtValue()) {
2359  Error(pos, "%s must be representable with a 32-bit integer.", usage);
2360  return false;
2361  }
2362  const Type *type = expr->GetType();
2363  if (type->IsUnsignedType())
2364  *value = (int)ci->getZExtValue();
2365  else
2366  *value = (int)ci->getSExtValue();
2367  return true;
2368  }
2369 }
2370 
2371 
2372 static EnumType *
2373 lCreateEnumType(const char *name, std::vector<Symbol *> *enums, SourcePos pos) {
2374  if (enums == NULL)
2375  return NULL;
2376 
2377  EnumType *enumType = name ? new EnumType(name, pos) : new EnumType(pos);
2378  if (name != NULL)
2379  m->symbolTable->AddType(name, enumType, pos);
2380 
2381  lFinalizeEnumeratorSymbols(*enums, enumType);
2382  for (unsigned int i = 0; i < enums->size(); ++i)
2383  m->symbolTable->AddVariable((*enums)[i]);
2384  enumType->SetEnumerators(*enums);
2385  return enumType;
2386 }
2387 
2388 
2389 /** Given an array of enumerator symbols, make sure each of them has a
2390  ConstExpr * in their Symbol::constValue member that stores their
2391  unsigned integer value. Symbols that had values explicitly provided
2392  in the source file will already have ConstExpr * set; we just need
2393  to set the values for the others here.
2394 */
2395 static void
2396 lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
2397  const EnumType *enumType) {
2398  enumType = enumType->GetAsConstType();
2399  enumType = enumType->GetAsUniformType();
2400 
2401  /* nextVal tracks the value for the next enumerant. It starts from
2402  zero and goes up with each successive enumerant. If any of them
2403  has a value specified, then nextVal is ignored for that one and is
2404  set to one plus that one's value for the default value for the next
2405  one. */
2406  uint32_t nextVal = 0;
2407 
2408  for (unsigned int i = 0; i < enums.size(); ++i) {
2409  enums[i]->type = enumType;
2410  if (enums[i]->constValue != NULL) {
2411  /* Already has a value, so first update nextVal with it. */
2412  int count = enums[i]->constValue->GetValues(&nextVal);
2413  AssertPos(enums[i]->pos, count == 1);
2414  ++nextVal;
2415 
2416  /* When the source file as being parsed, the ConstExpr for any
2417  enumerant with a specified value was set to have unsigned
2418  int32 type, since we haven't created the parent EnumType
2419  by then. Therefore, add a little type cast from uint32 to
2420  the actual enum type here and optimize it, which will have
2421  us end up with a ConstExpr with the desired EnumType... */
2422  Expr *castExpr = new TypeCastExpr(enumType, enums[i]->constValue,
2423  enums[i]->pos);
2424  castExpr = Optimize(castExpr);
2425  enums[i]->constValue = llvm::dyn_cast<ConstExpr>(castExpr);
2426  AssertPos(enums[i]->pos, enums[i]->constValue != NULL);
2427  }
2428  else {
2429  enums[i]->constValue = new ConstExpr(enumType, nextVal++,
2430  enums[i]->pos);
2431  }
2432  }
2433 }