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