Changes in src/Parser/parser.yy [32d6fdc:997185e]
- File:
-
- 1 edited
-
src/Parser/parser.yy (modified) (152 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/parser.yy
r32d6fdc r997185e 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tue Apr 4 14:02:00 202313 // Update Count : 632911 // Last Modified By : Peter A. Buhr 12 // 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 ) { … … 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 204 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." … … 210 206 #define MISSING_HIGH "Missing high value for down-to range so index is uninitialized." 211 207 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 ) { 208 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 233 209 if ( index->initializer ) { 234 210 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); … … 237 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 243 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; … … 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 * s tmt;307 ClauseNode * clause;308 ast::WaitForStmt * wfs;286 AggregateDecl::Aggregate aggKey; 287 TypeDecl::Kind tclass; 288 StatementNode * sn; 289 WaitForStmt * wfs; 290 Expression * constant; 309 291 CondCtl * ifctl; 310 ForCtrl * forctl; 311 LabelNode * labels; 312 InitializerNode * init; 313 OperKinds oper; 292 ForCtrl * fctl; 293 OperKinds compop; 294 LabelNode * label; 295 InitializerNode * in; 296 OperKinds op; 314 297 std::string * str; 315 bool is_volatile;316 EnumHiding enum_hiding;317 ast::ExceptionKind except_kind;318 ast::GenericExpr * genexpr;298 bool flag; 299 EnumHiding hide; 300 CatchStmt::Kind catch_kind; 301 GenericExpr * genexpr; 319 302 } 320 303 321 // ************************ TERMINAL TOKENS ********************************304 //************************* TERMINAL TOKENS ******************************** 322 305 323 306 // keywords … … 348 331 %token ATTRIBUTE EXTENSION // GCC 349 332 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN 350 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR WAITUNTIL// CFA333 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR // CFA 351 334 %token DISABLE ENABLE TRY THROW THROWRESUME AT // CFA 352 335 %token ASM // C99, extension ISO/IEC 9899:1999 Section J.5.10(1) … … 354 337 355 338 // names and constants: lexer differentiates between identifier and typedef names 356 %token<tok> IDENTIFIER TYPEDIMname TYPEDEFname TYPEGENname357 %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 358 341 %token<tok> INTEGERconstant CHARACTERconstant STRINGliteral 359 342 %token<tok> DIRECTIVE … … 381 364 %type<tok> identifier identifier_at identifier_or_type_name attr_name 382 365 %type<tok> quasi_keyword 383 %type< expr> string_literal366 %type<constant> string_literal 384 367 %type<str> string_literal_list 385 368 386 %type< enum_hiding> hide_opt visible_hide_opt369 %type<hide> hide_opt visible_hide_opt 387 370 388 371 // expressions 389 %type<e xpr> constant390 %type<e xpr> tuple tuple_expression_list391 %type<op er> ptrref_operator unary_operator assignment_operator simple_assignment_operator compound_assignment_operator392 %type<e xpr> primary_expression postfix_expression unary_expression393 %type<e xpr> cast_expression_list cast_expression exponential_expression multiplicative_expression additive_expression394 %type<e xpr> shift_expression relational_expression equality_expression395 %type<e xpr> AND_expression exclusive_OR_expression inclusive_OR_expression396 %type<e xpr> logical_AND_expression logical_OR_expression397 %type<e xpr> conditional_expression constant_expression assignment_expression assignment_expression_opt398 %type<e xpr> comma_expression comma_expression_opt399 %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 400 383 %type<ifctl> conditional_declaration 401 %type<f orctl> for_control_expression for_control_expression_list402 %type< oper> upupeq updown updowneq downupdowneq403 %type<e xpr> subrange384 %type<fctl> for_control_expression for_control_expression_list 385 %type<compop> upupeq updown updowneq downupdowneq 386 %type<en> subrange 404 387 %type<decl> asm_name_opt 405 %type<e xpr> asm_operands_opt asm_operands_list asm_operand406 %type<label s> label_list407 %type<e xpr> asm_clobbers_list_opt408 %type< is_volatile> asm_volatile_opt409 %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 410 393 %type<genexpr> generic_association generic_assoc_list 411 394 412 395 // statements 413 %type<stmt> statement labeled_statement compound_statement 414 %type<stmt> statement_decl statement_decl_list statement_list_nodecl 415 %type<stmt> selection_statement if_statement 416 %type<clause> switch_clause_list_opt switch_clause_list 417 %type<expr> case_value 418 %type<clause> case_clause case_value_list case_label case_label_list 419 %type<stmt> iteration_statement jump_statement 420 %type<stmt> expression_statement asm_statement 421 %type<stmt> with_statement 422 %type<expr> with_clause_opt 423 %type<stmt> exception_statement 424 %type<clause> handler_clause finally_clause 425 %type<except_kind> handler_key 426 %type<stmt> mutex_statement 427 %type<expr> when_clause when_clause_opt waitfor waituntil timeout 428 %type<stmt> waitfor_statement waituntil_statement 429 %type<wfs> wor_waitfor_clause 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 430 412 431 413 // declarations … … 439 421 %type<decl> assertion assertion_list assertion_list_opt 440 422 441 %type<e xpr> bit_subrange_size_opt bit_subrange_size423 %type<en> bit_subrange_size_opt bit_subrange_size 442 424 443 425 %type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type … … 452 434 453 435 %type<decl> enumerator_list enum_type enum_type_nobody 454 %type<in it> enumerator_value_opt436 %type<in> enumerator_value_opt 455 437 456 438 %type<decl> external_definition external_definition_list external_definition_list_opt … … 459 441 460 442 %type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract 461 %type<e xpr> field field_name_list field_name fraction_constants_opt443 %type<en> field field_name_list field_name fraction_constants_opt 462 444 463 445 %type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr … … 500 482 %type<decl> typedef_name typedef_declaration typedef_expression 501 483 502 %type<decl> variable_type_redeclarator variable_type_ptr variable_type_array variable_type_function 503 %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 504 485 505 486 %type<decl> type_parameter_redeclarator type_parameter_ptr type_parameter_array type_parameter_function … … 508 489 %type<decl> type_parameter type_parameter_list type_initializer_opt 509 490 510 %type<e xpr> type_parameters_opt type_list array_type_list491 %type<en> type_parameters_opt type_list array_type_list 511 492 512 493 %type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list … … 519 500 520 501 // initializers 521 %type<in it> initializer initializer_list_opt initializer_opt502 %type<in> initializer initializer_list_opt initializer_opt 522 503 523 504 // designators 524 %type<e xpr> designator designator_list designation505 %type<en> designator designator_list designation 525 506 526 507 … … 531 512 // Similar issues exit with the waitfor statement. 532 513 533 // Order of these lines matters (low-to-high precedence). THEN is left associative over W AND/WOR/TIMEOUT/ELSE, WAND/WOR534 // 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. 535 516 %precedence THEN // rule precedence for IF/WAITFOR statement 536 %precedence ANDAND // token precedence for start of WAND in WAITFOR statement537 %precedence WAND // token precedence for start of WAND in WAITFOR statement538 %precedence OROR // token precedence for start of WOR in WAITFOR statement539 517 %precedence WOR // token precedence for start of WOR in WAITFOR statement 540 518 %precedence TIMEOUT // token precedence for start of TIMEOUT in WAITFOR statement … … 614 592 constant: 615 593 // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant". 616 INTEGERconstant { $$ = new ExpressionNode( build_constantInteger( yylloc,*$1 ) ); }617 | FLOATING_DECIMALconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }618 | FLOATING_FRACTIONconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }619 | FLOATINGconstant { $$ = new ExpressionNode( build_constantFloat( yylloc,*$1 ) ); }620 | 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 ) ); } 621 599 ; 622 600 623 601 quasi_keyword: // CFA 624 602 TIMEOUT 625 | WAND626 603 | WOR 627 604 | CATCH … … 644 621 645 622 string_literal: 646 string_literal_list { $$ = new ExpressionNode( build_constantStr( yylloc, *$1 )); }623 string_literal_list { $$ = build_constantStr( *$1 ); } 647 624 ; 648 625 … … 661 638 primary_expression: 662 639 IDENTIFIER // typedef name cannot be used as a variable name 663 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }640 { $$ = new ExpressionNode( build_varref( $1 ) ); } 664 641 | quasi_keyword 665 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }642 { $$ = new ExpressionNode( build_varref( $1 ) ); } 666 643 | TYPEDIMname // CFA, generic length argument 667 644 // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); } 668 645 // { $$ = new ExpressionNode( build_varref( $1 ) ); } 669 { $$ = new ExpressionNode( build_dimensionref( yylloc,$1 ) ); }646 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); } 670 647 | tuple 671 648 | '(' comma_expression ')' 672 649 { $$ = $2; } 673 650 | '(' compound_statement ')' // GCC, lambda expression 674 { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2) ) ) ); }651 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); } 675 652 | type_name '.' identifier // CFA, nested type 676 { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc,$3 ) ) ); }653 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); } 677 654 | type_name '.' '[' field_name_list ']' // CFA, nested type / tuple field selector 678 655 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } … … 680 657 { 681 658 // add the missing control expression to the GenericExpr and return it 682 $5->control = maybeMoveBuild ( $3 );659 $5->control = maybeMoveBuild<Expression>( $3 ); 683 660 $$ = new ExpressionNode( $5 ); 684 661 } … … 706 683 { 707 684 // steal the association node from the singleton and delete the wrapper 708 assert( 1 == $3->associations.size() ); 709 $1->associations.push_back( $3->associations.front() ); 685 $1->associations.splice($1->associations.end(), $3->associations); 710 686 delete $3; 711 687 $$ = $1; … … 717 693 { 718 694 // create a GenericExpr wrapper with one association pair 719 $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } );695 $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>( $3 ) } } ); 720 696 } 721 697 | DEFAULT ':' assignment_expression 722 { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); }698 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>( $3 ) } } ); } 723 699 ; 724 700 … … 729 705 // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts. 730 706 // Current: Commas in subscripts make tuples. 731 { $$ = 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 ) ) )) ) ); } 732 708 | postfix_expression '[' assignment_expression ']' 733 709 // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a … … 735 711 // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is 736 712 // equivalent to the old x[i,j]. 737 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Index, $1, $3 ) ); }713 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); } 738 714 | constant '[' assignment_expression ']' // 3[a], 'a'[a], 3.5[a] 739 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Index, $1, $3 ) ); }715 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); } 740 716 | string_literal '[' assignment_expression ']' // "abc"[3], 3["abc"] 741 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }717 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); } 742 718 | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call 743 719 { 744 720 Token fn; 745 721 fn.str = new std::string( "?{}" ); // location undefined - use location of '{'? 746 $$ = 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 ) ) ) ); 747 723 } 748 724 | postfix_expression '(' argument_expression_list_opt ')' 749 { $$ = new ExpressionNode( build_func( yylloc,$1, $3 ) ); }725 { $$ = new ExpressionNode( build_func( $1, $3 ) ); } 750 726 | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')' 751 727 // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; } 752 { $$ = 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") ) ), 753 729 (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); } 754 730 | postfix_expression '`' identifier // CFA, postfix call 755 { $$ = 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 ) ); } 756 732 | constant '`' identifier // CFA, postfix call 757 { $$ = 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 ) ); } 758 734 | string_literal '`' identifier // CFA, postfix call 759 { $$ = 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 ) ) ); } 760 736 | postfix_expression '.' identifier 761 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc,$3 ) ) ); }737 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); } 762 738 | postfix_expression '.' INTEGERconstant // CFA, tuple index 763 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc,*$3 ) ) ); }739 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); } 764 740 | postfix_expression FLOATING_FRACTIONconstant // CFA, tuple index 765 { $$ = 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 ) ) ); } 766 742 | postfix_expression '.' '[' field_name_list ']' // CFA, tuple field selector 767 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }743 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 768 744 | postfix_expression '.' aggregate_control 769 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$3, $1 ) ); }745 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); } 770 746 | postfix_expression ARROW identifier 771 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc,$3 ) ) ); }747 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); } 772 748 | postfix_expression ARROW INTEGERconstant // CFA, tuple index 773 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc,*$3 ) ) ); }749 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); } 774 750 | postfix_expression ARROW '[' field_name_list ']' // CFA, tuple field selector 775 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }751 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); } 776 752 | postfix_expression ICR 777 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::IncrPost, $1 ) ); }753 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); } 778 754 | postfix_expression DECR 779 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::DecrPost, $1 ) ); }755 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, $1 ) ); } 780 756 | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal 781 { $$ = new ExpressionNode( build_compoundLiteral( yylloc,$2, new InitializerNode( $5, true ) ) ); }757 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); } 782 758 | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal 783 { $$ = 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 ) ) ); } 784 760 | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call 785 761 { 786 762 Token fn; 787 763 fn.str = new string( "^?{}" ); // location undefined 788 $$ = 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 ) ) ); 789 765 } 790 766 ; … … 805 781 '@' // CFA, default parameter 806 782 { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; } 807 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }783 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); } 808 784 | assignment_expression 809 785 ; … … 817 793 field_name 818 794 | FLOATING_DECIMALconstant field 819 { $$ = 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 ) ) ); } 820 796 | FLOATING_DECIMALconstant '[' field_name_list ']' 821 { $$ = 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 ) ) ); } 822 798 | field_name '.' field 823 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }799 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); } 824 800 | field_name '.' '[' field_name_list ']' 825 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }801 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 826 802 | field_name ARROW field 827 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }803 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); } 828 804 | field_name ARROW '[' field_name_list ']' 829 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc,$4 ) ) ); }805 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); } 830 806 ; 831 807 832 808 field_name: 833 809 INTEGERconstant fraction_constants_opt 834 { $$ = 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 ) ); } 835 811 | FLOATINGconstant fraction_constants_opt 836 { $$ = 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 ) ); } 837 813 | identifier_at fraction_constants_opt // CFA, allow anonymous fields 838 814 { 839 $$ = 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 ) ); 840 816 } 841 817 ; … … 846 822 | fraction_constants_opt FLOATING_FRACTIONconstant 847 823 { 848 ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc,*$2 );849 $$ = $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 ); 850 826 } 851 827 ; … … 857 833 | constant 858 834 | string_literal 859 { $$ = $1; }835 { $$ = new ExpressionNode( $1 ); } 860 836 | EXTENSION cast_expression // GCC 861 837 { $$ = $2->set_extension( true ); } … … 866 842 { 867 843 switch ( $1 ) { 868 case OperKinds::AddressOf:869 $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );844 case OperKinds::AddressOf: 845 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ); 870 846 break; 871 case OperKinds::PointTo:872 $$ = new ExpressionNode( build_unary_val( yylloc,$1, $2 ) );847 case OperKinds::PointTo: 848 $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); 873 849 break; 874 case OperKinds::And:875 $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );850 case OperKinds::And: 851 $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ) ); 876 852 break; 877 default:853 default: 878 854 assert( false ); 879 855 } 880 856 } 881 857 | unary_operator cast_expression 882 { $$ = new ExpressionNode( build_unary_val( yylloc,$1, $2 ) ); }858 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); } 883 859 | ICR unary_expression 884 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::Incr, $2 ) ); }860 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Incr, $2 ) ); } 885 861 | DECR unary_expression 886 { $$ = new ExpressionNode( build_unary_val( yylloc,OperKinds::Decr, $2 ) ); }862 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Decr, $2 ) ); } 887 863 | SIZEOF unary_expression 888 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }864 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild<Expression>( $2 ) ) ); } 889 865 | SIZEOF '(' type_no_function ')' 890 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc,maybeMoveBuildType( $3 ) ) ); }866 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); } 891 867 | ALIGNOF unary_expression // GCC, variable alignment 892 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }868 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild<Expression>( $2 ) ) ); } 893 869 | ALIGNOF '(' type_no_function ')' // GCC, type alignment 894 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc,maybeMoveBuildType( $3 ) ) ); }870 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); } 895 871 | OFFSETOF '(' type_no_function ',' identifier ')' 896 { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc,$5 ) ) ); }872 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); } 897 873 | TYPEID '(' type_no_function ')' 898 874 { … … 919 895 unary_expression 920 896 | '(' type_no_function ')' cast_expression 921 { $$ = new ExpressionNode( build_cast( yylloc,$2, $4 ) ); }897 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 922 898 | '(' aggregate_control '&' ')' cast_expression // CFA 923 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$2, $5 ) ); }899 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 924 900 | '(' aggregate_control '*' ')' cast_expression // CFA 925 { $$ = new ExpressionNode( build_keyword_cast( yylloc,$2, $5 ) ); }901 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 926 902 | '(' VIRTUAL ')' cast_expression // CFA 927 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }903 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $4 ), maybeMoveBuildType( nullptr ) ) ); } 928 904 | '(' VIRTUAL type_no_function ')' cast_expression // CFA 929 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }905 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $5 ), maybeMoveBuildType( $3 ) ) ); } 930 906 | '(' RETURN type_no_function ')' cast_expression // CFA 931 907 { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; } … … 935 911 { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; } 936 912 // | '(' type_no_function ')' tuple 937 // { $$ = new ast::ExpressionNode( build_cast( yylloc,$2, $4 ) ); }913 // { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 938 914 ; 939 915 … … 953 929 cast_expression 954 930 | exponential_expression '\\' cast_expression 955 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Exp, $1, $3 ) ); }931 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); } 956 932 ; 957 933 … … 959 935 exponential_expression 960 936 | multiplicative_expression '*' exponential_expression 961 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Mul, $1, $3 ) ); }937 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); } 962 938 | multiplicative_expression '/' exponential_expression 963 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Div, $1, $3 ) ); }939 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); } 964 940 | multiplicative_expression '%' exponential_expression 965 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Mod, $1, $3 ) ); }941 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); } 966 942 ; 967 943 … … 969 945 multiplicative_expression 970 946 | additive_expression '+' multiplicative_expression 971 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Plus, $1, $3 ) ); }947 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); } 972 948 | additive_expression '-' multiplicative_expression 973 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Minus, $1, $3 ) ); }949 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); } 974 950 ; 975 951 … … 977 953 additive_expression 978 954 | shift_expression LS additive_expression 979 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LShift, $1, $3 ) ); }955 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); } 980 956 | shift_expression RS additive_expression 981 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::RShift, $1, $3 ) ); }957 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); } 982 958 ; 983 959 … … 985 961 shift_expression 986 962 | relational_expression '<' shift_expression 987 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LThan, $1, $3 ) ); }963 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); } 988 964 | relational_expression '>' shift_expression 989 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::GThan, $1, $3 ) ); }965 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); } 990 966 | relational_expression LE shift_expression 991 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::LEThan, $1, $3 ) ); }967 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); } 992 968 | relational_expression GE shift_expression 993 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::GEThan, $1, $3 ) ); }969 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); } 994 970 ; 995 971 … … 997 973 relational_expression 998 974 | equality_expression EQ relational_expression 999 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Eq, $1, $3 ) ); }975 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); } 1000 976 | equality_expression NE relational_expression 1001 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Neq, $1, $3 ) ); }977 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); } 1002 978 ; 1003 979 … … 1005 981 equality_expression 1006 982 | AND_expression '&' equality_expression 1007 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::BitAnd, $1, $3 ) ); }983 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); } 1008 984 ; 1009 985 … … 1011 987 AND_expression 1012 988 | exclusive_OR_expression '^' AND_expression 1013 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::Xor, $1, $3 ) ); }989 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); } 1014 990 ; 1015 991 … … 1017 993 exclusive_OR_expression 1018 994 | inclusive_OR_expression '|' exclusive_OR_expression 1019 { $$ = new ExpressionNode( build_binary_val( yylloc,OperKinds::BitOr, $1, $3 ) ); }995 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); } 1020 996 ; 1021 997 … … 1023 999 inclusive_OR_expression 1024 1000 | logical_AND_expression ANDAND inclusive_OR_expression 1025 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr) ); }1001 { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); } 1026 1002 ; 1027 1003 … … 1029 1005 logical_AND_expression 1030 1006 | logical_OR_expression OROR logical_AND_expression 1031 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr) ); }1007 { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); } 1032 1008 ; 1033 1009 … … 1035 1011 logical_OR_expression 1036 1012 | logical_OR_expression '?' comma_expression ':' conditional_expression 1037 { $$ = new ExpressionNode( build_cond( yylloc,$1, $3, $5 ) ); }1013 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); } 1038 1014 // FIX ME: computes $1 twice 1039 1015 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand 1040 { $$ = new ExpressionNode( build_cond( yylloc,$1, $1, $4 ) ); }1016 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); } 1041 1017 ; 1042 1018 … … 1053 1029 // SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr; 1054 1030 // } else { 1055 $$ = new ExpressionNode( build_binary_val( yylloc,$2, $1, $3 ) );1031 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); 1056 1032 // } // if 1057 1033 } … … 1098 1074 // { $$ = new ExpressionNode( build_tuple( $3 ) ); } 1099 1075 '[' ',' tuple_expression_list ']' 1100 { $$ = new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }1076 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); } 1101 1077 | '[' push assignment_expression pop ',' tuple_expression_list ']' 1102 { $$ = new ExpressionNode( build_tuple( yylloc,(ExpressionNode *)($3->set_last( $6 ) ) )); }1078 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); } 1103 1079 ; 1104 1080 … … 1116 1092 assignment_expression 1117 1093 | comma_expression ',' assignment_expression 1118 { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1094 { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); } 1119 1095 ; 1120 1096 … … 1137 1113 | mutex_statement 1138 1114 | waitfor_statement 1139 | waituntil_statement1140 1115 | exception_statement 1141 1116 | enable_disable_statement … … 1143 1118 | asm_statement 1144 1119 | DIRECTIVE 1145 { $$ = new StatementNode( build_directive( yylloc,$1 ) ); }1120 { $$ = new StatementNode( build_directive( $1 ) ); } 1146 1121 ; 1147 1122 … … 1149 1124 // labels cannot be identifiers 0 or 1 1150 1125 identifier_or_type_name ':' attribute_list_opt statement 1151 { $$ = $4->add_label( yylloc,$1, $3 ); }1126 { $$ = $4->add_label( $1, $3 ); } 1152 1127 | identifier_or_type_name ':' attribute_list_opt error // syntax error 1153 1128 { … … 1161 1136 compound_statement: 1162 1137 '{' '}' 1163 { $$ = new StatementNode( build_compound( yylloc,(StatementNode *)0 ) ); }1138 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); } 1164 1139 | '{' push 1165 1140 local_label_declaration_opt // GCC, local labels appear at start of block 1166 1141 statement_decl_list // C99, intermix declarations and statements 1167 1142 pop '}' 1168 { $$ = new StatementNode( build_compound( yylloc,$4 ) ); }1143 { $$ = new StatementNode( build_compound( $4 ) ); } 1169 1144 ; 1170 1145 … … 1197 1172 expression_statement: 1198 1173 comma_expression_opt ';' 1199 { $$ = 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 ) ) ) ); } 1200 1177 ; 1201 1178 … … 1206 1183 { $$ = $2; } 1207 1184 | SWITCH '(' comma_expression ')' case_clause 1208 { $$ = new StatementNode( build_switch( yylloc,true, $3, $5 ) ); }1185 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); } 1209 1186 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1210 1187 { 1211 StatementNode *sw = new StatementNode( build_switch( yylloc,true, $3, $8 ) );1188 StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) ); 1212 1189 // The semantics of the declaration list is changed to include associated initialization, which is performed 1213 1190 // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound … … 1215 1192 // therefore, are removed from the grammar even though C allows it. The change also applies to choose 1216 1193 // statement. 1217 $$ = $7 ? new StatementNode( build_compound( yylloc,(StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1194 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1218 1195 } 1219 1196 | SWITCH '(' comma_expression ')' '{' error '}' // CFA, syntax error 1220 1197 { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; } 1221 1198 | CHOOSE '(' comma_expression ')' case_clause // CFA 1222 { $$ = new StatementNode( build_switch( yylloc,false, $3, $5 ) ); }1199 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); } 1223 1200 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1224 1201 { 1225 StatementNode *sw = new StatementNode( build_switch( yylloc,false, $3, $8 ) );1226 $$ = $7 ? new StatementNode( build_compound( yylloc,(StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;1202 StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) ); 1203 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1227 1204 } 1228 1205 | CHOOSE '(' comma_expression ')' '{' error '}' // CFA, syntax error … … 1233 1210 IF '(' conditional_declaration ')' statement %prec THEN 1234 1211 // explicitly deal with the shift/reduce conflict on if/else 1235 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc,$5 ), nullptr ) ); }1212 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); } 1236 1213 | IF '(' conditional_declaration ')' statement ELSE statement 1237 { $$ = 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 ) ) ); } 1238 1215 ; 1239 1216 … … 1247 1224 | declaration comma_expression // semi-colon separated 1248 1225 { $$ = new CondCtl( $1, $2 ); } 1249 ;1226 ; 1250 1227 1251 1228 // CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case … … 1255 1232 constant_expression { $$ = $1; } 1256 1233 | constant_expression ELLIPSIS constant_expression // GCC, subrange 1257 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1234 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); } 1258 1235 | subrange // CFA, subrange 1259 1236 ; 1260 1237 1261 1238 case_value_list: // CFA 1262 case_value { $$ = new ClauseNode( build_case( yylloc,$1 ) ); }1239 case_value { $$ = new StatementNode( build_case( $1 ) ); } 1263 1240 // convert case list, e.g., "case 1, 3, 5:" into "case 1: case 3: case 5" 1264 | 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 ) ) ) ); } 1265 1242 ; 1266 1243 … … 1271 1248 | CASE case_value_list error // syntax error 1272 1249 { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; } 1273 | DEFAULT ':' { $$ = new ClauseNode( build_default( yylloc) ); }1250 | DEFAULT ':' { $$ = new StatementNode( build_default() ); } 1274 1251 // A semantic check is required to ensure only one default clause per switch/choose statement. 1275 1252 | DEFAULT error // syntax error … … 1279 1256 case_label_list: // CFA 1280 1257 case_label 1281 | case_label_list case_label { $$ = $1->set_last( $2); }1258 | case_label_list case_label { $$ = (StatementNode *)( $1->set_last( $2 )); } 1282 1259 ; 1283 1260 1284 1261 case_clause: // CFA 1285 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 ) ); } 1286 1263 ; 1287 1264 … … 1294 1271 switch_clause_list: // CFA 1295 1272 case_label_list statement_list_nodecl 1296 { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc,$2 ) ) ); }1273 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); } 1297 1274 | switch_clause_list case_label_list statement_list_nodecl 1298 { $$ = $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 ) ) ) ) ); } 1299 1276 ; 1300 1277 1301 1278 iteration_statement: 1302 1279 WHILE '(' ')' statement %prec THEN // CFA => while ( 1 ) 1303 { $$ = 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 ) ) ); } 1304 1281 | WHILE '(' ')' statement ELSE statement // CFA 1305 1282 { 1306 $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc,$4 ) ) );1307 SemanticWarning( yylloc, Warning::SuperfluousElse );1283 $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); 1284 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1308 1285 } 1309 1286 | WHILE '(' conditional_declaration ')' statement %prec THEN 1310 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc,$5 ) ) ); }1287 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); } 1311 1288 | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA 1312 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc,$5 ), $7 ) ); }1289 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); } 1313 1290 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) 1314 { $$ = 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 ) ) ); } 1315 1292 | DO statement WHILE '(' ')' ELSE statement // CFA 1316 1293 { 1317 $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc,$2 ) ) );1318 SemanticWarning( yylloc, Warning::SuperfluousElse );1294 $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); 1295 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1319 1296 } 1320 1297 | DO statement WHILE '(' comma_expression ')' ';' 1321 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc,$2 ) ) ); }1298 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); } 1322 1299 | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA 1323 { $$ = 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 ) ); } 1324 1301 | FOR '(' ')' statement %prec THEN // CFA => for ( ;; ) 1325 { $$ = 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 ) ) ); } 1326 1303 | FOR '(' ')' statement ELSE statement // CFA 1327 1304 { 1328 $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc,$4 ) ) );1329 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, "" ); 1330 1307 } 1331 1308 | FOR '(' for_control_expression_list ')' statement %prec THEN 1332 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc,$5 ) ) ); }1309 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); } 1333 1310 | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA 1334 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc,$5 ), $7 ) ); }1311 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); } 1335 1312 ; 1336 1313 … … 1346 1323 if ( $1->condition ) { 1347 1324 if ( $3->condition ) { 1348 $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 ) ); 1349 1326 } // if 1350 1327 } else $1->condition = $3->condition; 1351 1328 if ( $1->change ) { 1352 1329 if ( $3->change ) { 1353 $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() ) ); 1354 1331 } // if 1355 1332 } else $1->change = $3->change; … … 1360 1337 for_control_expression: 1361 1338 ';' comma_expression_opt ';' comma_expression_opt 1362 { $$ = new ForCtrl( nullptr, $2, $4 ); }1339 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); } 1363 1340 | comma_expression ';' comma_expression_opt ';' comma_expression_opt 1364 { 1365 StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr; 1366 $$ = new ForCtrl( init, $3, $5 ); 1367 } 1341 { $$ = new ForCtrl( $1, $3, $5 ); } 1368 1342 | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';' 1369 { $$ = new ForCtrl( new StatementNode( $1 ), $2, $4 ); }1343 { $$ = new ForCtrl( $1, $2, $4 ); } 1370 1344 1371 1345 | '@' ';' comma_expression // CFA, empty loop-index 1372 { $$ = new ForCtrl( nullptr, $3, nullptr ); }1346 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); } 1373 1347 | '@' ';' comma_expression ';' comma_expression // CFA, empty loop-index 1374 { $$ = new ForCtrl( nullptr, $3, $5 ); }1348 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); } 1375 1349 1376 1350 | comma_expression // CFA, anonymous loop-index 1377 { $$ = 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 ); } 1378 1352 | downupdowneq comma_expression // CFA, anonymous loop-index 1379 { $$ = 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 ); } 1380 1354 1381 1355 | comma_expression updowneq comma_expression // CFA, anonymous loop-index 1382 { $$ = 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 ); } 1383 1357 | '@' updowneq comma_expression // CFA, anonymous loop-index 1384 1358 { 1385 1359 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1386 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 ); 1387 1361 } 1388 1362 | comma_expression updowneq '@' // CFA, anonymous loop-index … … 1392 1366 } 1393 1367 | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1394 { $$ = 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 ); } 1395 1369 | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1396 1370 { 1397 1371 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1398 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 ); 1399 1373 } 1400 1374 | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index … … 1415 1389 1416 1390 | comma_expression ';' comma_expression // CFA 1417 { $$ = forCtrl( yylloc,$3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }1391 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); } 1418 1392 | comma_expression ';' downupdowneq comma_expression // CFA 1419 { $$ = 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 ); } 1420 1394 1421 1395 | comma_expression ';' comma_expression updowneq comma_expression // CFA 1422 { $$ = 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 ); } 1423 1397 | comma_expression ';' '@' updowneq comma_expression // CFA 1424 1398 { 1425 1399 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1426 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, NEW_ONE );1400 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE ); 1427 1401 } 1428 1402 | comma_expression ';' comma_expression updowneq '@' // CFA … … 1430 1404 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1431 1405 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1432 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, NEW_ONE );1406 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE ); 1433 1407 } 1434 1408 | comma_expression ';' '@' updowneq '@' // CFA, error … … 1436 1410 1437 1411 | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA 1438 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }1412 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); } 1439 1413 | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error 1440 1414 { 1441 1415 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1442 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, $7 );1416 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 ); 1443 1417 } 1444 1418 | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA … … 1446 1420 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1447 1421 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1448 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, $7 );1422 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 ); 1449 1423 } 1450 1424 | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA 1451 { $$ = forCtrl( yylloc,$3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }1425 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); } 1452 1426 | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error 1453 1427 { 1454 1428 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1455 else $$ = forCtrl( yylloc,$5, $1, $5->clone(), $4, nullptr, nullptr );1429 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr ); 1456 1430 } 1457 1431 | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA … … 1459 1433 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1460 1434 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1461 else $$ = forCtrl( yylloc,$3, $1, $3->clone(), $4, nullptr, nullptr );1435 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr ); 1462 1436 } 1463 1437 | comma_expression ';' '@' updowneq '@' '~' '@' // CFA … … 1465 1439 1466 1440 | declaration comma_expression // CFA 1467 { $$ = forCtrl( yylloc,$1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }1441 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); } 1468 1442 | declaration downupdowneq comma_expression // CFA 1469 { $$ = 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 ); } 1470 1444 1471 1445 | declaration comma_expression updowneq comma_expression // CFA 1472 { $$ = 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 ); } 1473 1447 | declaration '@' updowneq comma_expression // CFA 1474 1448 { 1475 1449 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1476 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, NEW_ONE );1450 else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE ); 1477 1451 } 1478 1452 | declaration comma_expression updowneq '@' // CFA … … 1480 1454 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1481 1455 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1482 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, NEW_ONE );1456 else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE ); 1483 1457 } 1484 1458 1485 1459 | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA 1486 { $$ = 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 ); } 1487 1461 | declaration '@' updowneq comma_expression '~' comma_expression // CFA 1488 1462 { 1489 1463 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1490 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, $6 );1464 else $$ = forCtrl( $1, $4, $3, nullptr, $6 ); 1491 1465 } 1492 1466 | declaration comma_expression updowneq '@' '~' comma_expression // CFA … … 1494 1468 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1495 1469 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1496 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, $6 );1470 else $$ = forCtrl( $1, $2, $3, nullptr, $6 ); 1497 1471 } 1498 1472 | declaration comma_expression updowneq comma_expression '~' '@' // CFA 1499 { $$ = 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 ); } 1500 1474 | declaration '@' updowneq comma_expression '~' '@' // CFA 1501 1475 { 1502 1476 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1503 else $$ = forCtrl( yylloc,$1, $4, $3, nullptr, nullptr );1477 else $$ = forCtrl( $1, $4, $3, nullptr, nullptr ); 1504 1478 } 1505 1479 | declaration comma_expression updowneq '@' '~' '@' // CFA … … 1507 1481 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1508 1482 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1509 else $$ = forCtrl( yylloc,$1, $2, $3, nullptr, nullptr );1483 else $$ = forCtrl( $1, $2, $3, nullptr, nullptr ); 1510 1484 } 1511 1485 | declaration '@' updowneq '@' '~' '@' // CFA, error … … 1522 1496 SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr; 1523 1497 } 1524 ;1498 ; 1525 1499 1526 1500 downupdowneq: … … 1531 1505 | ErangeDownEq 1532 1506 { $$ = OperKinds::GEThan; } 1533 ;1507 ; 1534 1508 1535 1509 updown: … … 1538 1512 | ErangeDown 1539 1513 { $$ = OperKinds::GThan; } 1540 ;1514 ; 1541 1515 1542 1516 updowneq: … … 1546 1520 | ErangeDownEq 1547 1521 { $$ = OperKinds::GEThan; } 1548 ;1522 ; 1549 1523 1550 1524 jump_statement: 1551 1525 GOTO identifier_or_type_name ';' 1552 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }1526 { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); } 1553 1527 | GOTO '*' comma_expression ';' // GCC, computed goto 1554 1528 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3); … … 1557 1531 // A semantic check is required to ensure fallthru appears only in the body of a choose statement. 1558 1532 | fall_through_name ';' // CFA 1559 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }1533 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); } 1560 1534 | fall_through_name identifier_or_type_name ';' // CFA 1561 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }1535 { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); } 1562 1536 | fall_through_name DEFAULT ';' // CFA 1563 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }1537 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); } 1564 1538 | CONTINUE ';' 1565 1539 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1566 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }1540 { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); } 1567 1541 | CONTINUE identifier_or_type_name ';' // CFA, multi-level continue 1568 1542 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1569 1543 // the target of the transfer appears only at the start of an iteration statement. 1570 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }1544 { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); } 1571 1545 | BREAK ';' 1572 1546 // A semantic check is required to ensure this statement appears only in the body of an iteration statement. 1573 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }1547 { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); } 1574 1548 | BREAK identifier_or_type_name ';' // CFA, multi-level exit 1575 1549 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1576 1550 // the target of the transfer appears only at the start of an iteration statement. 1577 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }1551 { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); } 1578 1552 | RETURN comma_expression_opt ';' 1579 { $$ = new StatementNode( build_return( yylloc,$2 ) ); }1553 { $$ = new StatementNode( build_return( $2 ) ); } 1580 1554 | RETURN '{' initializer_list_opt comma_opt '}' ';' 1581 1555 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1582 1556 | SUSPEND ';' 1583 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None) ); }1557 { $$ = new StatementNode( build_suspend( nullptr ) ); } 1584 1558 | SUSPEND compound_statement 1585 { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None) ); }1559 { $$ = new StatementNode( build_suspend( $2 ) ); } 1586 1560 | SUSPEND COROUTINE ';' 1587 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }1561 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); } 1588 1562 | SUSPEND COROUTINE compound_statement 1589 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }1563 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); } 1590 1564 | SUSPEND GENERATOR ';' 1591 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }1565 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); } 1592 1566 | SUSPEND GENERATOR compound_statement 1593 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }1567 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); } 1594 1568 | THROW assignment_expression_opt ';' // handles rethrow 1595 { $$ = new StatementNode( build_throw( yylloc,$2 ) ); }1569 { $$ = new StatementNode( build_throw( $2 ) ); } 1596 1570 | THROWRESUME assignment_expression_opt ';' // handles reresume 1597 { $$ = new StatementNode( build_resume( yylloc,$2 ) ); }1571 { $$ = new StatementNode( build_resume( $2 ) ); } 1598 1572 | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume 1599 1573 { $$ = new StatementNode( build_resume_at( $2, $4 ) ); } … … 1607 1581 with_statement: 1608 1582 WITH '(' tuple_expression_list ')' statement 1609 { $$ = new StatementNode( build_with( yylloc,$3, $5 ) ); }1610 ; 1611 1612 // 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". 1613 1587 mutex_statement: 1614 MUTEX '(' argument_expression_list_opt ')' statement 1615 { 1616 if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; } 1617 $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) ); 1618 } 1588 MUTEX '(' argument_expression_list ')' statement 1589 { $$ = new StatementNode( build_mutex( $3, $5 ) ); } 1619 1590 ; 1620 1591 … … 1627 1598 { $$ = nullptr; } 1628 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 )); } 1629 1609 ; 1630 1610 … … 1637 1617 1638 1618 timeout: 1639 TIMEOUT '(' comma_expression ')' { $$ = $3; } 1640 ; 1641 1642 wor: 1643 OROR 1644 | WOR 1645 1646 waitfor: 1647 WAITFOR '(' cast_expression ')' 1648 { $$ = $3; } 1649 | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')' 1650 { $$ = (ExpressionNode *)($3->set_last( $5 )); } 1651 ; 1652 1653 wor_waitfor_clause: 1619 TIMEOUT '(' comma_expression ')' { $$ = $3; } 1620 ; 1621 1622 waitfor_clause: 1654 1623 when_clause_opt waitfor statement %prec THEN 1655 // Called first: create header for WaitForStmt. 1656 { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); } 1657 | wor_waitfor_clause wor when_clause_opt waitfor statement 1658 { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); } 1659 | wor_waitfor_clause wor when_clause_opt ELSE statement 1660 { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); } 1661 | wor_waitfor_clause wor when_clause_opt timeout statement %prec THEN 1662 { $$ = 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 ); } 1663 1631 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1664 | w or_waitfor_clause wor when_clause_opt timeout statement worELSE statement // syntax error1632 | when_clause_opt timeout statement WOR ELSE statement // syntax error 1665 1633 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1666 | w or_waitfor_clause wor when_clause_opt timeout statement worwhen_clause ELSE statement1667 { $$ = build_waitfor_ else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 )); }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 ); } 1668 1636 ; 1669 1637 1670 1638 waitfor_statement: 1671 wor_waitfor_clause %prec THEN 1672 { $$ = new StatementNode( $1 ); } 1673 ; 1674 1675 wand: 1676 ANDAND 1677 | WAND 1678 ; 1679 1680 waituntil: 1681 WAITUNTIL '(' cast_expression ')' 1682 { $$ = $3; } 1683 ; 1684 1685 waituntil_clause: 1686 when_clause_opt waituntil statement 1687 { printf( "waituntil_clause 1\n" ); $$ = nullptr; } 1688 | '(' wor_waituntil_clause ')' 1689 { printf( "waituntil_clause 2\n" ); $$ = nullptr; } 1690 ; 1691 1692 wand_waituntil_clause: 1693 waituntil_clause %prec THEN 1694 { printf( "wand_waituntil_clause 1\n" ); $$ = nullptr; } 1695 | waituntil_clause wand wand_waituntil_clause 1696 { printf( "wand_waituntil_clause 2\n" ); $$ = nullptr; } 1697 ; 1698 1699 wor_waituntil_clause: 1700 wand_waituntil_clause 1701 { printf( "wor_waituntil_clause 1\n" ); $$ = nullptr; } 1702 | wor_waituntil_clause wor wand_waituntil_clause 1703 { printf( "wor_waituntil_clause 2\n" ); $$ = nullptr; } 1704 | wor_waituntil_clause wor when_clause_opt ELSE statement 1705 { printf( "wor_waituntil_clause 3\n" ); $$ = nullptr; } 1706 | wor_waituntil_clause wor when_clause_opt timeout statement %prec THEN 1707 { printf( "wor_waituntil_clause 4\n" ); $$ = nullptr; } 1708 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1709 | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error 1710 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1711 | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement 1712 { printf( "wor_waituntil_clause 6\n" ); $$ = nullptr; } 1713 ; 1714 1715 waituntil_statement: 1716 wor_waituntil_clause %prec THEN 1717 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement. 1718 { $$ = new StatementNode( build_compound( yylloc, nullptr ) ); } 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 ) ); } 1719 1643 ; 1720 1644 1721 1645 exception_statement: 1722 TRY compound_statement handler_clause %prec THEN1723 { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr) ); }1646 TRY compound_statement handler_clause %prec THEN 1647 { $$ = new StatementNode( build_try( $2, $3, 0 ) ); } 1724 1648 | TRY compound_statement finally_clause 1725 { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }1649 { $$ = new StatementNode( build_try( $2, 0, $3 ) ); } 1726 1650 | TRY compound_statement handler_clause finally_clause 1727 { $$ = new StatementNode( build_try( yylloc,$2, $3, $4 ) ); }1651 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); } 1728 1652 ; 1729 1653 1730 1654 handler_clause: 1731 1655 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1732 { $$ = new ClauseNode( build_catch( yylloc,$1, $4, $6, $8 ) ); }1656 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); } 1733 1657 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1734 { $$ = $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 ) ) ); } 1735 1659 ; 1736 1660 … … 1742 1666 1743 1667 handler_key: 1744 CATCH { $$ = ast::Terminate; }1745 | RECOVER { $$ = ast::Terminate; }1746 | CATCHRESUME { $$ = ast::Resume; }1747 | FIXUP { $$ = ast::Resume; }1668 CATCH { $$ = CatchStmt::Terminate; } 1669 | RECOVER { $$ = CatchStmt::Terminate; } 1670 | CATCHRESUME { $$ = CatchStmt::Resume; } 1671 | FIXUP { $$ = CatchStmt::Resume; } 1748 1672 ; 1749 1673 1750 1674 finally_clause: 1751 FINALLY compound_statement { $$ = new ClauseNode( build_finally( yylloc,$2 ) ); }1675 FINALLY compound_statement { $$ = new StatementNode( build_finally( $2 ) ); } 1752 1676 ; 1753 1677 … … 1775 1699 asm_statement: 1776 1700 ASM asm_volatile_opt '(' string_literal ')' ';' 1777 { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr) ); }1701 { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); } 1778 1702 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC 1779 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6 ) ); }1703 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); } 1780 1704 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';' 1781 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6, $8 ) ); }1705 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); } 1782 1706 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';' 1783 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6, $8, $10 ) ); }1707 { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); } 1784 1708 | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';' 1785 { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }1709 { $$ = new StatementNode( build_asm( $2, $5, 0, $8, $10, $12 ) ); } 1786 1710 ; 1787 1711 … … 1807 1731 asm_operand: // GCC 1808 1732 string_literal '(' constant_expression ')' 1809 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1733 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); } 1810 1734 | '[' IDENTIFIER ']' string_literal '(' constant_expression ')' 1811 { 1812 $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, maybeMoveBuild( $4 ), maybeMoveBuild( $6 ) ) ); 1813 delete $2.str; 1814 } 1735 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); } 1815 1736 ; 1816 1737 … … 1819 1740 { $$ = nullptr; } // use default argument 1820 1741 | string_literal 1821 { $$ = $1; }1742 { $$ = new ExpressionNode( $1 ); } 1822 1743 | asm_clobbers_list_opt ',' string_literal 1823 { $$ = (ExpressionNode *)( $1->set_last( $3 )); }1744 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( $3 ) )); } 1824 1745 ; 1825 1746 … … 1827 1748 identifier 1828 1749 { 1829 $$ = new LabelNode(); $$->labels. emplace_back( yylloc,*$1 );1750 $$ = new LabelNode(); $$->labels.push_back( *$1 ); 1830 1751 delete $1; // allocated by lexer 1831 1752 } 1832 1753 | label_list ',' identifier 1833 1754 { 1834 $$ = $1; $1->labels. emplace_back( yylloc,*$3 );1755 $$ = $1; $1->labels.push_back( *$3 ); 1835 1756 delete $3; // allocated by lexer 1836 1757 } … … 1883 1804 { 1884 1805 // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" ); 1885 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {1806 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 1886 1807 // printf( "\tattr %s\n", attr->name.c_str() ); 1887 1808 // } // for … … 1893 1814 static_assert: 1894 1815 STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11 1895 { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 )); }1816 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); } 1896 1817 | STATICASSERT '(' constant_expression ')' ';' // CFA 1897 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc,*new string( "\"\"" ) ) ); }1818 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); } 1898 1819 1899 1820 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function … … 1959 1880 // '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict 1960 1881 // { 1961 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );1882 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true ); 1962 1883 // } 1963 1884 // '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')' 1964 1885 // { 1965 1886 // typedefTable.setNextIdentifier( *$5 ); 1966 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );1887 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1967 1888 // } 1968 1889 // | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')' 1969 1890 // { 1970 1891 // typedefTable.setNextIdentifier( *$5 ); 1971 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );1892 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1972 1893 // } 1973 1894 // | '[' ']' typegen_name … … 1981 1902 cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt 1982 1903 // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator). 1983 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr)->addQualifiers( $8 ); }1904 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); } 1984 1905 | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt 1985 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr)->addQualifiers( $8 ); }1906 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); } 1986 1907 ; 1987 1908 … … 2019 1940 { 2020 1941 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" ); 2021 if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) { 2022 SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr; 2023 } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3 1942 $$ = $3->addType( $2 )->addTypedef(); 2024 1943 } 2025 1944 | typedef_declaration pop ',' push declarator … … 2029 1948 } 2030 1949 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 ) 2031 { 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 } 2032 1954 | type_specifier TYPEDEF declarator 2033 { 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 } 2034 1959 | type_specifier TYPEDEF type_qualifier_list declarator 2035 { 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 } 2036 1964 ; 2037 1965 … … 2040 1968 TYPEDEF identifier '=' assignment_expression 2041 1969 { 2042 SemanticError( yylloc, "T YPEDEFexpression is deprecated, use typeof(...) instead." ); $$ = nullptr;1970 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 2043 1971 } 2044 1972 | typedef_expression pop ',' push identifier '=' assignment_expression 2045 1973 { 2046 SemanticError( yylloc, "T YPEDEFexpression is deprecated, use typeof(...) instead." ); $$ = nullptr;1974 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 2047 1975 } 2048 1976 ; … … 2054 1982 | typedef_expression // deprecated GCC, naming expression type 2055 1983 | sue_declaration_specifier 2056 {2057 assert( $1->type );2058 if ( $1->type->qualifiers.any() ) { // CV qualifiers ?2059 SemanticError( yylloc, "Useless type qualifier(s) in empty declaration." ); $$ = nullptr;2060 }2061 // enums are never empty declarations because there must have at least one enumeration.2062 if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ?2063 SemanticError( yylloc, "Useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr;2064 }2065 }2066 1984 ; 2067 1985 … … 2069 1987 // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static 2070 1988 // storage-class 2071 variable_declarator asm_name_opt initializer_opt1989 declarator asm_name_opt initializer_opt 2072 1990 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); } 2073 | variable_type_redeclarator asm_name_opt initializer_opt2074 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }2075 2076 | general_function_declarator asm_name_opt2077 { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }2078 | general_function_declarator asm_name_opt '=' VOID2079 { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }2080 2081 1991 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 2082 1992 { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); } 2083 1993 ; 2084 1994 2085 general_function_declarator:2086 function_type_redeclarator2087 | function_declarator2088 ;2089 2090 1995 declaration_specifier: // type specifier + storage class 2091 1996 basic_declaration_specifier 1997 | sue_declaration_specifier 2092 1998 | type_declaration_specifier 2093 | sue_declaration_specifier2094 | sue_declaration_specifier invalid_types2095 {2096 SemanticError( yylloc, ::toString( "Missing ';' after end of ",2097 $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),2098 " declaration" ) );2099 $$ = nullptr;2100 }2101 ;2102 2103 invalid_types:2104 aggregate_key2105 | basic_type_name2106 | indirect_type2107 1999 ; 2108 2000 … … 2121 2013 basic_type_specifier 2122 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 } 2123 2021 | type_type_specifier 2124 2022 ; … … 2167 2065 { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); } 2168 2066 | forall 2169 { $$ = DeclarationNode::newForall( $1 ); }2170 2067 ; 2171 2068 2172 2069 forall: 2173 2070 FORALL '(' type_parameter_list ')' // CFA 2174 { $$ = $3; }2071 { $$ = DeclarationNode::newForall( $3 ); } 2175 2072 ; 2176 2073 … … 2329 2226 { $$ = DeclarationNode::newTypeof( $3 ); } 2330 2227 | BASETYPEOF '(' type ')' // CFA: basetypeof( x ) y; 2331 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ), true ); }2228 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); } 2332 2229 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 2333 2230 { $$ = DeclarationNode::newTypeof( $3, true ); } … … 2342 2239 { 2343 2240 // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2344 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2241 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2345 2242 // printf( "\tattr %s\n", attr->name.c_str() ); 2346 2243 // } // for … … 2358 2255 { 2359 2256 // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2360 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2257 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2361 2258 // printf( "\tattr %s\n", attr->name.c_str() ); 2362 2259 // } // for … … 2436 2333 { 2437 2334 // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2438 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2335 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2439 2336 // printf( "\tattr %s\n", attr->name.c_str() ); 2440 2337 // } // for … … 2460 2357 '{' field_declaration_list_opt '}' type_parameters_opt 2461 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 2462 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 2463 2369 } 2464 2370 | aggregate_key attribute_list_opt TYPEDEFname // unqualified type name … … 2469 2375 '{' field_declaration_list_opt '}' type_parameters_opt 2470 2376 { 2377 // printf( "AGG3\n" ); 2471 2378 DeclarationNode::newFromTypedef( $3 ); 2472 2379 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); … … 2479 2386 '{' field_declaration_list_opt '}' type_parameters_opt 2480 2387 { 2388 // printf( "AGG4\n" ); 2481 2389 DeclarationNode::newFromTypeGen( $3, nullptr ); 2482 2390 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); … … 2505 2413 // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and 2506 2414 // delete newFromTypeGen. 2507 if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) { 2508 $$ = $3->addQualifiers( $2 ); 2509 } else { 2510 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 ); 2511 $3->type->symbolic.name = nullptr; // copied to $$ 2512 $3->type->symbolic.actuals = nullptr; 2513 delete $3; 2514 } 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; 2515 2419 } 2516 2420 ; … … 2523 2427 aggregate_data: 2524 2428 STRUCT vtable_opt 2525 { $$ = ast::AggregateDecl::Struct; }2429 { $$ = AggregateDecl::Struct; } 2526 2430 | UNION 2527 { $$ = ast::AggregateDecl::Union; }2431 { $$ = AggregateDecl::Union; } 2528 2432 | EXCEPTION // CFA 2529 { $$ = ast::AggregateDecl::Exception; }2530 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }2433 { $$ = AggregateDecl::Exception; } 2434 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2531 2435 ; 2532 2436 2533 2437 aggregate_control: // CFA 2534 2438 MONITOR 2535 { $$ = ast::AggregateDecl::Monitor; }2439 { $$ = AggregateDecl::Monitor; } 2536 2440 | MUTEX STRUCT 2537 { $$ = ast::AggregateDecl::Monitor; }2441 { $$ = AggregateDecl::Monitor; } 2538 2442 | GENERATOR 2539 { $$ = ast::AggregateDecl::Generator; }2443 { $$ = AggregateDecl::Generator; } 2540 2444 | MUTEX GENERATOR 2541 { 2542 SemanticError( yylloc, "monitor generator is currently unimplemented." ); 2543 $$ = ast::AggregateDecl::NoAggregate; 2544 } 2445 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2545 2446 | COROUTINE 2546 { $$ = ast::AggregateDecl::Coroutine; }2447 { $$ = AggregateDecl::Coroutine; } 2547 2448 | MUTEX COROUTINE 2548 { 2549 SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); 2550 $$ = ast::AggregateDecl::NoAggregate; 2551 } 2449 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2552 2450 | THREAD 2553 { $$ = ast::AggregateDecl::Thread; }2451 { $$ = AggregateDecl::Thread; } 2554 2452 | MUTEX THREAD 2555 { 2556 SemanticError( yylloc, "monitor thread is currently unimplemented." ); 2557 $$ = ast::AggregateDecl::NoAggregate; 2558 } 2453 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2559 2454 ; 2560 2455 … … 2572 2467 $$ = fieldDecl( $1, $2 ); 2573 2468 // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2574 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2469 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2575 2470 // printf( "\tattr %s\n", attr->name.c_str() ); 2576 2471 // } // for … … 2578 2473 | EXTENSION type_specifier field_declaring_list_opt ';' // GCC 2579 2474 { $$ = fieldDecl( $2, $3 ); distExt( $$ ); } 2580 | STATIC type_specifier field_declaring_list_opt ';' // CFA2581 { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }2582 2475 | INLINE type_specifier field_abstract_list_opt ';' // CFA 2583 2476 { … … 2590 2483 } 2591 2484 | INLINE aggregate_control ';' // CFA 2592 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }2485 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; } 2593 2486 | typedef_declaration ';' // CFA 2594 2487 | cfa_field_declaring_list ';' // CFA, new style field declaration … … 2616 2509 { $$ = $1->addBitfield( $2 ); } 2617 2510 | variable_type_redeclarator bit_subrange_size_opt 2618 // A semantic check is required to ensure bit_subrange only appears on integral types.2619 { $$ = $1->addBitfield( $2 ); }2620 | function_type_redeclarator bit_subrange_size_opt2621 2511 // A semantic check is required to ensure bit_subrange only appears on integral types. 2622 2512 { $$ = $1->addBitfield( $2 ); } … … 2673 2563 { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); } 2674 2564 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2675 {2676 if ( $3->storageClasses.val != 0 || $3->type->qualifiers. any())2565 { 2566 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) 2677 2567 { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2678 2568 2679 2569 $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 ); 2680 2570 } 2681 | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}'2682 {2683 $$ = DeclarationNode::newEnum( nullptr, $6, true, true )->addQualifiers( $4 );2684 }2685 2571 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt 2686 2572 { 2687 if ( $3->storageClasses. any()|| $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }2573 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." ); } 2688 2574 typedefTable.makeTypedef( *$6 ); 2689 2575 } … … 2691 2577 { 2692 2578 $$ = DeclarationNode::newEnum( $6, $11, true, true, $3, $9 )->addQualifiers( $5 )->addQualifiers( $7 ); 2693 }2694 | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt2695 hide_opt '{' enumerator_list comma_opt '}'2696 {2697 $$ = DeclarationNode::newEnum( $5, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 );2698 2579 } 2699 2580 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt … … 2701 2582 { 2702 2583 $$ = DeclarationNode::newEnum( $6->name, $10, true, true, $3, $8 )->addQualifiers( $5 )->addQualifiers( $7 ); 2703 }2704 | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt2705 hide_opt '{' enumerator_list comma_opt '}'2706 {2707 $$ = DeclarationNode::newEnum( $5->name, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 );2708 2584 } 2709 2585 | enum_type_nobody … … 2719 2595 enum_type_nobody: // enum - {...} 2720 2596 ENUM attribute_list_opt identifier 2721 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }2597 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); } 2722 2598 | ENUM attribute_list_opt type_name 2723 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }2599 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); } 2724 2600 ; 2725 2601 … … 2818 2694 2819 2695 cfa_abstract_parameter_declaration: // CFA, new & old style parameter declaration 2820 abstract_parameter_declaration 2696 // empty 2697 { $$ = nullptr; } 2698 | abstract_parameter_declaration 2821 2699 | cfa_identifier_parameter_declarator_no_tuple 2822 2700 | cfa_abstract_tuple … … 2861 2739 type_no_function: // sizeof, alignof, cast (constructor) 2862 2740 cfa_abstract_declarator_tuple // CFA 2863 | type_specifier // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing2741 | type_specifier 2864 2742 | type_specifier abstract_declarator 2865 2743 { $$ = $2->addType( $1 ); } … … 2906 2784 designator_list ':' // C99, CFA uses ":" instead of "=" 2907 2785 | identifier_at ':' // GCC, field name 2908 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }2786 { $$ = new ExpressionNode( build_varref( $1 ) ); } 2909 2787 ; 2910 2788 … … 2918 2796 designator: 2919 2797 '.' identifier_at // C99, field name 2920 { $$ = new ExpressionNode( build_varref( yylloc,$2 ) ); }2798 { $$ = new ExpressionNode( build_varref( $2 ) ); } 2921 2799 | '[' push assignment_expression pop ']' // C99, single array element 2922 2800 // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple. … … 2925 2803 { $$ = $3; } 2926 2804 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements 2927 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }2805 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); } 2928 2806 | '.' '[' push field_name_list pop ']' // CFA, tuple field selector 2929 2807 { $$ = $4; } … … 2965 2843 { 2966 2844 typedefTable.addToScope( *$2, TYPEDEFname, "9" ); 2967 if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }2968 if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }2969 if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }2845 if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); } 2846 if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); } 2847 if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); } 2970 2848 } 2971 2849 type_initializer_opt assertion_list_opt … … 2978 2856 { 2979 2857 typedefTable.addToScope( *$2, TYPEDIMname, "9" ); 2980 $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );2858 $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 ); 2981 2859 } 2982 2860 // | type_specifier identifier_parameter_declarator 2983 2861 | assertion_list 2984 { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }2862 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); } 2985 2863 ; 2986 2864 2987 2865 new_type_class: // CFA 2988 2866 // empty 2989 { $$ = ast::TypeDecl::Otype; }2867 { $$ = TypeDecl::Otype; } 2990 2868 | '&' 2991 { $$ = ast::TypeDecl::Dtype; }2869 { $$ = TypeDecl::Dtype; } 2992 2870 | '*' 2993 { $$ = ast::TypeDecl::DStype; } // dtype + sized2871 { $$ = TypeDecl::DStype; } // dtype + sized 2994 2872 // | '(' '*' ')' 2995 // { $$ = ast::TypeDecl::Ftype; }2873 // { $$ = TypeDecl::Ftype; } 2996 2874 | ELLIPSIS 2997 { $$ = ast::TypeDecl::Ttype; }2875 { $$ = TypeDecl::Ttype; } 2998 2876 ; 2999 2877 3000 2878 type_class: // CFA 3001 2879 OTYPE 3002 { $$ = ast::TypeDecl::Otype; }2880 { $$ = TypeDecl::Otype; } 3003 2881 | DTYPE 3004 { $$ = ast::TypeDecl::Dtype; }2882 { $$ = TypeDecl::Dtype; } 3005 2883 | FTYPE 3006 { $$ = ast::TypeDecl::Ftype; }2884 { $$ = TypeDecl::Ftype; } 3007 2885 | TTYPE 3008 { $$ = ast::TypeDecl::Ttype; }2886 { $$ = TypeDecl::Ttype; } 3009 2887 ; 3010 2888 … … 3032 2910 type_list: // CFA 3033 2911 type 3034 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }2912 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3035 2913 | assignment_expression 3036 2914 | type_list ',' type 3037 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }2915 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3038 2916 | type_list ',' assignment_expression 3039 2917 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } … … 3060 2938 { 3061 2939 typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" ); 3062 $$ = DeclarationNode::newTypeDecl( $1, nullptr);2940 $$ = DeclarationNode::newTypeDecl( $1, 0 ); 3063 2941 } 3064 2942 | identifier_or_type_name '(' type_parameter_list ')' … … 3071 2949 trait_specifier: // CFA 3072 2950 TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}' 3073 { 3074 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 3075 $$ = DeclarationNode::newTrait( $2, $4, nullptr ); 3076 } 3077 | forall TRAIT identifier_or_type_name '{' '}' // alternate 3078 { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); } 2951 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); } 3079 2952 | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}' 3080 { 3081 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 3082 $$ = DeclarationNode::newTrait( $2, $4, $8 ); 3083 } 3084 | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate 3085 { $$ = DeclarationNode::newTrait( $3, $1, $6 ); } 2953 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); } 3086 2954 ; 3087 2955 … … 3142 3010 external_definition: 3143 3011 DIRECTIVE 3144 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc,$1 ) ) ); }3012 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); } 3145 3013 | declaration 3146 {3147 // Variable declarations of anonymous types requires creating a unique type-name across multiple translation3148 // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is3149 // disallowed at the moment.3150 if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {3151 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {3152 SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;3153 } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union3154 SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;3155 }3156 }3157 }3158 3014 | IDENTIFIER IDENTIFIER 3159 3015 { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; } … … 3175 3031 } 3176 3032 | ASM '(' string_literal ')' ';' // GCC, global assembler statement 3177 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr) ) ); }3033 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); } 3178 3034 | EXTERN STRINGliteral 3179 3035 { 3180 3036 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3181 linkage = ast::Linkage::update( yylloc, linkage, $2 );3037 linkage = LinkageSpec::update( yylloc, linkage, $2 ); 3182 3038 } 3183 3039 up external_definition down … … 3190 3046 { 3191 3047 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3192 linkage = ast::Linkage::update( yylloc, linkage, $2 );3048 linkage = LinkageSpec::update( yylloc, linkage, $2 ); 3193 3049 } 3194 3050 '{' up external_definition_list_opt down '}' … … 3201 3057 | type_qualifier_list 3202 3058 { 3203 if ( $1->type->qualifiers. any()) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3059 if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3204 3060 if ( $1->type->forall ) forall = true; // remember generic type 3205 3061 } … … 3207 3063 { 3208 3064 distQual( $5, $1 ); 3209 forall = false;3065 forall = false; 3210 3066 $$ = $5; 3211 3067 } 3212 3068 | declaration_qualifier_list 3213 3069 { 3214 if ( $1->type && $1->type->qualifiers. any()) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3070 if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3215 3071 if ( $1->type && $1->type->forall ) forall = true; // remember generic type 3216 3072 } … … 3218 3074 { 3219 3075 distQual( $5, $1 ); 3220 forall = false;3076 forall = false; 3221 3077 $$ = $5; 3222 3078 } 3223 3079 | declaration_qualifier_list type_qualifier_list 3224 3080 { 3225 if ( ($1->type && $1->type->qualifiers. any()) || ($2->type && $2->type->qualifiers.any()) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3081 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." ); } 3226 3082 if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type 3227 3083 } … … 3229 3085 { 3230 3086 distQual( $6, $1->addQualifiers( $2 ) ); 3231 forall = false;3087 forall = false; 3232 3088 $$ = $6; 3233 3089 } … … 3273 3129 $$ = $2->addFunctionBody( $4, $3 )->addType( $1 ); 3274 3130 } 3275 | declaration_specifier function_type_redeclarator with_clause_opt compound_statement3131 | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement 3276 3132 { 3277 3133 rebindForall( $1, $2 ); … … 3309 3165 | variable_type_redeclarator 3310 3166 | function_declarator 3311 | function_type_redeclarator3312 3167 ; 3313 3168 3314 3169 subrange: 3315 3170 constant_expression '~' constant_expression // CFA, integer subrange 3316 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }3171 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); } 3317 3172 ; 3318 3173 … … 3323 3178 { 3324 3179 DeclarationNode * name = new DeclarationNode(); 3325 name->asmName = maybeMoveBuild( $3 );3180 name->asmName = $3; 3326 3181 $$ = name->addQualifiers( $5 ); 3327 3182 } … … 3420 3275 variable_ptr: 3421 3276 ptrref_operator variable_declarator 3422 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3277 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3423 3278 | ptrref_operator type_qualifier_list variable_declarator 3424 3279 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3436 3291 | '(' attribute_list variable_ptr ')' array_dimension 3437 3292 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3438 | '(' variable_array ')' multi_array_dimension // redundant parenthesis3293 | '(' variable_array ')' multi_array_dimension // redundant parenthesis 3439 3294 { $$ = $2->addArray( $4 ); } 3440 3295 | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis … … 3484 3339 function_ptr: 3485 3340 ptrref_operator function_declarator 3486 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3341 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3487 3342 | ptrref_operator type_qualifier_list function_declarator 3488 3343 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3536 3391 KR_function_ptr: 3537 3392 ptrref_operator KR_function_declarator 3538 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3393 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3539 3394 | ptrref_operator type_qualifier_list KR_function_declarator 3540 3395 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3560 3415 ; 3561 3416 3562 // This pattern parses a declaration for a variable that redefines a type name, e.g.:3417 // This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.: 3563 3418 // 3564 3419 // typedef int foo; … … 3566 3421 // int foo; // redefine typedef name in new scope 3567 3422 // } 3423 // 3424 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 3425 // and functions versus pointers to arrays and functions. 3568 3426 3569 3427 paren_type: … … 3580 3438 paren_type attribute_list_opt 3581 3439 { $$ = $1->addQualifiers( $2 ); } 3582 | variable_type_ptr3583 | variable_type_array attribute_list_opt3440 | type_ptr 3441 | type_array attribute_list_opt 3584 3442 { $$ = $1->addQualifiers( $2 ); } 3585 | variable_type_function attribute_list_opt3443 | type_function attribute_list_opt 3586 3444 { $$ = $1->addQualifiers( $2 ); } 3587 3445 ; 3588 3446 3589 variable_type_ptr:3447 type_ptr: 3590 3448 ptrref_operator variable_type_redeclarator 3591 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3449 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3592 3450 | ptrref_operator type_qualifier_list variable_type_redeclarator 3593 3451 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3594 | '(' variable_type_ptr ')' attribute_list_opt// redundant parenthesis3452 | '(' type_ptr ')' attribute_list_opt // redundant parenthesis 3595 3453 { $$ = $2->addQualifiers( $4 ); } 3596 | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis3454 | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis 3597 3455 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3598 3456 ; 3599 3457 3600 variable_type_array:3458 type_array: 3601 3459 paren_type array_dimension 3602 3460 { $$ = $1->addArray( $2 ); } 3603 | '(' variable_type_ptr ')' array_dimension3461 | '(' type_ptr ')' array_dimension 3604 3462 { $$ = $2->addArray( $4 ); } 3605 | '(' attribute_list variable_type_ptr ')' array_dimension3463 | '(' attribute_list type_ptr ')' array_dimension 3606 3464 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3607 | '(' variable_type_array ')' multi_array_dimension// redundant parenthesis3465 | '(' type_array ')' multi_array_dimension // redundant parenthesis 3608 3466 { $$ = $2->addArray( $4 ); } 3609 | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis3467 | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis 3610 3468 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3611 | '(' variable_type_array ')'// redundant parenthesis3469 | '(' type_array ')' // redundant parenthesis 3612 3470 { $$ = $2; } 3613 | '(' attribute_list variable_type_array ')'// redundant parenthesis3471 | '(' attribute_list type_array ')' // redundant parenthesis 3614 3472 { $$ = $3->addQualifiers( $2 ); } 3615 3473 ; 3616 3474 3617 variable_type_function: 3618 '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3619 { $$ = $2->addParamList( $6 ); } 3620 | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3621 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3622 | '(' variable_type_function ')' // redundant parenthesis 3623 { $$ = $2; } 3624 | '(' attribute_list variable_type_function ')' // redundant parenthesis 3625 { $$ = $3->addQualifiers( $2 ); } 3626 ; 3627 3628 // This pattern parses a declaration for a function prototype that redefines a type name. It precludes declaring an 3629 // array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to 3630 // arrays and functions. 3631 3632 function_type_redeclarator: 3633 function_type_no_ptr attribute_list_opt 3634 { $$ = $1->addQualifiers( $2 ); } 3635 | function_type_ptr 3636 | function_type_array attribute_list_opt 3637 { $$ = $1->addQualifiers( $2 ); } 3638 ; 3639 3640 function_type_no_ptr: 3475 type_function: 3641 3476 paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3642 3477 { $$ = $1->addParamList( $4 ); } 3643 | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'3478 | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3644 3479 { $$ = $2->addParamList( $6 ); } 3645 | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'3480 | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3646 3481 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3647 | '(' function_type_no_ptr ')'// redundant parenthesis3482 | '(' type_function ')' // redundant parenthesis 3648 3483 { $$ = $2; } 3649 | '(' attribute_list function_type_no_ptr ')' // redundant parenthesis 3650 { $$ = $3->addQualifiers( $2 ); } 3651 ; 3652 3653 function_type_ptr: 3654 ptrref_operator function_type_redeclarator 3655 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3656 | ptrref_operator type_qualifier_list function_type_redeclarator 3657 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3658 | '(' function_type_ptr ')' attribute_list_opt 3659 { $$ = $2->addQualifiers( $4 ); } 3660 | '(' attribute_list function_type_ptr ')' attribute_list_opt 3661 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3662 ; 3663 3664 function_type_array: 3665 '(' function_type_ptr ')' array_dimension 3666 { $$ = $2->addArray( $4 ); } 3667 | '(' attribute_list function_type_ptr ')' array_dimension 3668 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3669 | '(' function_type_array ')' multi_array_dimension // redundant parenthesis 3670 { $$ = $2->addArray( $4 ); } 3671 | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis 3672 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3673 | '(' function_type_array ')' // redundant parenthesis 3674 { $$ = $2; } 3675 | '(' attribute_list function_type_array ')' // redundant parenthesis 3484 | '(' attribute_list type_function ')' // redundant parenthesis 3676 3485 { $$ = $3->addQualifiers( $2 ); } 3677 3486 ; … … 3696 3505 identifier_parameter_ptr: 3697 3506 ptrref_operator identifier_parameter_declarator 3698 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3507 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3699 3508 | ptrref_operator type_qualifier_list identifier_parameter_declarator 3700 3509 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3753 3562 type_parameter_ptr: 3754 3563 ptrref_operator type_parameter_redeclarator 3755 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3564 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3756 3565 | ptrref_operator type_qualifier_list type_parameter_redeclarator 3757 3566 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3796 3605 abstract_ptr: 3797 3606 ptrref_operator 3798 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }3607 { $$ = DeclarationNode::newPointer( 0, $1 ); } 3799 3608 | ptrref_operator type_qualifier_list 3800 3609 { $$ = DeclarationNode::newPointer( $2, $1 ); } 3801 3610 | ptrref_operator abstract_declarator 3802 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3611 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3803 3612 | ptrref_operator type_qualifier_list abstract_declarator 3804 3613 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3829 3638 // Only the first dimension can be empty. 3830 3639 '[' ']' 3831 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }3640 { $$ = DeclarationNode::newArray( 0, 0, false ); } 3832 3641 | '[' ']' multi_array_dimension 3833 { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }3642 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); } 3834 3643 // Cannot use constant_expression because of tuples => semantic check 3835 3644 | '[' push assignment_expression pop ',' comma_expression ']' // CFA 3836 { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }3645 { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); } 3837 3646 // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; } 3838 3647 | '[' push array_type_list pop ']' // CFA … … 3843 3652 array_type_list: 3844 3653 basic_type_name 3845 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3654 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3846 3655 | type_name 3847 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3656 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3848 3657 | assignment_expression upupeq assignment_expression 3849 3658 | array_type_list ',' basic_type_name 3850 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3851 | array_type_list ',' type_name 3852 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3659 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3660 | array_type_list ',' type_name 3661 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3853 3662 | array_type_list ',' assignment_expression upupeq assignment_expression 3854 3663 ; … … 3859 3668 | ErangeUpEq 3860 3669 { $$ = OperKinds::LEThan; } 3861 ;3670 ; 3862 3671 3863 3672 multi_array_dimension: 3864 3673 '[' push assignment_expression pop ']' 3865 { $$ = DeclarationNode::newArray( $3, nullptr, false ); }3674 { $$ = DeclarationNode::newArray( $3, 0, false ); } 3866 3675 | '[' push '*' pop ']' // C99 3867 3676 { $$ = DeclarationNode::newVarArray( 0 ); } 3868 3677 | multi_array_dimension '[' push assignment_expression pop ']' 3869 { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }3678 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); } 3870 3679 | multi_array_dimension '[' push '*' pop ']' // C99 3871 3680 { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); } … … 3964 3773 array_parameter_1st_dimension: 3965 3774 '[' ']' 3966 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }3775 { $$ = DeclarationNode::newArray( 0, 0, false ); } 3967 3776 // multi_array_dimension handles the '[' '*' ']' case 3968 3777 | '[' push type_qualifier_list '*' pop ']' // remaining C99 3969 3778 { $$ = DeclarationNode::newVarArray( $3 ); } 3970 3779 | '[' push type_qualifier_list pop ']' 3971 { $$ = DeclarationNode::newArray( nullptr, $3, false ); }3780 { $$ = DeclarationNode::newArray( 0, $3, false ); } 3972 3781 // multi_array_dimension handles the '[' assignment_expression ']' case 3973 3782 | '[' push type_qualifier_list assignment_expression pop ']' … … 3998 3807 variable_abstract_ptr: 3999 3808 ptrref_operator 4000 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }3809 { $$ = DeclarationNode::newPointer( 0, $1 ); } 4001 3810 | ptrref_operator type_qualifier_list 4002 3811 { $$ = DeclarationNode::newPointer( $2, $1 ); } 4003 3812 | ptrref_operator variable_abstract_declarator 4004 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3813 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4005 3814 | ptrref_operator type_qualifier_list variable_abstract_declarator 4006 3815 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 4044 3853 // No SUE declaration in parameter list. 4045 3854 ptrref_operator type_specifier_nobody 4046 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3855 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4047 3856 | type_qualifier_list ptrref_operator type_specifier_nobody 4048 3857 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4049 3858 | ptrref_operator cfa_abstract_function 4050 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3859 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4051 3860 | type_qualifier_list ptrref_operator cfa_abstract_function 4052 3861 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4053 3862 | ptrref_operator cfa_identifier_parameter_declarator_tuple 4054 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3863 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4055 3864 | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple 4056 3865 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } … … 4061 3870 // shift/reduce conflict with new-style empty (void) function return type. 4062 3871 '[' ']' type_specifier_nobody 4063 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3872 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4064 3873 | cfa_array_parameter_1st_dimension type_specifier_nobody 4065 3874 { $$ = $2->addNewArray( $1 ); } 4066 3875 | '[' ']' multi_array_dimension type_specifier_nobody 4067 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3876 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4068 3877 | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody 4069 3878 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } … … 4072 3881 4073 3882 | '[' ']' cfa_identifier_parameter_ptr 4074 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3883 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4075 3884 | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr 4076 3885 { $$ = $2->addNewArray( $1 ); } 4077 3886 | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr 4078 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3887 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4079 3888 | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr 4080 3889 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } … … 4132 3941 cfa_abstract_ptr: // CFA 4133 3942 ptrref_operator type_specifier 4134 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3943 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4135 3944 | type_qualifier_list ptrref_operator type_specifier 4136 3945 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4137 3946 | ptrref_operator cfa_abstract_function 4138 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3947 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4139 3948 | type_qualifier_list ptrref_operator cfa_abstract_function 4140 3949 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4141 3950 | ptrref_operator cfa_abstract_declarator_tuple 4142 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3951 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4143 3952 | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple 4144 3953 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
Note:
See TracChangeset
for help on using the changeset viewer.