Changes in src/Parser/parser.yy [0442f93f:46da46b]
- File:
-
- 1 edited
-
src/Parser/parser.yy (modified) (140 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/parser.yy
r0442f93f r46da46b 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 7 14:32:28 202313 // Update Count : 634112 // Last Modified On : Mon Nov 21 22:34:30 2022 13 // Update Count : 5848 14 14 // 15 15 … … 44 44 45 45 #include <cstdio> 46 #include <sstream>47 46 #include <stack> 48 47 using namespace std; 49 48 50 #include "SynTree/Type.h" // for Type 51 #include "DeclarationNode.h" // for DeclarationNode, ... 52 #include "ExpressionNode.h" // for ExpressionNode, ... 53 #include "InitializerNode.h" // for InitializerNode, ... 54 #include "ParserTypes.h" 55 #include "StatementNode.h" // for build_... 49 #include "SynTree/Declaration.h" 50 #include "ParseNode.h" 56 51 #include "TypedefTable.h" 57 52 #include "TypeData.h" 53 #include "SynTree/LinkageSpec.h" 58 54 #include "Common/SemanticError.h" // error_str 59 55 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo... 60 56 61 #include "SynTree/Attribute.h" // for Attribute57 #include "SynTree/Attribute.h" // for Attribute 62 58 63 59 // lex uses __null in a boolean context, it's fine. … … 67 63 68 64 extern DeclarationNode * parseTree; 69 extern ast::Linkage::Spec linkage;65 extern LinkageSpec::Spec linkage; 70 66 extern TypedefTable typedefTable; 71 67 72 stack< ast::Linkage::Spec> linkageStack;68 stack<LinkageSpec::Spec> linkageStack; 73 69 74 70 bool appendStr( string & to, string & from ) { … … 108 104 assert( declList ); 109 105 // printf( "distAttr1 typeSpec %p\n", typeSpec ); typeSpec->print( std::cout ); 110 DeclarationNode * c l = (new DeclarationNode)->addType( typeSpec );106 DeclarationNode * cur = declList, * cl = (new DeclarationNode)->addType( typeSpec ); 111 107 // printf( "distAttr2 cl %p\n", cl ); cl->type->print( std::cout ); 112 108 // cl->type->aggregate.name = cl->type->aggInst.aggregate->aggregate.name; 113 109 114 for ( DeclarationNode * cur = dynamic_cast<DeclarationNode *>( declList->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) {110 for ( cur = dynamic_cast<DeclarationNode *>( cur->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) { 115 111 cl->cloneBaseType( cur ); 116 112 } // for … … 203 199 } // fieldDecl 204 200 205 #define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc,*new string( "0" ) ) )206 #define NEW_ONE new ExpressionNode( build_constantInteger( yylloc,*new string( "1" ) ) )201 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) ) 202 #define NEW_ONE new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) 207 203 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right) 208 #define MISSING_ANON_FIELD "syntax error, missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." 209 #define MISSING_LOW "syntax error, missing low value for up-to range so index is uninitialized." 210 #define MISSING_HIGH "syntax error, missing high value for down-to range so index is uninitialized." 211 212 static ForCtrl * makeForCtrl( 213 const CodeLocation & location, 214 DeclarationNode * init, 215 enum OperKinds compop, 216 ExpressionNode * comp, 217 ExpressionNode * inc ) { 218 // Wrap both comp/inc if they are non-null. 219 if ( comp ) comp = new ExpressionNode( build_binary_val( location, 220 compop, 221 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 222 comp ) ); 223 if ( inc ) inc = new ExpressionNode( build_binary_val( location, 224 // choose += or -= for upto/downto 225 compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn, 226 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 227 inc ) ); 228 // The StatementNode call frees init->name, it must happen later. 229 return new ForCtrl( new StatementNode( init ), comp, inc ); 230 } 231 232 ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 204 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." 205 #define MISSING_LOW "Missing low value for up-to range so index is uninitialized." 206 #define MISSING_HIGH "Missing high value for down-to range so index is uninitialized." 207 208 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 233 209 if ( index->initializer ) { 234 SemanticError( yylloc, " syntax error, direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );210 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); 235 211 } // if 236 212 if ( index->next ) { 237 SemanticError( yylloc, " syntax error, multiple loop indexes disallowed in for-loop declaration." );213 SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." ); 238 214 } // if 239 DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) ); 240 return makeForCtrl( location, initDecl, compop, comp, inc ); 215 return new ForCtrl( index->addInitializer( new InitializerNode( start ) ), 216 // NULL comp/inc => leave blank 217 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr, 218 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 219 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr ); 241 220 } // forCtrl 242 221 243 ForCtrl * forCtrl( const CodeLocation & location,ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {244 ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());245 if ( constant && (constant-> rep == "0" || constant->rep== "1") ) {246 type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicType::SignedInt ) ) );222 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 223 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get()); 224 if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) { 225 type = new ExpressionNode( new CastExpr( maybeMoveBuild<Expression>(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) ); 247 226 } // if 248 DeclarationNode * initDecl = distAttr( 249 DeclarationNode::newTypeof( type, true ), 250 DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) 251 ); 252 return makeForCtrl( location, initDecl, compop, comp, inc ); 227 // type = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__for_control_index_constraints__" ) ) ), type ) ); 228 return new ForCtrl( 229 distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ), 230 // NULL comp/inc => leave blank 231 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr, 232 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 233 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr ); 253 234 } // forCtrl 254 235 255 ForCtrl * forCtrl( const CodeLocation & location,ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {256 if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {257 return forCtrl( location,type, new string( identifier->name ), start, compop, comp, inc );258 } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get()) ) {259 if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {260 return forCtrl( location,type, new string( identifier->name ), start, compop, comp, inc );236 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 237 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) { 238 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 239 } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) { 240 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) { 241 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 261 242 } else { 262 SemanticError( yylloc, " syntax error, loop-index name missing. Expression disallowed." ); return nullptr;243 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; 263 244 } // if 264 245 } else { 265 SemanticError( yylloc, " syntax error, loop-index name missing. Expression disallowed.." ); return nullptr;246 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; 266 247 } // if 267 248 } // forCtrl 268 249 269 250 static void IdentifierBeforeIdentifier( string & identifier1, string & identifier2, const char * kind ) { 270 SemanticError( yylloc, ::toString( " syntax error, adjacent identifiers \"", identifier1, "\" and \"", identifier2, "\" are not meaningful in a", kind, ".\n"251 SemanticError( yylloc, ::toString( "Adjacent identifiers \"", identifier1, "\" and \"", identifier2, "\" are not meaningful in a", kind, ".\n" 271 252 "Possible cause is misspelled type name or missing generic parameter." ) ); 272 253 } // IdentifierBeforeIdentifier 273 254 274 255 static void IdentifierBeforeType( string & identifier, const char * kind ) { 275 SemanticError( yylloc, ::toString( " syntax error, identifier \"", identifier, "\" cannot appear before a ", kind, ".\n"256 SemanticError( yylloc, ::toString( "Identifier \"", identifier, "\" cannot appear before a ", kind, ".\n" 276 257 "Possible cause is misspelled storage/CV qualifier, misspelled typename, or missing generic parameter." ) ); 277 258 } // IdentifierBeforeType … … 300 281 %union { 301 282 Token tok; 302 ExpressionNode * expr; 283 ParseNode * pn; 284 ExpressionNode * en; 303 285 DeclarationNode * decl; 304 ast::AggregateDecl::Aggregate aggKey; 305 ast::TypeDecl::Kind tclass; 306 StatementNode * stmt; 307 ClauseNode * clause; 308 ast::WaitForStmt * wfs; 309 ast::WaitUntilStmt::ClauseNode * wucn; 286 AggregateDecl::Aggregate aggKey; 287 TypeDecl::Kind tclass; 288 StatementNode * sn; 289 WaitForStmt * wfs; 290 Expression * constant; 310 291 CondCtl * ifctl; 311 ForCtrl * forctl; 312 LabelNode * labels; 313 InitializerNode * init; 314 OperKinds oper; 292 ForCtrl * fctl; 293 OperKinds compop; 294 LabelNode * label; 295 InitializerNode * in; 296 OperKinds op; 315 297 std::string * str; 316 bool is_volatile;317 EnumHiding enum_hiding;318 ast::ExceptionKind except_kind;319 ast::GenericExpr * genexpr;298 bool flag; 299 EnumHiding hide; 300 CatchStmt::Kind catch_kind; 301 GenericExpr * genexpr; 320 302 } 321 303 322 // ************************ TERMINAL TOKENS ********************************304 //************************* TERMINAL TOKENS ******************************** 323 305 324 306 // keywords … … 349 331 %token ATTRIBUTE EXTENSION // GCC 350 332 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN 351 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR WAITUNTIL// CFA333 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR // CFA 352 334 %token DISABLE ENABLE TRY THROW THROWRESUME AT // CFA 353 335 %token ASM // C99, extension ISO/IEC 9899:1999 Section J.5.10(1) … … 355 337 356 338 // names and constants: lexer differentiates between identifier and typedef names 357 %token<tok> IDENTIFIER TYPEDIMname TYPEDEFname TYPEGENname358 %token<tok> TIMEOUT W AND WORCATCH RECOVER CATCHRESUME FIXUP FINALLY // CFA339 %token<tok> IDENTIFIER QUOTED_IDENTIFIER TYPEDIMname TYPEDEFname TYPEGENname 340 %token<tok> TIMEOUT WOR CATCH RECOVER CATCHRESUME FIXUP FINALLY // CFA 359 341 %token<tok> INTEGERconstant CHARACTERconstant STRINGliteral 360 342 %token<tok> DIRECTIVE … … 382 364 %type<tok> identifier identifier_at identifier_or_type_name attr_name 383 365 %type<tok> quasi_keyword 384 %type< expr> string_literal366 %type<constant> string_literal 385 367 %type<str> string_literal_list 386 368 387 %type< enum_hiding> hide_opt visible_hide_opt369 %type<hide> hide_opt visible_hide_opt 388 370 389 371 // expressions 390 %type<e xpr> constant391 %type<e xpr> tuple tuple_expression_list392 %type<op er> ptrref_operator unary_operator assignment_operator simple_assignment_operator compound_assignment_operator393 %type<e xpr> primary_expression postfix_expression unary_expression394 %type<e xpr> cast_expression_list cast_expression exponential_expression multiplicative_expression additive_expression395 %type<e xpr> shift_expression relational_expression equality_expression396 %type<e xpr> AND_expression exclusive_OR_expression inclusive_OR_expression397 %type<e xpr> logical_AND_expression logical_OR_expression398 %type<e xpr> conditional_expression constant_expression assignment_expression assignment_expression_opt399 %type<e xpr> comma_expression comma_expression_opt400 %type<e xpr> argument_expression_list_opt argument_expression_list argument_expression default_initializer_opt372 %type<en> constant 373 %type<en> tuple tuple_expression_list 374 %type<op> ptrref_operator unary_operator assignment_operator simple_assignment_operator compound_assignment_operator 375 %type<en> primary_expression postfix_expression unary_expression 376 %type<en> cast_expression_list cast_expression exponential_expression multiplicative_expression additive_expression 377 %type<en> shift_expression relational_expression equality_expression 378 %type<en> AND_expression exclusive_OR_expression inclusive_OR_expression 379 %type<en> logical_AND_expression logical_OR_expression 380 %type<en> conditional_expression constant_expression assignment_expression assignment_expression_opt 381 %type<en> comma_expression comma_expression_opt 382 %type<en> argument_expression_list_opt argument_expression_list argument_expression default_initializer_opt 401 383 %type<ifctl> conditional_declaration 402 %type<f orctl> for_control_expression for_control_expression_list403 %type< oper> upupeq updown updowneq downupdowneq404 %type<e xpr> subrange384 %type<fctl> for_control_expression for_control_expression_list 385 %type<compop> upupeq updown updowneq downupdowneq 386 %type<en> subrange 405 387 %type<decl> asm_name_opt 406 %type<e xpr> asm_operands_opt asm_operands_list asm_operand407 %type<label s> label_list408 %type<e xpr> asm_clobbers_list_opt409 %type< is_volatile> asm_volatile_opt410 %type<e xpr> handler_predicate_opt388 %type<en> asm_operands_opt asm_operands_list asm_operand 389 %type<label> label_list 390 %type<en> asm_clobbers_list_opt 391 %type<flag> asm_volatile_opt 392 %type<en> handler_predicate_opt 411 393 %type<genexpr> generic_association generic_assoc_list 412 394 413 395 // statements 414 %type<stmt> statement labeled_statement compound_statement 415 %type<stmt> statement_decl statement_decl_list statement_list_nodecl 416 %type<stmt> selection_statement if_statement 417 %type<clause> switch_clause_list_opt switch_clause_list 418 %type<expr> case_value 419 %type<clause> case_clause case_value_list case_label case_label_list 420 %type<stmt> iteration_statement jump_statement 421 %type<stmt> expression_statement asm_statement 422 %type<stmt> with_statement 423 %type<expr> with_clause_opt 424 %type<stmt> exception_statement 425 %type<clause> handler_clause finally_clause 426 %type<except_kind> handler_key 427 %type<stmt> mutex_statement 428 %type<expr> when_clause when_clause_opt waitfor waituntil timeout 429 %type<stmt> waitfor_statement waituntil_statement 430 %type<wfs> wor_waitfor_clause 431 %type<wucn> waituntil_clause wand_waituntil_clause wor_waituntil_clause 396 %type<sn> statement labeled_statement compound_statement 397 %type<sn> statement_decl statement_decl_list statement_list_nodecl 398 %type<sn> selection_statement if_statement 399 %type<sn> switch_clause_list_opt switch_clause_list 400 %type<en> case_value 401 %type<sn> case_clause case_value_list case_label case_label_list 402 %type<sn> iteration_statement jump_statement 403 %type<sn> expression_statement asm_statement 404 %type<sn> with_statement 405 %type<en> with_clause_opt 406 %type<sn> exception_statement handler_clause finally_clause 407 %type<catch_kind> handler_key 408 %type<sn> mutex_statement 409 %type<en> when_clause when_clause_opt waitfor timeout 410 %type<sn> waitfor_statement 411 %type<wfs> waitfor_clause 432 412 433 413 // declarations … … 441 421 %type<decl> assertion assertion_list assertion_list_opt 442 422 443 %type<e xpr> bit_subrange_size_opt bit_subrange_size423 %type<en> bit_subrange_size_opt bit_subrange_size 444 424 445 425 %type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type … … 454 434 455 435 %type<decl> enumerator_list enum_type enum_type_nobody 456 %type<in it> enumerator_value_opt436 %type<in> enumerator_value_opt 457 437 458 438 %type<decl> external_definition external_definition_list external_definition_list_opt … … 461 441 462 442 %type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract 463 %type<e xpr> field field_name_list field_name fraction_constants_opt443 %type<en> field field_name_list field_name fraction_constants_opt 464 444 465 445 %type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr … … 502 482 %type<decl> typedef_name typedef_declaration typedef_expression 503 483 504 %type<decl> variable_type_redeclarator variable_type_ptr variable_type_array variable_type_function 505 %type<decl> general_function_declarator function_type_redeclarator function_type_array function_type_no_ptr function_type_ptr 484 %type<decl> variable_type_redeclarator type_ptr type_array type_function 506 485 507 486 %type<decl> type_parameter_redeclarator type_parameter_ptr type_parameter_array type_parameter_function … … 510 489 %type<decl> type_parameter type_parameter_list type_initializer_opt 511 490 512 %type<e xpr> type_parameters_opt type_list array_type_list491 %type<en> type_parameters_opt type_list array_type_list 513 492 514 493 %type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list … … 521 500 522 501 // initializers 523 %type<in it> initializer initializer_list_opt initializer_opt502 %type<in> initializer initializer_list_opt initializer_opt 524 503 525 504 // designators 526 %type<e xpr> designator designator_list designation505 %type<en> designator designator_list designation 527 506 528 507 … … 533 512 // Similar issues exit with the waitfor statement. 534 513 535 // Order of these lines matters (low-to-high precedence). THEN is left associative over W AND/WOR/TIMEOUT/ELSE, WAND/WOR536 // is leftassociative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE.514 // Order of these lines matters (low-to-high precedence). THEN is left associative over WOR/TIMEOUT/ELSE, WOR is left 515 // associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE. 537 516 %precedence THEN // rule precedence for IF/WAITFOR statement 538 %precedence ANDAND // token precedence for start of WAND in WAITFOR statement539 %precedence WAND // token precedence for start of WAND in WAITFOR statement540 %precedence OROR // token precedence for start of WOR in WAITFOR statement541 517 %precedence WOR // token precedence for start of WOR in WAITFOR statement 542 518 %precedence TIMEOUT // token precedence for start of TIMEOUT in WAITFOR statement … … 616 592 constant: 617 593 // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant". 618 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( yylloc,*$1 ) ); }619 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }620 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }621 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }622 | CHARACTERconstant { $$ = new ExpressionNode( build_constantChar( yylloc,*$1 ) ); }594 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); } 595 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); } 596 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); } 597 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); } 598 | CHARACTERconstant { $$ = new ExpressionNode( build_constantChar( *$1 ) ); } 623 599 ; 624 600 625 601 quasi_keyword: // CFA 626 602 TIMEOUT 627 | WAND628 603 | WOR 629 604 | CATCH … … 646 621 647 622 string_literal: 648 string_literal_list { $$ = new ExpressionNode( build_constantStr( yylloc, *$1 )); }623 string_literal_list { $$ = build_constantStr( *$1 ); } 649 624 ; 650 625 … … 663 638 primary_expression: 664 639 IDENTIFIER // typedef name cannot be used as a variable name 665 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }640 { $$ = new ExpressionNode( build_varref( $1 ) ); } 666 641 | quasi_keyword 667 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }642 { $$ = new ExpressionNode( build_varref( $1 ) ); } 668 643 | TYPEDIMname // CFA, generic length argument 669 644 // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); } 670 645 // { $$ = new ExpressionNode( build_varref( $1 ) ); } 671 { $$ = new ExpressionNode( build_dimensionref( yylloc,$1 ) ); }646 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); } 672 647 | tuple 673 648 | '(' comma_expression ')' 674 649 { $$ = $2; } 675 650 | '(' compound_statement ')' // GCC, lambda expression 676 { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2) ) ) ); }651 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); } 677 652 | type_name '.' identifier // CFA, nested type 678 { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc,$3 ) ) ); }653 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); } 679 654 | type_name '.' '[' field_name_list ']' // CFA, nested type / tuple field selector 680 655 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } … … 682 657 { 683 658 // add the missing control expression to the GenericExpr and return it 684 $5->control = maybeMoveBuild ( $3 );659 $5->control = maybeMoveBuild<Expression>( $3 ); 685 660 $$ = new ExpressionNode( $5 ); 686 661 } … … 689 664 // | RESUME '(' comma_expression ')' compound_statement 690 665 // { SemanticError( yylloc, "Resume expression is currently unimplemented." ); $$ = nullptr; } 691 | IDENTIFIER IDENTIFIER // invalid syntax rules666 | IDENTIFIER IDENTIFIER // syntax error 692 667 { IdentifierBeforeIdentifier( *$1.str, *$2.str, "n expression" ); $$ = nullptr; } 693 | IDENTIFIER type_qualifier // invalid syntax rules668 | IDENTIFIER type_qualifier // syntax error 694 669 { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; } 695 | IDENTIFIER storage_class // invalid syntax rules670 | IDENTIFIER storage_class // syntax error 696 671 { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; } 697 | IDENTIFIER basic_type_name // invalid syntax rules672 | IDENTIFIER basic_type_name // syntax error 698 673 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 699 | IDENTIFIER TYPEDEFname // invalid syntax rules674 | IDENTIFIER TYPEDEFname // syntax error 700 675 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 701 | IDENTIFIER TYPEGENname // invalid syntax rules676 | IDENTIFIER TYPEGENname // syntax error 702 677 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 703 678 ; … … 708 683 { 709 684 // steal the association node from the singleton and delete the wrapper 710 assert( 1 == $3->associations.size() ); 711 $1->associations.push_back( $3->associations.front() ); 685 $1->associations.splice($1->associations.end(), $3->associations); 712 686 delete $3; 713 687 $$ = $1; … … 719 693 { 720 694 // create a GenericExpr wrapper with one association pair 721 $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } );695 $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>( $3 ) } } ); 722 696 } 723 697 | DEFAULT ':' assignment_expression 724 { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); }698 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>( $3 ) } } ); } 725 699 ; 726 700 … … 731 705 // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts. 732 706 // Current: Commas in subscripts make tuples. 733 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }707 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); } 734 708 | postfix_expression '[' assignment_expression ']' 735 709 // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a … … 737 711 // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is 738 712 // equivalent to the old x[i,j]. 739 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Index, $1, $3 ) ); }713 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); } 740 714 | constant '[' assignment_expression ']' // 3[a], 'a'[a], 3.5[a] 741 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Index, $1, $3 ) ); }715 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); } 742 716 | string_literal '[' assignment_expression ']' // "abc"[3], 3["abc"] 743 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }717 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); } 744 718 | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call 745 719 { 746 720 Token fn; 747 721 fn.str = new std::string( "?{}" ); // location undefined - use location of '{'? 748 $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc,fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );722 $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) ); 749 723 } 750 724 | postfix_expression '(' argument_expression_list_opt ')' 751 { $$ = new ExpressionNode( build_func( yylloc,$1, $3 ) ); }725 { $$ = new ExpressionNode( build_func( $1, $3 ) ); } 752 726 | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')' 753 727 // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; } 754 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,new string( "__builtin_va_arg") ) ),728 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ), 755 729 (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); } 756 730 | postfix_expression '`' identifier // CFA, postfix call 757 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,build_postfix_name( $3 ) ) ), $1 ) ); }731 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); } 758 732 | constant '`' identifier // CFA, postfix call 759 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,build_postfix_name( $3 ) ) ), $1 ) ); }733 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); } 760 734 | string_literal '`' identifier // CFA, postfix call 761 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1) ); }735 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); } 762 736 | postfix_expression '.' identifier 763 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc,$3 ) ) ); }737 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); } 764 738 | postfix_expression '.' INTEGERconstant // CFA, tuple index 765 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc,*$3 ) ) ); }739 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); } 766 740 | postfix_expression FLOATING_FRACTIONconstant // CFA, tuple index 767 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc,*$2 ) ) ); }741 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); } 768 742 | postfix_expression '.' '[' field_name_list ']' // CFA, tuple field selector 769 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }743 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 770 744 | postfix_expression '.' aggregate_control 771 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$3, $1 ) ); }745 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); } 772 746 | postfix_expression ARROW identifier 773 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc,$3 ) ) ); }747 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); } 774 748 | postfix_expression ARROW INTEGERconstant // CFA, tuple index 775 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc,*$3 ) ) ); }749 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); } 776 750 | postfix_expression ARROW '[' field_name_list ']' // CFA, tuple field selector 777 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }751 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); } 778 752 | postfix_expression ICR 779 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::IncrPost, $1 ) ); }753 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); } 780 754 | postfix_expression DECR 781 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::DecrPost, $1 ) ); }755 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, $1 ) ); } 782 756 | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal 783 { $$ = new ExpressionNode( build_compoundLiteral( yylloc,$2, new InitializerNode( $5, true ) ) ); }757 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); } 784 758 | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal 785 { $$ = new ExpressionNode( build_compoundLiteral( yylloc,$2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }759 { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); } 786 760 | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call 787 761 { 788 762 Token fn; 789 763 fn.str = new string( "^?{}" ); // location undefined 790 $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc,fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );764 $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) ); 791 765 } 792 766 ; … … 807 781 '@' // CFA, default parameter 808 782 { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; } 809 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }783 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); } 810 784 | assignment_expression 811 785 ; … … 819 793 field_name 820 794 | FLOATING_DECIMALconstant field 821 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), maybeMoveBuild( $2 ) ) ); }795 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); } 822 796 | FLOATING_DECIMALconstant '[' field_name_list ']' 823 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc,$3 ) ) ); }797 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); } 824 798 | field_name '.' field 825 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }799 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); } 826 800 | field_name '.' '[' field_name_list ']' 827 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }801 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 828 802 | field_name ARROW field 829 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }803 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); } 830 804 | field_name ARROW '[' field_name_list ']' 831 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }805 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); } 832 806 ; 833 807 834 808 field_name: 835 809 INTEGERconstant fraction_constants_opt 836 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc,*$1 ), $2 ) ); }810 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); } 837 811 | FLOATINGconstant fraction_constants_opt 838 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc,*$1 ), $2 ) ); }812 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); } 839 813 | identifier_at fraction_constants_opt // CFA, allow anonymous fields 840 814 { 841 $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc,$1 ), $2 ) );815 $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) ); 842 816 } 843 817 ; … … 848 822 | fraction_constants_opt FLOATING_FRACTIONconstant 849 823 { 850 ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc,*$2 );851 $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1,constant ) ) : new ExpressionNode( constant );824 Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 ); 825 $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1, constant ) ) : new ExpressionNode( constant ); 852 826 } 853 827 ; … … 859 833 | constant 860 834 | string_literal 861 { $$ = $1; }835 { $$ = new ExpressionNode( $1 ); } 862 836 | EXTENSION cast_expression // GCC 863 837 { $$ = $2->set_extension( true ); } … … 868 842 { 869 843 switch ( $1 ) { 870 case OperKinds::AddressOf:871 $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );844 case OperKinds::AddressOf: 845 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ); 872 846 break; 873 case OperKinds::PointTo:874 $$ = new ExpressionNode( build_unary_val( yylloc,$1, $2 ) );847 case OperKinds::PointTo: 848 $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); 875 849 break; 876 case OperKinds::And:877 $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );850 case OperKinds::And: 851 $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ) ); 878 852 break; 879 default:853 default: 880 854 assert( false ); 881 855 } 882 856 } 883 857 | unary_operator cast_expression 884 { $$ = new ExpressionNode( build_unary_val( yylloc,$1, $2 ) ); }858 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); } 885 859 | ICR unary_expression 886 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::Incr, $2 ) ); }860 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Incr, $2 ) ); } 887 861 | DECR unary_expression 888 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::Decr, $2 ) ); }862 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Decr, $2 ) ); } 889 863 | SIZEOF unary_expression 890 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }864 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild<Expression>( $2 ) ) ); } 891 865 | SIZEOF '(' type_no_function ')' 892 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc,maybeMoveBuildType( $3 ) ) ); }866 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); } 893 867 | ALIGNOF unary_expression // GCC, variable alignment 894 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }868 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild<Expression>( $2 ) ) ); } 895 869 | ALIGNOF '(' type_no_function ')' // GCC, type alignment 896 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc,maybeMoveBuildType( $3 ) ) ); }870 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); } 897 871 | OFFSETOF '(' type_no_function ',' identifier ')' 898 { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc,$5 ) ) ); }872 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); } 899 873 | TYPEID '(' type_no_function ')' 900 874 { … … 921 895 unary_expression 922 896 | '(' type_no_function ')' cast_expression 923 { $$ = new ExpressionNode( build_cast( yylloc,$2, $4 ) ); }897 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 924 898 | '(' aggregate_control '&' ')' cast_expression // CFA 925 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$2, $5 ) ); }899 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 926 900 | '(' aggregate_control '*' ')' cast_expression // CFA 927 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$2, $5 ) ); }901 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 928 902 | '(' VIRTUAL ')' cast_expression // CFA 929 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }903 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $4 ), maybeMoveBuildType( nullptr ) ) ); } 930 904 | '(' VIRTUAL type_no_function ')' cast_expression // CFA 931 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }905 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $5 ), maybeMoveBuildType( $3 ) ) ); } 932 906 | '(' RETURN type_no_function ')' cast_expression // CFA 933 { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }907 { $$ = new ExpressionNode( build_cast( $3, $5, CastExpr::Return ) ); } 934 908 | '(' COERCE type_no_function ')' cast_expression // CFA 935 909 { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; } … … 937 911 { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; } 938 912 // | '(' type_no_function ')' tuple 939 // { $$ = new ast::ExpressionNode( build_cast( yylloc,$2, $4 ) ); }913 // { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 940 914 ; 941 915 … … 955 929 cast_expression 956 930 | exponential_expression '\\' cast_expression 957 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Exp, $1, $3 ) ); }931 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); } 958 932 ; 959 933 … … 961 935 exponential_expression 962 936 | multiplicative_expression '*' exponential_expression 963 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Mul, $1, $3 ) ); }937 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); } 964 938 | multiplicative_expression '/' exponential_expression 965 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Div, $1, $3 ) ); }939 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); } 966 940 | multiplicative_expression '%' exponential_expression 967 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Mod, $1, $3 ) ); }941 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); } 968 942 ; 969 943 … … 971 945 multiplicative_expression 972 946 | additive_expression '+' multiplicative_expression 973 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Plus, $1, $3 ) ); }947 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); } 974 948 | additive_expression '-' multiplicative_expression 975 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Minus, $1, $3 ) ); }949 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); } 976 950 ; 977 951 … … 979 953 additive_expression 980 954 | shift_expression LS additive_expression 981 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LShift, $1, $3 ) ); }955 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); } 982 956 | shift_expression RS additive_expression 983 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::RShift, $1, $3 ) ); }957 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); } 984 958 ; 985 959 … … 987 961 shift_expression 988 962 | relational_expression '<' shift_expression 989 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LThan, $1, $3 ) ); }963 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); } 990 964 | relational_expression '>' shift_expression 991 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::GThan, $1, $3 ) ); }965 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); } 992 966 | relational_expression LE shift_expression 993 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LEThan, $1, $3 ) ); }967 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); } 994 968 | relational_expression GE shift_expression 995 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::GEThan, $1, $3 ) ); }969 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); } 996 970 ; 997 971 … … 999 973 relational_expression 1000 974 | equality_expression EQ relational_expression 1001 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Eq, $1, $3 ) ); }975 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); } 1002 976 | equality_expression NE relational_expression 1003 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Neq, $1, $3 ) ); }977 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); } 1004 978 ; 1005 979 … … 1007 981 equality_expression 1008 982 | AND_expression '&' equality_expression 1009 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::BitAnd, $1, $3 ) ); }983 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); } 1010 984 ; 1011 985 … … 1013 987 AND_expression 1014 988 | exclusive_OR_expression '^' AND_expression 1015 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Xor, $1, $3 ) ); }989 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); } 1016 990 ; 1017 991 … … 1019 993 exclusive_OR_expression 1020 994 | inclusive_OR_expression '|' exclusive_OR_expression 1021 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::BitOr, $1, $3 ) ); }995 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); } 1022 996 ; 1023 997 … … 1025 999 inclusive_OR_expression 1026 1000 | logical_AND_expression ANDAND inclusive_OR_expression 1027 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr) ); }1001 { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); } 1028 1002 ; 1029 1003 … … 1031 1005 logical_AND_expression 1032 1006 | logical_OR_expression OROR logical_AND_expression 1033 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr) ); }1007 { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); } 1034 1008 ; 1035 1009 … … 1037 1011 logical_OR_expression 1038 1012 | logical_OR_expression '?' comma_expression ':' conditional_expression 1039 { $$ = new ExpressionNode( build_cond( yylloc,$1, $3, $5 ) ); }1013 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); } 1040 1014 // FIX ME: computes $1 twice 1041 1015 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand 1042 { $$ = new ExpressionNode( build_cond( yylloc,$1, $1, $4 ) ); }1016 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); } 1043 1017 ; 1044 1018 … … 1055 1029 // SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr; 1056 1030 // } else { 1057 $$ = new ExpressionNode( build_binary_val( yylloc,$2, $1, $3 ) );1031 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); 1058 1032 // } // if 1059 1033 } … … 1100 1074 // { $$ = new ExpressionNode( build_tuple( $3 ) ); } 1101 1075 '[' ',' tuple_expression_list ']' 1102 { $$ = new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }1076 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); } 1103 1077 | '[' push assignment_expression pop ',' tuple_expression_list ']' 1104 { $$ = new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)($3->set_last( $6 ) ) )); }1078 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); } 1105 1079 ; 1106 1080 … … 1118 1092 assignment_expression 1119 1093 | comma_expression ',' assignment_expression 1120 { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1094 { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); } 1121 1095 ; 1122 1096 … … 1139 1113 | mutex_statement 1140 1114 | waitfor_statement 1141 | waituntil_statement1142 1115 | exception_statement 1143 1116 | enable_disable_statement … … 1145 1118 | asm_statement 1146 1119 | DIRECTIVE 1147 { $$ = new StatementNode( build_directive( yylloc,$1 ) ); }1120 { $$ = new StatementNode( build_directive( $1 ) ); } 1148 1121 ; 1149 1122 … … 1151 1124 // labels cannot be identifiers 0 or 1 1152 1125 identifier_or_type_name ':' attribute_list_opt statement 1153 { $$ = $4->add_label( yylloc,$1, $3 ); }1154 | identifier_or_type_name ':' attribute_list_opt error // invalid syntax rule1155 { 1156 SemanticError( yylloc, ::toString( " syntx error, label \"", *$1.str, "\" must be associated with a statement, "1126 { $$ = $4->add_label( $1, $3 ); } 1127 | identifier_or_type_name ':' attribute_list_opt error // syntax error 1128 { 1129 SemanticError( yylloc, ::toString( "Label \"", *$1.str, "\" must be associated with a statement, " 1157 1130 "where a declaration, case, or default is not a statement. " 1158 1131 "Move the label or terminate with a semi-colon." ) ); … … 1163 1136 compound_statement: 1164 1137 '{' '}' 1165 { $$ = new StatementNode( build_compound( yylloc,(StatementNode *)0 ) ); }1138 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); } 1166 1139 | '{' push 1167 1140 local_label_declaration_opt // GCC, local labels appear at start of block 1168 1141 statement_decl_list // C99, intermix declarations and statements 1169 1142 pop '}' 1170 { $$ = new StatementNode( build_compound( yylloc,$4 ) ); }1143 { $$ = new StatementNode( build_compound( $4 ) ); } 1171 1144 ; 1172 1145 … … 1193 1166 | statement_list_nodecl statement 1194 1167 { assert( $1 ); $1->set_last( $2 ); $$ = $1; } 1195 | statement_list_nodecl error // invalid syntax rule1196 { SemanticError( yylloc, " syntax error, declarations only allowed at the start of the switch body, i.e., after the '{'." ); $$ = nullptr; }1168 | statement_list_nodecl error // syntax error 1169 { SemanticError( yylloc, "Declarations only allowed at the start of the switch body, i.e., after the '{'." ); $$ = nullptr; } 1197 1170 ; 1198 1171 1199 1172 expression_statement: 1200 1173 comma_expression_opt ';' 1201 { $$ = new StatementNode( build_expr( yylloc, $1 ) ); } 1174 { $$ = new StatementNode( build_expr( $1 ) ); } 1175 | MUTEX '(' ')' comma_expression ';' 1176 { $$ = new StatementNode( build_mutex( nullptr, new StatementNode( build_expr( $4 ) ) ) ); } 1202 1177 ; 1203 1178 … … 1208 1183 { $$ = $2; } 1209 1184 | SWITCH '(' comma_expression ')' case_clause 1210 { $$ = new StatementNode( build_switch( yylloc,true, $3, $5 ) ); }1185 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); } 1211 1186 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1212 1187 { 1213 StatementNode *sw = new StatementNode( build_switch( yylloc,true, $3, $8 ) );1188 StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) ); 1214 1189 // The semantics of the declaration list is changed to include associated initialization, which is performed 1215 1190 // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound … … 1217 1192 // therefore, are removed from the grammar even though C allows it. The change also applies to choose 1218 1193 // statement. 1219 $$ = $7 ? new StatementNode( build_compound( yylloc,(StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1220 } 1221 | SWITCH '(' comma_expression ')' '{' error '}' // CFA, invalid syntax ruleerror1222 { SemanticError( yylloc, " synatx error, declarations can onlyappear before the list of case clauses." ); $$ = nullptr; }1194 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1195 } 1196 | SWITCH '(' comma_expression ')' '{' error '}' // CFA, syntax error 1197 { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; } 1223 1198 | CHOOSE '(' comma_expression ')' case_clause // CFA 1224 { $$ = new StatementNode( build_switch( yylloc,false, $3, $5 ) ); }1199 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); } 1225 1200 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1226 1201 { 1227 StatementNode *sw = new StatementNode( build_switch( yylloc,false, $3, $8 ) );1228 $$ = $7 ? new StatementNode( build_compound( yylloc,(StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1229 } 1230 | CHOOSE '(' comma_expression ')' '{' error '}' // CFA, invalid syntax rule1231 { SemanticError( yylloc, " syntax error, declarations can onlyappear before the list of case clauses." ); $$ = nullptr; }1202 StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) ); 1203 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1204 } 1205 | CHOOSE '(' comma_expression ')' '{' error '}' // CFA, syntax error 1206 { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; } 1232 1207 ; 1233 1208 … … 1235 1210 IF '(' conditional_declaration ')' statement %prec THEN 1236 1211 // explicitly deal with the shift/reduce conflict on if/else 1237 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc,$5 ), nullptr ) ); }1212 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); } 1238 1213 | IF '(' conditional_declaration ')' statement ELSE statement 1239 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc,$7 ) ) ); }1214 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); } 1240 1215 ; 1241 1216 … … 1249 1224 | declaration comma_expression // semi-colon separated 1250 1225 { $$ = new CondCtl( $1, $2 ); } 1251 ;1226 ; 1252 1227 1253 1228 // CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case … … 1257 1232 constant_expression { $$ = $1; } 1258 1233 | constant_expression ELLIPSIS constant_expression // GCC, subrange 1259 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1234 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); } 1260 1235 | subrange // CFA, subrange 1261 1236 ; 1262 1237 1263 1238 case_value_list: // CFA 1264 case_value { $$ = new ClauseNode( build_case( yylloc,$1 ) ); }1239 case_value { $$ = new StatementNode( build_case( $1 ) ); } 1265 1240 // convert case list, e.g., "case 1, 3, 5:" into "case 1: case 3: case 5" 1266 | case_value_list ',' case_value { $$ = $1->set_last( new ClauseNode( build_case( yylloc, $3) ) ); }1241 | case_value_list ',' case_value { $$ = (StatementNode *)($1->set_last( new StatementNode( build_case( $3 ) ) ) ); } 1267 1242 ; 1268 1243 1269 1244 case_label: // CFA 1270 CASE error // invalid syntax rule1271 { SemanticError( yylloc, " syntax error, case list missingafter case." ); $$ = nullptr; }1245 CASE error // syntax error 1246 { SemanticError( yylloc, "Missing case list after case." ); $$ = nullptr; } 1272 1247 | CASE case_value_list ':' { $$ = $2; } 1273 | CASE case_value_list error // invalid syntax rule1274 { SemanticError( yylloc, " syntax error, colon missingafter case list." ); $$ = nullptr; }1275 | DEFAULT ':' { $$ = new ClauseNode( build_default( yylloc) ); }1248 | CASE case_value_list error // syntax error 1249 { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; } 1250 | DEFAULT ':' { $$ = new StatementNode( build_default() ); } 1276 1251 // A semantic check is required to ensure only one default clause per switch/choose statement. 1277 | DEFAULT error // invalid syntax rules1278 { SemanticError( yylloc, " syntax error, colon missingafter default." ); $$ = nullptr; }1252 | DEFAULT error // syntax error 1253 { SemanticError( yylloc, "Missing colon after default." ); $$ = nullptr; } 1279 1254 ; 1280 1255 1281 1256 case_label_list: // CFA 1282 1257 case_label 1283 | case_label_list case_label { $$ = $1->set_last( $2); }1258 | case_label_list case_label { $$ = (StatementNode *)( $1->set_last( $2 )); } 1284 1259 ; 1285 1260 1286 1261 case_clause: // CFA 1287 case_label_list statement { $$ = $1->append_last_case( maybe_build_compound( yylloc,$2 ) ); }1262 case_label_list statement { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); } 1288 1263 ; 1289 1264 … … 1296 1271 switch_clause_list: // CFA 1297 1272 case_label_list statement_list_nodecl 1298 { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc,$2 ) ) ); }1273 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); } 1299 1274 | switch_clause_list case_label_list statement_list_nodecl 1300 { $$ = $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3) ) ) ); }1275 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); } 1301 1276 ; 1302 1277 1303 1278 iteration_statement: 1304 1279 WHILE '(' ')' statement %prec THEN // CFA => while ( 1 ) 1305 { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc,$4 ) ) ); }1280 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); } 1306 1281 | WHILE '(' ')' statement ELSE statement // CFA 1307 1282 { 1308 $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc,$4 ) ) );1309 SemanticWarning( yylloc, Warning::SuperfluousElse );1283 $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); 1284 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1310 1285 } 1311 1286 | WHILE '(' conditional_declaration ')' statement %prec THEN 1312 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc,$5 ) ) ); }1287 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); } 1313 1288 | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA 1314 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc,$5 ), $7 ) ); }1289 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); } 1315 1290 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) 1316 { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc,$2 ) ) ); }1291 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); } 1317 1292 | DO statement WHILE '(' ')' ELSE statement // CFA 1318 1293 { 1319 $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc,$2 ) ) );1320 SemanticWarning( yylloc, Warning::SuperfluousElse );1294 $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); 1295 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1321 1296 } 1322 1297 | DO statement WHILE '(' comma_expression ')' ';' 1323 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc,$2 ) ) ); }1298 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); } 1324 1299 | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA 1325 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc,$2 ), $8 ) ); }1300 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); } 1326 1301 | FOR '(' ')' statement %prec THEN // CFA => for ( ;; ) 1327 { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc,$4 ) ) ); }1302 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); } 1328 1303 | FOR '(' ')' statement ELSE statement // CFA 1329 1304 { 1330 $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc,$4 ) ) );1331 SemanticWarning( yylloc, Warning::SuperfluousElse );1305 $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); 1306 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1332 1307 } 1333 1308 | FOR '(' for_control_expression_list ')' statement %prec THEN 1334 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc,$5 ) ) ); }1309 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); } 1335 1310 | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA 1336 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc,$5 ), $7 ) ); }1311 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); } 1337 1312 ; 1338 1313 … … 1348 1323 if ( $1->condition ) { 1349 1324 if ( $3->condition ) { 1350 $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr) );1325 $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) ); 1351 1326 } // if 1352 1327 } else $1->condition = $3->condition; 1353 1328 if ( $1->change ) { 1354 1329 if ( $3->change ) { 1355 $1->change->expr.reset( new ast::CommaExpr( yylloc,$1->change->expr.release(), $3->change->expr.release() ) );1330 $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) ); 1356 1331 } // if 1357 1332 } else $1->change = $3->change; … … 1362 1337 for_control_expression: 1363 1338 ';' comma_expression_opt ';' comma_expression_opt 1364 { $$ = new ForCtrl( nullptr, $2, $4 ); }1339 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); } 1365 1340 | comma_expression ';' comma_expression_opt ';' comma_expression_opt 1366 { 1367 StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr; 1368 $$ = new ForCtrl( init, $3, $5 ); 1369 } 1341 { $$ = new ForCtrl( $1, $3, $5 ); } 1370 1342 | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';' 1371 { $$ = new ForCtrl( new StatementNode( $1 ), $2, $4 ); }1343 { $$ = new ForCtrl( $1, $2, $4 ); } 1372 1344 1373 1345 | '@' ';' comma_expression // CFA, empty loop-index 1374 { $$ = new ForCtrl( nullptr, $3, nullptr ); }1346 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); } 1375 1347 | '@' ';' comma_expression ';' comma_expression // CFA, empty loop-index 1376 { $$ = new ForCtrl( nullptr, $3, $5 ); }1348 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); } 1377 1349 1378 1350 | comma_expression // CFA, anonymous loop-index 1379 { $$ = forCtrl( yylloc,$1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }1351 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); } 1380 1352 | downupdowneq comma_expression // CFA, anonymous loop-index 1381 { $$ = forCtrl( yylloc,$2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }1353 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); } 1382 1354 1383 1355 | comma_expression updowneq comma_expression // CFA, anonymous loop-index 1384 { $$ = forCtrl( yylloc,$1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }1356 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); } 1385 1357 | '@' updowneq comma_expression // CFA, anonymous loop-index 1386 1358 { 1387 1359 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1388 else $$ = forCtrl( yylloc,$3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );1360 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE ); 1389 1361 } 1390 1362 | comma_expression updowneq '@' // CFA, anonymous loop-index … … 1394 1366 } 1395 1367 | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1396 { $$ = forCtrl( yylloc,$1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }1368 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); } 1397 1369 | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1398 1370 { 1399 1371 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1400 else $$ = forCtrl( yylloc,$3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );1372 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 ); 1401 1373 } 1402 1374 | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index … … 1405 1377 else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1406 1378 } 1407 | comma_expression updowneq comma_expression '~' '@' // CFA, invalid syntax rules1379 | comma_expression updowneq comma_expression '~' '@' // CFA, error 1408 1380 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1409 | '@' updowneq '@' // CFA, invalid syntax rules1381 | '@' updowneq '@' // CFA, error 1410 1382 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1411 | '@' updowneq comma_expression '~' '@' // CFA, invalid syntax rules1383 | '@' updowneq comma_expression '~' '@' // CFA, error 1412 1384 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1413 | comma_expression updowneq '@' '~' '@' // CFA, invalid syntax rules1385 | comma_expression updowneq '@' '~' '@' // CFA, error 1414 1386 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1415 | '@' updowneq '@' '~' '@' // CFA, invalid syntax rules1387 | '@' updowneq '@' '~' '@' // CFA, error 1416 1388 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1417 1389 1418 1390 | comma_expression ';' comma_expression // CFA 1419 { $$ = forCtrl( yylloc,$3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }1391 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); } 1420 1392 | comma_expression ';' downupdowneq comma_expression // CFA 1421 { $$ = forCtrl( yylloc,$4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }1393 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); } 1422 1394 1423 1395 | comma_expression ';' comma_expression updowneq comma_expression // CFA 1424 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }1396 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); } 1425 1397 | comma_expression ';' '@' updowneq comma_expression // CFA 1426 1398 { 1427 1399 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1428 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, NEW_ONE );1400 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE ); 1429 1401 } 1430 1402 | comma_expression ';' comma_expression updowneq '@' // CFA 1431 1403 { 1432 1404 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1433 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, " syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }1434 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, NEW_ONE );1435 } 1436 | comma_expression ';' '@' updowneq '@' // CFA, invalid syntax rules1437 { SemanticError( yylloc, " syntax error, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }1405 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1406 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE ); 1407 } 1408 | comma_expression ';' '@' updowneq '@' // CFA, error 1409 { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; } 1438 1410 1439 1411 | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA 1440 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }1441 | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, invalid syntax rules1412 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); } 1413 | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error 1442 1414 { 1443 1415 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1444 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, $7 );1416 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 ); 1445 1417 } 1446 1418 | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA 1447 1419 { 1448 1420 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1449 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, " syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }1450 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, $7 );1421 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1422 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 ); 1451 1423 } 1452 1424 | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA 1453 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }1454 | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, invalid syntax rules1425 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); } 1426 | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error 1455 1427 { 1456 1428 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1457 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, nullptr );1429 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr ); 1458 1430 } 1459 1431 | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA 1460 1432 { 1461 1433 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1462 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, " syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }1463 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, nullptr );1434 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1435 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr ); 1464 1436 } 1465 1437 | comma_expression ';' '@' updowneq '@' '~' '@' // CFA 1466 { SemanticError( yylloc, " syntax error, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }1438 { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; } 1467 1439 1468 1440 | declaration comma_expression // CFA 1469 { $$ = forCtrl( yylloc,$1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }1441 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); } 1470 1442 | declaration downupdowneq comma_expression // CFA 1471 { $$ = forCtrl( yylloc,$1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }1443 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); } 1472 1444 1473 1445 | declaration comma_expression updowneq comma_expression // CFA 1474 { $$ = forCtrl( yylloc,$1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }1446 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); } 1475 1447 | declaration '@' updowneq comma_expression // CFA 1476 1448 { 1477 1449 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1478 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, NEW_ONE );1450 else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE ); 1479 1451 } 1480 1452 | declaration comma_expression updowneq '@' // CFA 1481 1453 { 1482 1454 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1483 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, " syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }1484 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, NEW_ONE );1455 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1456 else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE ); 1485 1457 } 1486 1458 1487 1459 | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA 1488 { $$ = forCtrl( yylloc,$1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }1460 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); } 1489 1461 | declaration '@' updowneq comma_expression '~' comma_expression // CFA 1490 1462 { 1491 1463 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1492 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, $6 );1464 else $$ = forCtrl( $1, $4, $3, nullptr, $6 ); 1493 1465 } 1494 1466 | declaration comma_expression updowneq '@' '~' comma_expression // CFA 1495 1467 { 1496 1468 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1497 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, " syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }1498 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, $6 );1469 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1470 else $$ = forCtrl( $1, $2, $3, nullptr, $6 ); 1499 1471 } 1500 1472 | declaration comma_expression updowneq comma_expression '~' '@' // CFA 1501 { $$ = forCtrl( yylloc,$1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }1473 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); } 1502 1474 | declaration '@' updowneq comma_expression '~' '@' // CFA 1503 1475 { 1504 1476 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1505 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, nullptr );1477 else $$ = forCtrl( $1, $4, $3, nullptr, nullptr ); 1506 1478 } 1507 1479 | declaration comma_expression updowneq '@' '~' '@' // CFA 1508 1480 { 1509 1481 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1510 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, " syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }1511 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, nullptr );1512 } 1513 | declaration '@' updowneq '@' '~' '@' // CFA, invalid syntax rules1514 { SemanticError( yylloc, " syntax error, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }1482 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1483 else $$ = forCtrl( $1, $2, $3, nullptr, nullptr ); 1484 } 1485 | declaration '@' updowneq '@' '~' '@' // CFA, error 1486 { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; } 1515 1487 1516 1488 | comma_expression ';' TYPEDEFname // CFA, array type … … 1521 1493 | comma_expression ';' downupdowneq TYPEDEFname // CFA, array type 1522 1494 { 1523 if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { 1524 SemanticError( yylloc, "syntax error, all enumeration ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; 1525 } 1495 if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "All enumation ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; } 1526 1496 SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr; 1527 1497 } 1528 ;1498 ; 1529 1499 1530 1500 downupdowneq: … … 1535 1505 | ErangeDownEq 1536 1506 { $$ = OperKinds::GEThan; } 1537 ;1507 ; 1538 1508 1539 1509 updown: … … 1542 1512 | ErangeDown 1543 1513 { $$ = OperKinds::GThan; } 1544 ;1514 ; 1545 1515 1546 1516 updowneq: … … 1550 1520 | ErangeDownEq 1551 1521 { $$ = OperKinds::GEThan; } 1552 ;1522 ; 1553 1523 1554 1524 jump_statement: 1555 1525 GOTO identifier_or_type_name ';' 1556 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }1526 { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); } 1557 1527 | GOTO '*' comma_expression ';' // GCC, computed goto 1558 1528 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3); … … 1561 1531 // A semantic check is required to ensure fallthru appears only in the body of a choose statement. 1562 1532 | fall_through_name ';' // CFA 1563 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }1533 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); } 1564 1534 | fall_through_name identifier_or_type_name ';' // CFA 1565 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }1535 { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); } 1566 1536 | fall_through_name DEFAULT ';' // CFA 1567 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }1537 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); } 1568 1538 | CONTINUE ';' 1569 1539 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1570 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }1540 { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); } 1571 1541 | CONTINUE identifier_or_type_name ';' // CFA, multi-level continue 1572 1542 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1573 1543 // the target of the transfer appears only at the start of an iteration statement. 1574 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }1544 { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); } 1575 1545 | BREAK ';' 1576 1546 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1577 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }1547 { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); } 1578 1548 | BREAK identifier_or_type_name ';' // CFA, multi-level exit 1579 1549 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1580 1550 // the target of the transfer appears only at the start of an iteration statement. 1581 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }1551 { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); } 1582 1552 | RETURN comma_expression_opt ';' 1583 { $$ = new StatementNode( build_return( yylloc,$2 ) ); }1553 { $$ = new StatementNode( build_return( $2 ) ); } 1584 1554 | RETURN '{' initializer_list_opt comma_opt '}' ';' 1585 1555 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1586 1556 | SUSPEND ';' 1587 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None) ); }1557 { $$ = new StatementNode( build_suspend( nullptr ) ); } 1588 1558 | SUSPEND compound_statement 1589 { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None) ); }1559 { $$ = new StatementNode( build_suspend( $2 ) ); } 1590 1560 | SUSPEND COROUTINE ';' 1591 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }1561 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); } 1592 1562 | SUSPEND COROUTINE compound_statement 1593 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }1563 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); } 1594 1564 | SUSPEND GENERATOR ';' 1595 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }1565 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); } 1596 1566 | SUSPEND GENERATOR compound_statement 1597 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }1567 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); } 1598 1568 | THROW assignment_expression_opt ';' // handles rethrow 1599 { $$ = new StatementNode( build_throw( yylloc,$2 ) ); }1569 { $$ = new StatementNode( build_throw( $2 ) ); } 1600 1570 | THROWRESUME assignment_expression_opt ';' // handles reresume 1601 { $$ = new StatementNode( build_resume( yylloc,$2 ) ); }1571 { $$ = new StatementNode( build_resume( $2 ) ); } 1602 1572 | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume 1603 1573 { $$ = new StatementNode( build_resume_at( $2, $4 ) ); } … … 1611 1581 with_statement: 1612 1582 WITH '(' tuple_expression_list ')' statement 1613 { $$ = new StatementNode( build_with( yylloc,$3, $5 ) ); }1614 ; 1615 1616 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so possiblychange syntax to "with mutex".1583 { $$ = new StatementNode( build_with( $3, $5 ) ); } 1584 ; 1585 1586 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so change syntax to "with mutex". 1617 1587 mutex_statement: 1618 MUTEX '(' argument_expression_list_opt ')' statement 1619 { 1620 if ( ! $3 ) { SemanticError( yylloc, "syntax error, mutex argument list cannot be empty." ); $$ = nullptr; } 1621 $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) ); 1622 } 1588 MUTEX '(' argument_expression_list ')' statement 1589 { $$ = new StatementNode( build_mutex( $3, $5 ) ); } 1623 1590 ; 1624 1591 … … 1631 1598 { $$ = nullptr; } 1632 1599 | when_clause 1600 ; 1601 1602 waitfor: 1603 WAITFOR '(' cast_expression ')' 1604 { $$ = $3; } 1605 // | WAITFOR '(' cast_expression ',' argument_expression_list_opt ')' 1606 // { $$ = (ExpressionNode *)$3->set_last( $5 ); } 1607 | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')' 1608 { $$ = (ExpressionNode *)($3->set_last( $5 )); } 1633 1609 ; 1634 1610 … … 1641 1617 1642 1618 timeout: 1643 TIMEOUT '(' comma_expression ')' { $$ = $3; } 1644 ; 1645 1646 wor: 1647 OROR 1648 | WOR 1649 1650 waitfor: 1651 WAITFOR '(' cast_expression ')' 1652 { $$ = $3; } 1653 | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')' 1654 { $$ = (ExpressionNode *)($3->set_last( $5 )); } 1655 ; 1656 1657 wor_waitfor_clause: 1619 TIMEOUT '(' comma_expression ')' { $$ = $3; } 1620 ; 1621 1622 waitfor_clause: 1658 1623 when_clause_opt waitfor statement %prec THEN 1659 // Called first: create header for WaitForStmt. 1660 { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); } 1661 | wor_waitfor_clause wor when_clause_opt waitfor statement 1662 { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); } 1663 | wor_waitfor_clause wor when_clause_opt ELSE statement 1664 { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); } 1665 | wor_waitfor_clause wor when_clause_opt timeout statement %prec THEN 1666 { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); } 1624 { $$ = build_waitfor( $2, maybe_build_compound( $3 ), $1 ); } 1625 | when_clause_opt waitfor statement WOR waitfor_clause 1626 { $$ = build_waitfor( $2, maybe_build_compound( $3 ), $1, $5 ); } 1627 | when_clause_opt timeout statement %prec THEN 1628 { $$ = build_waitfor_timeout( $2, maybe_build_compound( $3 ), $1 ); } 1629 | when_clause_opt ELSE statement 1630 { $$ = build_waitfor_timeout( nullptr, maybe_build_compound( $3 ), $1 ); } 1667 1631 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1668 | w or_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // invalid syntax rules1669 { SemanticError( yylloc, " syntax error,else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }1670 | w or_waitfor_clause wor when_clause_opt timeout statement worwhen_clause ELSE statement1671 { $$ = build_waitfor_ else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 )); }1632 | when_clause_opt timeout statement WOR ELSE statement // syntax error 1633 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1634 | when_clause_opt timeout statement WOR when_clause ELSE statement 1635 { $$ = build_waitfor_timeout( $2, maybe_build_compound( $3 ), $1, maybe_build_compound( $7 ), $5 ); } 1672 1636 ; 1673 1637 1674 1638 waitfor_statement: 1675 wor_waitfor_clause %prec THEN 1676 { $$ = new StatementNode( $1 ); } 1677 ; 1678 1679 wand: 1680 ANDAND 1681 | WAND 1682 ; 1683 1684 waituntil: 1685 WAITUNTIL '(' comma_expression ')' 1686 { $$ = $3; } 1687 ; 1688 1689 waituntil_clause: 1690 when_clause_opt waituntil statement 1691 { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); } 1692 | '(' wor_waituntil_clause ')' 1693 { $$ = $2; } 1694 ; 1695 1696 wand_waituntil_clause: 1697 waituntil_clause %prec THEN 1698 { $$ = $1; } 1699 | waituntil_clause wand wand_waituntil_clause 1700 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); } 1701 ; 1702 1703 wor_waituntil_clause: 1704 wand_waituntil_clause 1705 { $$ = $1; } 1706 | wor_waituntil_clause wor wand_waituntil_clause 1707 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); } 1708 | wor_waituntil_clause wor when_clause_opt ELSE statement 1709 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); } 1710 | wor_waituntil_clause wor when_clause_opt timeout statement %prec THEN 1711 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); } 1712 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1713 | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // invalid syntax rules 1714 { SemanticError( yylloc, "syntax error, else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1715 | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement 1716 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, 1717 new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, 1718 build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ), 1719 build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); } 1720 ; 1721 1722 waituntil_statement: 1723 wor_waituntil_clause %prec THEN 1724 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement. 1725 { 1726 $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) ); 1727 // $$ = new StatementNode( build_compound( yylloc, nullptr ) ); 1728 } 1639 when_clause_opt waitfor statement %prec THEN 1640 { $$ = new StatementNode( build_waitfor( $2, $3, $1 ) ); } 1641 | when_clause_opt waitfor statement WOR waitfor_clause 1642 { $$ = new StatementNode( build_waitfor( $2, $3, $1, $5 ) ); } 1729 1643 ; 1730 1644 1731 1645 exception_statement: 1732 TRY compound_statement handler_clause %prec THEN1733 { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr) ); }1646 TRY compound_statement handler_clause %prec THEN 1647 { $$ = new StatementNode( build_try( $2, $3, 0 ) ); } 1734 1648 | TRY compound_statement finally_clause 1735 { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }1649 { $$ = new StatementNode( build_try( $2, 0, $3 ) ); } 1736 1650 | TRY compound_statement handler_clause finally_clause 1737 { $$ = new StatementNode( build_try( yylloc,$2, $3, $4 ) ); }1651 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); } 1738 1652 ; 1739 1653 1740 1654 handler_clause: 1741 1655 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1742 { $$ = new ClauseNode( build_catch( yylloc,$1, $4, $6, $8 ) ); }1656 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); } 1743 1657 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1744 { $$ = $1->set_last( new ClauseNode( build_catch( yylloc,$2, $5, $7, $9 ) ) ); }1658 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); } 1745 1659 ; 1746 1660 … … 1752 1666 1753 1667 handler_key: 1754 CATCH { $$ = ast::Terminate; }1755 | RECOVER { $$ = ast::Terminate; }1756 | CATCHRESUME { $$ = ast::Resume; }1757 | FIXUP { $$ = ast::Resume; }1668 CATCH { $$ = CatchStmt::Terminate; } 1669 | RECOVER { $$ = CatchStmt::Terminate; } 1670 | CATCHRESUME { $$ = CatchStmt::Resume; } 1671 | FIXUP { $$ = CatchStmt::Resume; } 1758 1672 ; 1759 1673 1760 1674 finally_clause: 1761 FINALLY compound_statement { $$ = new ClauseNode( build_finally( yylloc,$2 ) ); }1675 FINALLY compound_statement { $$ = new StatementNode( build_finally( $2 ) ); } 1762 1676 ; 1763 1677 … … 1785 1699 asm_statement: 1786 1700 ASM asm_volatile_opt '(' string_literal ')' ';' 1787 { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr) ); }1701 { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); } 1788 1702 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC 1789 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6 ) ); }1703 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); } 1790 1704 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';' 1791 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6, $8 ) ); }1705 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); } 1792 1706 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';' 1793 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6, $8, $10 ) ); }1707 { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); } 1794 1708 | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';' 1795 { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }1709 { $$ = new StatementNode( build_asm( $2, $5, 0, $8, $10, $12 ) ); } 1796 1710 ; 1797 1711 … … 1817 1731 asm_operand: // GCC 1818 1732 string_literal '(' constant_expression ')' 1819 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1733 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); } 1820 1734 | '[' IDENTIFIER ']' string_literal '(' constant_expression ')' 1821 { 1822 $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, maybeMoveBuild( $4 ), maybeMoveBuild( $6 ) ) ); 1823 delete $2.str; 1824 } 1735 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); } 1825 1736 ; 1826 1737 … … 1829 1740 { $$ = nullptr; } // use default argument 1830 1741 | string_literal 1831 { $$ = $1; }1742 { $$ = new ExpressionNode( $1 ); } 1832 1743 | asm_clobbers_list_opt ',' string_literal 1833 { $$ = (ExpressionNode *)( $1->set_last( $3 )); }1744 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( $3 ) )); } 1834 1745 ; 1835 1746 … … 1837 1748 identifier 1838 1749 { 1839 $$ = new LabelNode(); $$->labels. emplace_back( yylloc,*$1 );1750 $$ = new LabelNode(); $$->labels.push_back( *$1 ); 1840 1751 delete $1; // allocated by lexer 1841 1752 } 1842 1753 | label_list ',' identifier 1843 1754 { 1844 $$ = $1; $1->labels. emplace_back( yylloc,*$3 );1755 $$ = $1; $1->labels.push_back( *$3 ); 1845 1756 delete $3; // allocated by lexer 1846 1757 } … … 1893 1804 { 1894 1805 // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" ); 1895 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {1806 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 1896 1807 // printf( "\tattr %s\n", attr->name.c_str() ); 1897 1808 // } // for … … 1903 1814 static_assert: 1904 1815 STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11 1905 { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 )); }1816 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); } 1906 1817 | STATICASSERT '(' constant_expression ')' ';' // CFA 1907 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc,*new string( "\"\"" ) ) ); }1818 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); } 1908 1819 1909 1820 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function … … 1969 1880 // '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict 1970 1881 // { 1971 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );1882 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true ); 1972 1883 // } 1973 1884 // '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')' 1974 1885 // { 1975 1886 // typedefTable.setNextIdentifier( *$5 ); 1976 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );1887 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1977 1888 // } 1978 1889 // | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')' 1979 1890 // { 1980 1891 // typedefTable.setNextIdentifier( *$5 ); 1981 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );1892 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1982 1893 // } 1983 1894 // | '[' ']' typegen_name … … 1991 1902 cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt 1992 1903 // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator). 1993 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr)->addQualifiers( $8 ); }1904 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); } 1994 1905 | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt 1995 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr)->addQualifiers( $8 ); }1906 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); } 1996 1907 ; 1997 1908 … … 2029 1940 { 2030 1941 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" ); 2031 if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) { 2032 SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr; 2033 } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3 1942 $$ = $3->addType( $2 )->addTypedef(); 2034 1943 } 2035 1944 | typedef_declaration pop ',' push declarator … … 2039 1948 } 2040 1949 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 ) 2041 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; } 1950 { 1951 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "6" ); 1952 $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef(); 1953 } 2042 1954 | type_specifier TYPEDEF declarator 2043 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; } 1955 { 1956 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" ); 1957 $$ = $3->addType( $1 )->addTypedef(); 1958 } 2044 1959 | type_specifier TYPEDEF type_qualifier_list declarator 2045 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; } 1960 { 1961 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" ); 1962 $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 ); 1963 } 2046 1964 ; 2047 1965 … … 2050 1968 TYPEDEF identifier '=' assignment_expression 2051 1969 { 2052 SemanticError( yylloc, "T YPEDEFexpression is deprecated, use typeof(...) instead." ); $$ = nullptr;1970 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 2053 1971 } 2054 1972 | typedef_expression pop ',' push identifier '=' assignment_expression 2055 1973 { 2056 SemanticError( yylloc, "T YPEDEFexpression is deprecated, use typeof(...) instead." ); $$ = nullptr;1974 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 2057 1975 } 2058 1976 ; … … 2064 1982 | typedef_expression // deprecated GCC, naming expression type 2065 1983 | sue_declaration_specifier 2066 {2067 assert( $1->type );2068 if ( $1->type->qualifiers.any() ) { // CV qualifiers ?2069 SemanticError( yylloc, "syntax error, useless type qualifier(s) in empty declaration." ); $$ = nullptr;2070 }2071 // enums are never empty declarations because there must have at least one enumeration.2072 if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ?2073 SemanticError( yylloc, "syntax error, useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr;2074 }2075 }2076 1984 ; 2077 1985 … … 2079 1987 // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static 2080 1988 // storage-class 2081 variable_declarator asm_name_opt initializer_opt1989 declarator asm_name_opt initializer_opt 2082 1990 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); } 2083 | variable_type_redeclarator asm_name_opt initializer_opt2084 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }2085 2086 | general_function_declarator asm_name_opt2087 { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }2088 | general_function_declarator asm_name_opt '=' VOID2089 { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }2090 2091 1991 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 2092 1992 { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); } 2093 1993 ; 2094 1994 2095 general_function_declarator:2096 function_type_redeclarator2097 | function_declarator2098 ;2099 2100 1995 declaration_specifier: // type specifier + storage class 2101 1996 basic_declaration_specifier 1997 | sue_declaration_specifier 2102 1998 | type_declaration_specifier 2103 | sue_declaration_specifier2104 | sue_declaration_specifier invalid_types // invalid syntax rule2105 {2106 SemanticError( yylloc, ::toString( "syntax error, expecting ';' at end of ",2107 $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),2108 " declaration." ) );2109 $$ = nullptr;2110 }2111 ;2112 2113 invalid_types:2114 aggregate_key2115 | basic_type_name2116 | indirect_type2117 1999 ; 2118 2000 … … 2131 2013 basic_type_specifier 2132 2014 | sue_type_specifier 2015 { 2016 // printf( "sue_type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2017 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2018 // printf( "\tattr %s\n", attr->name.c_str() ); 2019 // } // for 2020 } 2133 2021 | type_type_specifier 2134 2022 ; … … 2177 2065 { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); } 2178 2066 | forall 2179 { $$ = DeclarationNode::newForall( $1 ); }2180 2067 ; 2181 2068 2182 2069 forall: 2183 2070 FORALL '(' type_parameter_list ')' // CFA 2184 { $$ = $3; }2071 { $$ = DeclarationNode::newForall( $3 ); } 2185 2072 ; 2186 2073 … … 2339 2226 { $$ = DeclarationNode::newTypeof( $3 ); } 2340 2227 | BASETYPEOF '(' type ')' // CFA: basetypeof( x ) y; 2341 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ), true ); }2228 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); } 2342 2229 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 2343 2230 { $$ = DeclarationNode::newTypeof( $3, true ); } … … 2352 2239 { 2353 2240 // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2354 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2241 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2355 2242 // printf( "\tattr %s\n", attr->name.c_str() ); 2356 2243 // } // for … … 2368 2255 { 2369 2256 // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2370 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2257 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2371 2258 // printf( "\tattr %s\n", attr->name.c_str() ); 2372 2259 // } // for … … 2446 2333 { 2447 2334 // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2448 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2335 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2449 2336 // printf( "\tattr %s\n", attr->name.c_str() ); 2450 2337 // } // for … … 2470 2357 '{' field_declaration_list_opt '}' type_parameters_opt 2471 2358 { 2359 // printf( "aggregate_type1 %s\n", $3.str->c_str() ); 2360 // if ( $2 ) 2361 // for ( Attribute * attr: reverseIterate( $2->attributes ) ) { 2362 // printf( "copySpecifiers12 %s\n", attr->name.c_str() ); 2363 // } // for 2472 2364 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); 2365 // printf( "aggregate_type2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2366 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2367 // printf( "aggregate_type3 %s\n", attr->name.c_str() ); 2368 // } // for 2473 2369 } 2474 2370 | aggregate_key attribute_list_opt TYPEDEFname // unqualified type name … … 2479 2375 '{' field_declaration_list_opt '}' type_parameters_opt 2480 2376 { 2377 // printf( "AGG3\n" ); 2481 2378 DeclarationNode::newFromTypedef( $3 ); 2482 2379 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); … … 2489 2386 '{' field_declaration_list_opt '}' type_parameters_opt 2490 2387 { 2388 // printf( "AGG4\n" ); 2491 2389 DeclarationNode::newFromTypeGen( $3, nullptr ); 2492 2390 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); … … 2515 2413 // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and 2516 2414 // delete newFromTypeGen. 2517 if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) { 2518 $$ = $3->addQualifiers( $2 ); 2519 } else { 2520 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 ); 2521 $3->type->symbolic.name = nullptr; // copied to $$ 2522 $3->type->symbolic.actuals = nullptr; 2523 delete $3; 2524 } 2415 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 ); 2416 $3->type->symbolic.name = nullptr; 2417 $3->type->symbolic.actuals = nullptr; 2418 delete $3; 2525 2419 } 2526 2420 ; … … 2533 2427 aggregate_data: 2534 2428 STRUCT vtable_opt 2535 { $$ = ast::AggregateDecl::Struct; }2429 { $$ = AggregateDecl::Struct; } 2536 2430 | UNION 2537 { $$ = ast::AggregateDecl::Union; }2431 { $$ = AggregateDecl::Union; } 2538 2432 | EXCEPTION // CFA 2539 { $$ = ast::AggregateDecl::Exception; }2540 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }2433 { $$ = AggregateDecl::Exception; } 2434 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2541 2435 ; 2542 2436 2543 2437 aggregate_control: // CFA 2544 2438 MONITOR 2545 { $$ = ast::AggregateDecl::Monitor; }2439 { $$ = AggregateDecl::Monitor; } 2546 2440 | MUTEX STRUCT 2547 { $$ = ast::AggregateDecl::Monitor; }2441 { $$ = AggregateDecl::Monitor; } 2548 2442 | GENERATOR 2549 { $$ = ast::AggregateDecl::Generator; }2443 { $$ = AggregateDecl::Generator; } 2550 2444 | MUTEX GENERATOR 2551 { 2552 SemanticError( yylloc, "monitor generator is currently unimplemented." ); 2553 $$ = ast::AggregateDecl::NoAggregate; 2554 } 2445 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2555 2446 | COROUTINE 2556 { $$ = ast::AggregateDecl::Coroutine; }2447 { $$ = AggregateDecl::Coroutine; } 2557 2448 | MUTEX COROUTINE 2558 { 2559 SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); 2560 $$ = ast::AggregateDecl::NoAggregate; 2561 } 2449 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2562 2450 | THREAD 2563 { $$ = ast::AggregateDecl::Thread; }2451 { $$ = AggregateDecl::Thread; } 2564 2452 | MUTEX THREAD 2565 { 2566 SemanticError( yylloc, "monitor thread is currently unimplemented." ); 2567 $$ = ast::AggregateDecl::NoAggregate; 2568 } 2453 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2569 2454 ; 2570 2455 … … 2582 2467 $$ = fieldDecl( $1, $2 ); 2583 2468 // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2584 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2469 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2585 2470 // printf( "\tattr %s\n", attr->name.c_str() ); 2586 2471 // } // for 2587 2472 } 2588 | type_specifier field_declaring_list_opt '}' // invalid syntax rule2589 {2590 SemanticError( yylloc, ::toString( "syntax error, expecting ';' at end of previous declaration." ) );2591 $$ = nullptr;2592 }2593 2473 | EXTENSION type_specifier field_declaring_list_opt ';' // GCC 2594 2474 { $$ = fieldDecl( $2, $3 ); distExt( $$ ); } 2595 | STATIC type_specifier field_declaring_list_opt ';' // CFA2596 { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }2597 2475 | INLINE type_specifier field_abstract_list_opt ';' // CFA 2598 2476 { … … 2605 2483 } 2606 2484 | INLINE aggregate_control ';' // CFA 2607 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }2485 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; } 2608 2486 | typedef_declaration ';' // CFA 2609 2487 | cfa_field_declaring_list ';' // CFA, new style field declaration … … 2631 2509 { $$ = $1->addBitfield( $2 ); } 2632 2510 | variable_type_redeclarator bit_subrange_size_opt 2633 // A semantic check is required to ensure bit_subrange only appears on integral types.2634 { $$ = $1->addBitfield( $2 ); }2635 | function_type_redeclarator bit_subrange_size_opt2636 2511 // A semantic check is required to ensure bit_subrange only appears on integral types. 2637 2512 { $$ = $1->addBitfield( $2 ); } … … 2688 2563 { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); } 2689 2564 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2690 {2691 if ( $3->storageClasses.val != 0 || $3->type->qualifiers. any() ) {2692 SemanticError( yylloc, "syntax error, storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." );2693 } 2565 { 2566 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) 2567 { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2568 2694 2569 $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 ); 2695 2570 } … … 2700 2575 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt 2701 2576 { 2702 if ( $3->storageClasses.any() || $3->type->qualifiers.val != 0 ) { 2703 SemanticError( yylloc, "syntax error, storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); 2704 } 2577 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2705 2578 typedefTable.makeTypedef( *$6 ); 2706 2579 } … … 2736 2609 enum_type_nobody: // enum - {...} 2737 2610 ENUM attribute_list_opt identifier 2738 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }2611 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); } 2739 2612 | ENUM attribute_list_opt type_name 2740 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }2613 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); } 2741 2614 ; 2742 2615 … … 2878 2751 type_no_function: // sizeof, alignof, cast (constructor) 2879 2752 cfa_abstract_declarator_tuple // CFA 2880 | type_specifier // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing2753 | type_specifier 2881 2754 | type_specifier abstract_declarator 2882 2755 { $$ = $2->addType( $1 ); } … … 2923 2796 designator_list ':' // C99, CFA uses ":" instead of "=" 2924 2797 | identifier_at ':' // GCC, field name 2925 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }2798 { $$ = new ExpressionNode( build_varref( $1 ) ); } 2926 2799 ; 2927 2800 … … 2935 2808 designator: 2936 2809 '.' identifier_at // C99, field name 2937 { $$ = new ExpressionNode( build_varref( yylloc,$2 ) ); }2810 { $$ = new ExpressionNode( build_varref( $2 ) ); } 2938 2811 | '[' push assignment_expression pop ']' // C99, single array element 2939 2812 // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple. … … 2942 2815 { $$ = $3; } 2943 2816 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements 2944 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }2817 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); } 2945 2818 | '.' '[' push field_name_list pop ']' // CFA, tuple field selector 2946 2819 { $$ = $4; } … … 2982 2855 { 2983 2856 typedefTable.addToScope( *$2, TYPEDEFname, "9" ); 2984 if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }2985 if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }2986 if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }2857 if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); } 2858 if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); } 2859 if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); } 2987 2860 } 2988 2861 type_initializer_opt assertion_list_opt … … 2995 2868 { 2996 2869 typedefTable.addToScope( *$2, TYPEDIMname, "9" ); 2997 $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );2870 $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 ); 2998 2871 } 2999 2872 // | type_specifier identifier_parameter_declarator 3000 2873 | assertion_list 3001 { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }2874 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); } 3002 2875 ; 3003 2876 3004 2877 new_type_class: // CFA 3005 2878 // empty 3006 { $$ = ast::TypeDecl::Otype; }2879 { $$ = TypeDecl::Otype; } 3007 2880 | '&' 3008 { $$ = ast::TypeDecl::Dtype; }2881 { $$ = TypeDecl::Dtype; } 3009 2882 | '*' 3010 { $$ = ast::TypeDecl::DStype; } // dtype + sized2883 { $$ = TypeDecl::DStype; } // dtype + sized 3011 2884 // | '(' '*' ')' 3012 // { $$ = ast::TypeDecl::Ftype; }2885 // { $$ = TypeDecl::Ftype; } 3013 2886 | ELLIPSIS 3014 { $$ = ast::TypeDecl::Ttype; }2887 { $$ = TypeDecl::Ttype; } 3015 2888 ; 3016 2889 3017 2890 type_class: // CFA 3018 2891 OTYPE 3019 { $$ = ast::TypeDecl::Otype; }2892 { $$ = TypeDecl::Otype; } 3020 2893 | DTYPE 3021 { $$ = ast::TypeDecl::Dtype; }2894 { $$ = TypeDecl::Dtype; } 3022 2895 | FTYPE 3023 { $$ = ast::TypeDecl::Ftype; }2896 { $$ = TypeDecl::Ftype; } 3024 2897 | TTYPE 3025 { $$ = ast::TypeDecl::Ttype; }2898 { $$ = TypeDecl::Ttype; } 3026 2899 ; 3027 2900 … … 3049 2922 type_list: // CFA 3050 2923 type 3051 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }2924 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3052 2925 | assignment_expression 3053 2926 | type_list ',' type 3054 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }2927 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3055 2928 | type_list ',' assignment_expression 3056 2929 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } … … 3077 2950 { 3078 2951 typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" ); 3079 $$ = DeclarationNode::newTypeDecl( $1, nullptr);2952 $$ = DeclarationNode::newTypeDecl( $1, 0 ); 3080 2953 } 3081 2954 | identifier_or_type_name '(' type_parameter_list ')' … … 3088 2961 trait_specifier: // CFA 3089 2962 TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}' 3090 { 3091 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 3092 $$ = DeclarationNode::newTrait( $2, $4, nullptr ); 3093 } 3094 | forall TRAIT identifier_or_type_name '{' '}' // alternate 3095 { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); } 2963 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); } 3096 2964 | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}' 3097 { 3098 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 3099 $$ = DeclarationNode::newTrait( $2, $4, $8 ); 3100 } 3101 | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate 3102 { $$ = DeclarationNode::newTrait( $3, $1, $6 ); } 2965 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); } 3103 2966 ; 3104 2967 … … 3159 3022 external_definition: 3160 3023 DIRECTIVE 3161 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc,$1 ) ) ); }3024 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); } 3162 3025 | declaration 3163 {3164 // Variable declarations of anonymous types requires creating a unique type-name across multiple translation3165 // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is3166 // disallowed at the moment.3167 if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {3168 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {3169 SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;3170 } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union3171 SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;3172 }3173 }3174 }3175 3026 | IDENTIFIER IDENTIFIER 3176 3027 { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; } 3177 | IDENTIFIER type_qualifier // invalid syntax rules3028 | IDENTIFIER type_qualifier // syntax error 3178 3029 { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; } 3179 | IDENTIFIER storage_class // invalid syntax rules3030 | IDENTIFIER storage_class // syntax error 3180 3031 { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; } 3181 | IDENTIFIER basic_type_name // invalid syntax rules3032 | IDENTIFIER basic_type_name // syntax error 3182 3033 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 3183 | IDENTIFIER TYPEDEFname // invalid syntax rules3034 | IDENTIFIER TYPEDEFname // syntax error 3184 3035 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 3185 | IDENTIFIER TYPEGENname // invalid syntax rules3036 | IDENTIFIER TYPEGENname // syntax error 3186 3037 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 3187 3038 | external_function_definition … … 3192 3043 } 3193 3044 | ASM '(' string_literal ')' ';' // GCC, global assembler statement 3194 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr) ) ); }3045 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); } 3195 3046 | EXTERN STRINGliteral 3196 3047 { 3197 3048 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3198 linkage = ast::Linkage::update( yylloc, linkage, $2 );3049 linkage = LinkageSpec::update( yylloc, linkage, $2 ); 3199 3050 } 3200 3051 up external_definition down … … 3207 3058 { 3208 3059 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3209 linkage = ast::Linkage::update( yylloc, linkage, $2 );3060 linkage = LinkageSpec::update( yylloc, linkage, $2 ); 3210 3061 } 3211 3062 '{' up external_definition_list_opt down '}' … … 3218 3069 | type_qualifier_list 3219 3070 { 3220 if ( $1->type->qualifiers.any() ) { 3221 SemanticError( yylloc, "syntax error, CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); 3222 } 3071 if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3223 3072 if ( $1->type->forall ) forall = true; // remember generic type 3224 3073 } … … 3226 3075 { 3227 3076 distQual( $5, $1 ); 3228 forall = false;3077 forall = false; 3229 3078 $$ = $5; 3230 3079 } 3231 3080 | declaration_qualifier_list 3232 3081 { 3233 if ( $1->type && $1->type->qualifiers.any() ) { 3234 SemanticError( yylloc, "syntax error, CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); 3235 } 3082 if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3236 3083 if ( $1->type && $1->type->forall ) forall = true; // remember generic type 3237 3084 } … … 3239 3086 { 3240 3087 distQual( $5, $1 ); 3241 forall = false;3088 forall = false; 3242 3089 $$ = $5; 3243 3090 } 3244 3091 | declaration_qualifier_list type_qualifier_list 3245 3092 { 3246 if ( ($1->type && $1->type->qualifiers.any()) || ($2->type && $2->type->qualifiers.any()) ) { 3247 SemanticError( yylloc, "syntax error, CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); 3248 } 3093 if ( ($1->type && $1->type->qualifiers.val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3249 3094 if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type 3250 3095 } … … 3252 3097 { 3253 3098 distQual( $6, $1->addQualifiers( $2 ) ); 3254 forall = false;3099 forall = false; 3255 3100 $$ = $6; 3256 3101 } … … 3277 3122 $$ = $3; forall = false; 3278 3123 if ( $5 ) { 3279 SemanticError( yylloc, " syntax error, attributes cannot be associated with function body. Move attribute(s) before \"with\" clause." );3124 SemanticError( yylloc, "Attributes cannot be associated with function body. Move attribute(s) before \"with\" clause." ); 3280 3125 $$ = nullptr; 3281 3126 } // if … … 3296 3141 $$ = $2->addFunctionBody( $4, $3 )->addType( $1 ); 3297 3142 } 3298 | declaration_specifier function_type_redeclarator with_clause_opt compound_statement3143 | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement 3299 3144 { 3300 3145 rebindForall( $1, $2 ); … … 3332 3177 | variable_type_redeclarator 3333 3178 | function_declarator 3334 | function_type_redeclarator3335 3179 ; 3336 3180 3337 3181 subrange: 3338 3182 constant_expression '~' constant_expression // CFA, integer subrange 3339 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }3183 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); } 3340 3184 ; 3341 3185 … … 3346 3190 { 3347 3191 DeclarationNode * name = new DeclarationNode(); 3348 name->asmName = maybeMoveBuild( $3 );3192 name->asmName = $3; 3349 3193 $$ = name->addQualifiers( $5 ); 3350 3194 } … … 3443 3287 variable_ptr: 3444 3288 ptrref_operator variable_declarator 3445 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3289 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3446 3290 | ptrref_operator type_qualifier_list variable_declarator 3447 3291 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3459 3303 | '(' attribute_list variable_ptr ')' array_dimension 3460 3304 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3461 | '(' variable_array ')' multi_array_dimension // redundant parenthesis3305 | '(' variable_array ')' multi_array_dimension // redundant parenthesis 3462 3306 { $$ = $2->addArray( $4 ); } 3463 3307 | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis … … 3507 3351 function_ptr: 3508 3352 ptrref_operator function_declarator 3509 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3353 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3510 3354 | ptrref_operator type_qualifier_list function_declarator 3511 3355 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3559 3403 KR_function_ptr: 3560 3404 ptrref_operator KR_function_declarator 3561 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3405 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3562 3406 | ptrref_operator type_qualifier_list KR_function_declarator 3563 3407 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3583 3427 ; 3584 3428 3585 // This pattern parses a declaration for a variable that redefines a type name, e.g.:3429 // This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.: 3586 3430 // 3587 3431 // typedef int foo; … … 3589 3433 // int foo; // redefine typedef name in new scope 3590 3434 // } 3435 // 3436 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 3437 // and functions versus pointers to arrays and functions. 3591 3438 3592 3439 paren_type: … … 3603 3450 paren_type attribute_list_opt 3604 3451 { $$ = $1->addQualifiers( $2 ); } 3605 | variable_type_ptr3606 | variable_type_array attribute_list_opt3452 | type_ptr 3453 | type_array attribute_list_opt 3607 3454 { $$ = $1->addQualifiers( $2 ); } 3608 | variable_type_function attribute_list_opt3455 | type_function attribute_list_opt 3609 3456 { $$ = $1->addQualifiers( $2 ); } 3610 3457 ; 3611 3458 3612 variable_type_ptr:3459 type_ptr: 3613 3460 ptrref_operator variable_type_redeclarator 3614 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3461 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3615 3462 | ptrref_operator type_qualifier_list variable_type_redeclarator 3616 3463 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3617 | '(' variable_type_ptr ')' attribute_list_opt// redundant parenthesis3464 | '(' type_ptr ')' attribute_list_opt // redundant parenthesis 3618 3465 { $$ = $2->addQualifiers( $4 ); } 3619 | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis3466 | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis 3620 3467 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3621 3468 ; 3622 3469 3623 variable_type_array:3470 type_array: 3624 3471 paren_type array_dimension 3625 3472 { $$ = $1->addArray( $2 ); } 3626 | '(' variable_type_ptr ')' array_dimension3473 | '(' type_ptr ')' array_dimension 3627 3474 { $$ = $2->addArray( $4 ); } 3628 | '(' attribute_list variable_type_ptr ')' array_dimension3475 | '(' attribute_list type_ptr ')' array_dimension 3629 3476 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3630 | '(' variable_type_array ')' multi_array_dimension// redundant parenthesis3477 | '(' type_array ')' multi_array_dimension // redundant parenthesis 3631 3478 { $$ = $2->addArray( $4 ); } 3632 | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis3479 | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis 3633 3480 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3634 | '(' variable_type_array ')'// redundant parenthesis3481 | '(' type_array ')' // redundant parenthesis 3635 3482 { $$ = $2; } 3636 | '(' attribute_list variable_type_array ')'// redundant parenthesis3483 | '(' attribute_list type_array ')' // redundant parenthesis 3637 3484 { $$ = $3->addQualifiers( $2 ); } 3638 3485 ; 3639 3486 3640 variable_type_function: 3641 '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3642 { $$ = $2->addParamList( $6 ); } 3643 | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3644 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3645 | '(' variable_type_function ')' // redundant parenthesis 3646 { $$ = $2; } 3647 | '(' attribute_list variable_type_function ')' // redundant parenthesis 3648 { $$ = $3->addQualifiers( $2 ); } 3649 ; 3650 3651 // This pattern parses a declaration for a function prototype that redefines a type name. It precludes declaring an 3652 // array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to 3653 // arrays and functions. 3654 3655 function_type_redeclarator: 3656 function_type_no_ptr attribute_list_opt 3657 { $$ = $1->addQualifiers( $2 ); } 3658 | function_type_ptr 3659 | function_type_array attribute_list_opt 3660 { $$ = $1->addQualifiers( $2 ); } 3661 ; 3662 3663 function_type_no_ptr: 3487 type_function: 3664 3488 paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3665 3489 { $$ = $1->addParamList( $4 ); } 3666 | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'3490 | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3667 3491 { $$ = $2->addParamList( $6 ); } 3668 | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'3492 | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3669 3493 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3670 | '(' function_type_no_ptr ')'// redundant parenthesis3494 | '(' type_function ')' // redundant parenthesis 3671 3495 { $$ = $2; } 3672 | '(' attribute_list function_type_no_ptr ')' // redundant parenthesis 3673 { $$ = $3->addQualifiers( $2 ); } 3674 ; 3675 3676 function_type_ptr: 3677 ptrref_operator function_type_redeclarator 3678 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3679 | ptrref_operator type_qualifier_list function_type_redeclarator 3680 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3681 | '(' function_type_ptr ')' attribute_list_opt 3682 { $$ = $2->addQualifiers( $4 ); } 3683 | '(' attribute_list function_type_ptr ')' attribute_list_opt 3684 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3685 ; 3686 3687 function_type_array: 3688 '(' function_type_ptr ')' array_dimension 3689 { $$ = $2->addArray( $4 ); } 3690 | '(' attribute_list function_type_ptr ')' array_dimension 3691 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3692 | '(' function_type_array ')' multi_array_dimension // redundant parenthesis 3693 { $$ = $2->addArray( $4 ); } 3694 | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis 3695 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3696 | '(' function_type_array ')' // redundant parenthesis 3697 { $$ = $2; } 3698 | '(' attribute_list function_type_array ')' // redundant parenthesis 3496 | '(' attribute_list type_function ')' // redundant parenthesis 3699 3497 { $$ = $3->addQualifiers( $2 ); } 3700 3498 ; … … 3719 3517 identifier_parameter_ptr: 3720 3518 ptrref_operator identifier_parameter_declarator 3721 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3519 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3722 3520 | ptrref_operator type_qualifier_list identifier_parameter_declarator 3723 3521 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3776 3574 type_parameter_ptr: 3777 3575 ptrref_operator type_parameter_redeclarator 3778 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3576 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3779 3577 | ptrref_operator type_qualifier_list type_parameter_redeclarator 3780 3578 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3819 3617 abstract_ptr: 3820 3618 ptrref_operator 3821 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }3619 { $$ = DeclarationNode::newPointer( 0, $1 ); } 3822 3620 | ptrref_operator type_qualifier_list 3823 3621 { $$ = DeclarationNode::newPointer( $2, $1 ); } 3824 3622 | ptrref_operator abstract_declarator 3825 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3623 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3826 3624 | ptrref_operator type_qualifier_list abstract_declarator 3827 3625 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3852 3650 // Only the first dimension can be empty. 3853 3651 '[' ']' 3854 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }3652 { $$ = DeclarationNode::newArray( 0, 0, false ); } 3855 3653 | '[' ']' multi_array_dimension 3856 { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }3654 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); } 3857 3655 // Cannot use constant_expression because of tuples => semantic check 3858 3656 | '[' push assignment_expression pop ',' comma_expression ']' // CFA 3859 { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }3657 { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); } 3860 3658 // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; } 3861 3659 | '[' push array_type_list pop ']' // CFA … … 3866 3664 array_type_list: 3867 3665 basic_type_name 3868 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3666 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3869 3667 | type_name 3870 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3668 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3871 3669 | assignment_expression upupeq assignment_expression 3872 3670 | array_type_list ',' basic_type_name 3873 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3874 | array_type_list ',' type_name 3875 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3671 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3672 | array_type_list ',' type_name 3673 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3876 3674 | array_type_list ',' assignment_expression upupeq assignment_expression 3877 3675 ; … … 3882 3680 | ErangeUpEq 3883 3681 { $$ = OperKinds::LEThan; } 3884 ;3682 ; 3885 3683 3886 3684 multi_array_dimension: 3887 3685 '[' push assignment_expression pop ']' 3888 { $$ = DeclarationNode::newArray( $3, nullptr, false ); }3686 { $$ = DeclarationNode::newArray( $3, 0, false ); } 3889 3687 | '[' push '*' pop ']' // C99 3890 3688 { $$ = DeclarationNode::newVarArray( 0 ); } 3891 3689 | multi_array_dimension '[' push assignment_expression pop ']' 3892 { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }3690 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); } 3893 3691 | multi_array_dimension '[' push '*' pop ']' // C99 3894 3692 { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); } … … 3987 3785 array_parameter_1st_dimension: 3988 3786 '[' ']' 3989 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }3787 { $$ = DeclarationNode::newArray( 0, 0, false ); } 3990 3788 // multi_array_dimension handles the '[' '*' ']' case 3991 3789 | '[' push type_qualifier_list '*' pop ']' // remaining C99 3992 3790 { $$ = DeclarationNode::newVarArray( $3 ); } 3993 3791 | '[' push type_qualifier_list pop ']' 3994 { $$ = DeclarationNode::newArray( nullptr, $3, false ); }3792 { $$ = DeclarationNode::newArray( 0, $3, false ); } 3995 3793 // multi_array_dimension handles the '[' assignment_expression ']' case 3996 3794 | '[' push type_qualifier_list assignment_expression pop ']' … … 4021 3819 variable_abstract_ptr: 4022 3820 ptrref_operator 4023 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }3821 { $$ = DeclarationNode::newPointer( 0, $1 ); } 4024 3822 | ptrref_operator type_qualifier_list 4025 3823 { $$ = DeclarationNode::newPointer( $2, $1 ); } 4026 3824 | ptrref_operator variable_abstract_declarator 4027 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3825 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4028 3826 | ptrref_operator type_qualifier_list variable_abstract_declarator 4029 3827 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 4067 3865 // No SUE declaration in parameter list. 4068 3866 ptrref_operator type_specifier_nobody 4069 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3867 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4070 3868 | type_qualifier_list ptrref_operator type_specifier_nobody 4071 3869 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4072 3870 | ptrref_operator cfa_abstract_function 4073 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3871 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4074 3872 | type_qualifier_list ptrref_operator cfa_abstract_function 4075 3873 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4076 3874 | ptrref_operator cfa_identifier_parameter_declarator_tuple 4077 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3875 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4078 3876 | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple 4079 3877 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } … … 4084 3882 // shift/reduce conflict with new-style empty (void) function return type. 4085 3883 '[' ']' type_specifier_nobody 4086 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3884 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4087 3885 | cfa_array_parameter_1st_dimension type_specifier_nobody 4088 3886 { $$ = $2->addNewArray( $1 ); } 4089 3887 | '[' ']' multi_array_dimension type_specifier_nobody 4090 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3888 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4091 3889 | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody 4092 3890 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } … … 4095 3893 4096 3894 | '[' ']' cfa_identifier_parameter_ptr 4097 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3895 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4098 3896 | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr 4099 3897 { $$ = $2->addNewArray( $1 ); } 4100 3898 | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr 4101 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3899 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4102 3900 | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr 4103 3901 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } … … 4155 3953 cfa_abstract_ptr: // CFA 4156 3954 ptrref_operator type_specifier 4157 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3955 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4158 3956 | type_qualifier_list ptrref_operator type_specifier 4159 3957 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4160 3958 | ptrref_operator cfa_abstract_function 4161 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3959 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4162 3960 | type_qualifier_list ptrref_operator cfa_abstract_function 4163 3961 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4164 3962 | ptrref_operator cfa_abstract_declarator_tuple 4165 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3963 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4166 3964 | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple 4167 3965 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
Note:
See TracChangeset
for help on using the changeset viewer.