Changes in src/Parser/parser.yy [c86b08d:46da46b]
- File:
-
- 1 edited
-
src/Parser/parser.yy (modified) (144 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/parser.yy
rc86b08d r46da46b 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; … … 56 55 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo... 57 56 58 #include "SynTree/Attribute.h" // for Attribute57 #include "SynTree/Attribute.h" // for Attribute 59 58 60 59 // lex uses __null in a boolean context, it's fine. … … 64 63 65 64 extern DeclarationNode * parseTree; 66 extern ast::Linkage::Spec linkage;65 extern LinkageSpec::Spec linkage; 67 66 extern TypedefTable typedefTable; 68 67 69 stack< ast::Linkage::Spec> linkageStack;68 stack<LinkageSpec::Spec> linkageStack; 70 69 71 70 bool appendStr( string & to, string & from ) { … … 200 199 } // fieldDecl 201 200 202 #define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc,*new string( "0" ) ) )203 #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" ) ) ) 204 203 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right) 205 204 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." … … 207 206 #define MISSING_HIGH "Missing high value for down-to range so index is uninitialized." 208 207 209 static ForCtrl * makeForCtrl( 210 const CodeLocation & location, 211 DeclarationNode * init, 212 enum OperKinds compop, 213 ExpressionNode * comp, 214 ExpressionNode * inc ) { 215 // Wrap both comp/inc if they are non-null. 216 if ( comp ) comp = new ExpressionNode( build_binary_val( location, 217 compop, 218 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 219 comp ) ); 220 if ( inc ) inc = new ExpressionNode( build_binary_val( location, 221 // choose += or -= for upto/downto 222 compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn, 223 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 224 inc ) ); 225 // The StatementNode call frees init->name, it must happen later. 226 return new ForCtrl( new StatementNode( init ), comp, inc ); 227 } 228 229 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 ) { 230 209 if ( index->initializer ) { 231 210 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); … … 234 213 SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." ); 235 214 } // if 236 DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) ); 237 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 ); 238 220 } // forCtrl 239 221 240 ForCtrl * forCtrl( const CodeLocation & location,ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {241 ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());242 if ( constant && (constant-> rep == "0" || constant->rep== "1") ) {243 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 ) ) ); 244 226 } // if 245 DeclarationNode * initDecl = distAttr( 246 DeclarationNode::newTypeof( type, true ), 247 DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) 248 ); 249 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 ); 250 234 } // forCtrl 251 235 252 ForCtrl * forCtrl( const CodeLocation & location,ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {253 if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {254 return forCtrl( location,type, new string( identifier->name ), start, compop, comp, inc );255 } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get()) ) {256 if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {257 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 ); 258 242 } else { 259 243 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; … … 300 284 ExpressionNode * en; 301 285 DeclarationNode * decl; 302 ast::AggregateDecl::Aggregate aggKey;303 ast::TypeDecl::Kind tclass;286 AggregateDecl::Aggregate aggKey; 287 TypeDecl::Kind tclass; 304 288 StatementNode * sn; 305 ast::WaitForStmt * wfs; 306 ast::WaitUntilStmt::ClauseNode * wuscn; 307 ast::Expr * constant; 289 WaitForStmt * wfs; 290 Expression * constant; 308 291 CondCtl * ifctl; 309 292 ForCtrl * fctl; … … 315 298 bool flag; 316 299 EnumHiding hide; 317 ast::ExceptionKind catch_kind;318 ast::GenericExpr * genexpr;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 … … 424 407 %type<catch_kind> handler_key 425 408 %type<sn> mutex_statement 426 %type<en> when_clause when_clause_opt waitfor waituntil timeout 427 %type<sn> waitfor_statement waituntil_statement 428 %type<wfs> wor_waitfor_clause 429 %type<wuscn> waituntil_clause wand_waituntil_clause wor_waituntil_clause 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 … … 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 … … 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 { $$ = 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, new ExpressionNode( $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 ) ) ), new ExpressionNode( $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 ; … … 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 { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }907 { $$ = new ExpressionNode( build_cast( $3, $5, CastExpr::Return ) ); } 932 908 | '(' COERCE type_no_function ')' cast_expression // CFA 933 909 { SemanticError( yylloc, "Coerce 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 ; … … 1271 1248 | CASE case_value_list error // syntax error 1272 1249 { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; } 1273 | DEFAULT ':' { $$ = new StatementNode( 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 … … 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 { $$ = (StatementNode *)( $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 { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); } 1688 | '(' wor_waituntil_clause ')' 1689 { $$ = $2; } 1690 ; 1691 1692 wand_waituntil_clause: 1693 waituntil_clause %prec THEN 1694 { $$ = $1; } 1695 | waituntil_clause wand wand_waituntil_clause 1696 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); } 1697 ; 1698 1699 wor_waituntil_clause: 1700 wand_waituntil_clause 1701 { $$ = $1; } 1702 | wor_waituntil_clause wor wand_waituntil_clause 1703 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); } 1704 | wor_waituntil_clause wor when_clause_opt ELSE statement 1705 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); } 1706 | wor_waituntil_clause wor when_clause_opt timeout statement %prec THEN 1707 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); } 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 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, 1713 new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, 1714 build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ), 1715 build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); } 1716 ; 1717 1718 waituntil_statement: 1719 wor_waituntil_clause %prec THEN 1720 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement. 1721 { 1722 $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) ); 1723 // $$ = new StatementNode( build_compound( yylloc, nullptr ) ); 1724 } 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 ) ); } 1725 1643 ; 1726 1644 1727 1645 exception_statement: 1728 TRY compound_statement handler_clause %prec THEN1729 { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr) ); }1646 TRY compound_statement handler_clause %prec THEN 1647 { $$ = new StatementNode( build_try( $2, $3, 0 ) ); } 1730 1648 | TRY compound_statement finally_clause 1731 { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }1649 { $$ = new StatementNode( build_try( $2, 0, $3 ) ); } 1732 1650 | TRY compound_statement handler_clause finally_clause 1733 { $$ = new StatementNode( build_try( yylloc,$2, $3, $4 ) ); }1651 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); } 1734 1652 ; 1735 1653 1736 1654 handler_clause: 1737 1655 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1738 { $$ = new StatementNode( build_catch( yylloc,$1, $4, $6, $8 ) ); }1656 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); } 1739 1657 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1740 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( yylloc,$2, $5, $7, $9 ) ) ); }1658 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); } 1741 1659 ; 1742 1660 … … 1748 1666 1749 1667 handler_key: 1750 CATCH { $$ = ast::Terminate; }1751 | RECOVER { $$ = ast::Terminate; }1752 | CATCHRESUME { $$ = ast::Resume; }1753 | FIXUP { $$ = ast::Resume; }1668 CATCH { $$ = CatchStmt::Terminate; } 1669 | RECOVER { $$ = CatchStmt::Terminate; } 1670 | CATCHRESUME { $$ = CatchStmt::Resume; } 1671 | FIXUP { $$ = CatchStmt::Resume; } 1754 1672 ; 1755 1673 1756 1674 finally_clause: 1757 FINALLY compound_statement { $$ = new StatementNode( build_finally( yylloc,$2 ) ); }1675 FINALLY compound_statement { $$ = new StatementNode( build_finally( $2 ) ); } 1758 1676 ; 1759 1677 … … 1781 1699 asm_statement: 1782 1700 ASM asm_volatile_opt '(' string_literal ')' ';' 1783 { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr) ); }1701 { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); } 1784 1702 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC 1785 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6 ) ); }1703 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); } 1786 1704 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';' 1787 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6, $8 ) ); }1705 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); } 1788 1706 | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';' 1789 { $$ = new StatementNode( build_asm( yylloc,$2, $4, $6, $8, $10 ) ); }1707 { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); } 1790 1708 | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';' 1791 { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }1709 { $$ = new StatementNode( build_asm( $2, $5, 0, $8, $10, $12 ) ); } 1792 1710 ; 1793 1711 … … 1813 1731 asm_operand: // GCC 1814 1732 string_literal '(' constant_expression ')' 1815 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", $1, maybeMoveBuild( $3 ) ) ); }1733 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); } 1816 1734 | '[' IDENTIFIER ']' string_literal '(' constant_expression ')' 1817 { 1818 $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, $4, maybeMoveBuild( $6 ) ) ); 1819 delete $2.str; 1820 } 1735 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); } 1821 1736 ; 1822 1737 … … 1833 1748 identifier 1834 1749 { 1835 $$ = new LabelNode(); $$->labels. emplace_back( yylloc,*$1 );1750 $$ = new LabelNode(); $$->labels.push_back( *$1 ); 1836 1751 delete $1; // allocated by lexer 1837 1752 } 1838 1753 | label_list ',' identifier 1839 1754 { 1840 $$ = $1; $1->labels. emplace_back( yylloc,*$3 );1755 $$ = $1; $1->labels.push_back( *$3 ); 1841 1756 delete $3; // allocated by lexer 1842 1757 } … … 1889 1804 { 1890 1805 // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" ); 1891 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {1806 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 1892 1807 // printf( "\tattr %s\n", attr->name.c_str() ); 1893 1808 // } // for … … 1901 1816 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); } 1902 1817 | STATICASSERT '(' constant_expression ')' ';' // CFA 1903 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc,*new string( "\"\"" ) ) ); }1818 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); } 1904 1819 1905 1820 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function … … 1965 1880 // '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict 1966 1881 // { 1967 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );1882 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true ); 1968 1883 // } 1969 1884 // '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')' 1970 1885 // { 1971 1886 // typedefTable.setNextIdentifier( *$5 ); 1972 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );1887 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1973 1888 // } 1974 1889 // | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')' 1975 1890 // { 1976 1891 // typedefTable.setNextIdentifier( *$5 ); 1977 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );1892 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1978 1893 // } 1979 1894 // | '[' ']' typegen_name … … 1987 1902 cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt 1988 1903 // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator). 1989 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr)->addQualifiers( $8 ); }1904 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); } 1990 1905 | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt 1991 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr)->addQualifiers( $8 ); }1906 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); } 1992 1907 ; 1993 1908 … … 2025 1940 { 2026 1941 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" ); 2027 if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) { 2028 SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr; 2029 } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3 1942 $$ = $3->addType( $2 )->addTypedef(); 2030 1943 } 2031 1944 | typedef_declaration pop ',' push declarator … … 2035 1948 } 2036 1949 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 ) 2037 { 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 } 2038 1954 | type_specifier TYPEDEF declarator 2039 { 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 } 2040 1959 | type_specifier TYPEDEF type_qualifier_list declarator 2041 { 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 } 2042 1964 ; 2043 1965 … … 2046 1968 TYPEDEF identifier '=' assignment_expression 2047 1969 { 2048 SemanticError( yylloc, "T YPEDEFexpression is deprecated, use typeof(...) instead." ); $$ = nullptr;1970 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 2049 1971 } 2050 1972 | typedef_expression pop ',' push identifier '=' assignment_expression 2051 1973 { 2052 SemanticError( yylloc, "T YPEDEFexpression is deprecated, use typeof(...) instead." ); $$ = nullptr;1974 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 2053 1975 } 2054 1976 ; … … 2060 1982 | typedef_expression // deprecated GCC, naming expression type 2061 1983 | sue_declaration_specifier 2062 {2063 assert( $1->type );2064 if ( $1->type->qualifiers.any() ) { // CV qualifiers ?2065 SemanticError( yylloc, "Useless type qualifier(s) in empty declaration." ); $$ = nullptr;2066 }2067 // enums are never empty declarations because there must have at least one enumeration.2068 if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ?2069 SemanticError( yylloc, "Useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr;2070 }2071 }2072 1984 ; 2073 1985 … … 2075 1987 // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static 2076 1988 // storage-class 2077 variable_declarator asm_name_opt initializer_opt1989 declarator asm_name_opt initializer_opt 2078 1990 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); } 2079 | variable_type_redeclarator asm_name_opt initializer_opt2080 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }2081 2082 | general_function_declarator asm_name_opt2083 { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }2084 | general_function_declarator asm_name_opt '=' VOID2085 { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }2086 2087 1991 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 2088 1992 { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); } 2089 1993 ; 2090 1994 2091 general_function_declarator:2092 function_type_redeclarator2093 | function_declarator2094 ;2095 2096 1995 declaration_specifier: // type specifier + storage class 2097 1996 basic_declaration_specifier 1997 | sue_declaration_specifier 2098 1998 | type_declaration_specifier 2099 | sue_declaration_specifier2100 | sue_declaration_specifier invalid_types2101 {2102 SemanticError( yylloc, ::toString( "Missing ';' after end of ",2103 $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),2104 " declaration" ) );2105 $$ = nullptr;2106 }2107 ;2108 2109 invalid_types:2110 aggregate_key2111 | basic_type_name2112 | indirect_type2113 1999 ; 2114 2000 … … 2127 2013 basic_type_specifier 2128 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 } 2129 2021 | type_type_specifier 2130 2022 ; … … 2173 2065 { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); } 2174 2066 | forall 2175 { $$ = DeclarationNode::newForall( $1 ); }2176 2067 ; 2177 2068 2178 2069 forall: 2179 2070 FORALL '(' type_parameter_list ')' // CFA 2180 { $$ = $3; }2071 { $$ = DeclarationNode::newForall( $3 ); } 2181 2072 ; 2182 2073 … … 2335 2226 { $$ = DeclarationNode::newTypeof( $3 ); } 2336 2227 | BASETYPEOF '(' type ')' // CFA: basetypeof( x ) y; 2337 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ), true ); }2228 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); } 2338 2229 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 2339 2230 { $$ = DeclarationNode::newTypeof( $3, true ); } … … 2348 2239 { 2349 2240 // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2350 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2241 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2351 2242 // printf( "\tattr %s\n", attr->name.c_str() ); 2352 2243 // } // for … … 2364 2255 { 2365 2256 // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2366 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2257 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2367 2258 // printf( "\tattr %s\n", attr->name.c_str() ); 2368 2259 // } // for … … 2442 2333 { 2443 2334 // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2444 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2335 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2445 2336 // printf( "\tattr %s\n", attr->name.c_str() ); 2446 2337 // } // for … … 2466 2357 '{' field_declaration_list_opt '}' type_parameters_opt 2467 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 2468 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 2469 2369 } 2470 2370 | aggregate_key attribute_list_opt TYPEDEFname // unqualified type name … … 2475 2375 '{' field_declaration_list_opt '}' type_parameters_opt 2476 2376 { 2377 // printf( "AGG3\n" ); 2477 2378 DeclarationNode::newFromTypedef( $3 ); 2478 2379 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); … … 2485 2386 '{' field_declaration_list_opt '}' type_parameters_opt 2486 2387 { 2388 // printf( "AGG4\n" ); 2487 2389 DeclarationNode::newFromTypeGen( $3, nullptr ); 2488 2390 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); … … 2511 2413 // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and 2512 2414 // delete newFromTypeGen. 2513 if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) { 2514 $$ = $3->addQualifiers( $2 ); 2515 } else { 2516 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 ); 2517 $3->type->symbolic.name = nullptr; // copied to $$ 2518 $3->type->symbolic.actuals = nullptr; 2519 delete $3; 2520 } 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; 2521 2419 } 2522 2420 ; … … 2529 2427 aggregate_data: 2530 2428 STRUCT vtable_opt 2531 { $$ = ast::AggregateDecl::Struct; }2429 { $$ = AggregateDecl::Struct; } 2532 2430 | UNION 2533 { $$ = ast::AggregateDecl::Union; }2431 { $$ = AggregateDecl::Union; } 2534 2432 | EXCEPTION // CFA 2535 { $$ = ast::AggregateDecl::Exception; }2536 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }2433 { $$ = AggregateDecl::Exception; } 2434 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2537 2435 ; 2538 2436 2539 2437 aggregate_control: // CFA 2540 2438 MONITOR 2541 { $$ = ast::AggregateDecl::Monitor; }2439 { $$ = AggregateDecl::Monitor; } 2542 2440 | MUTEX STRUCT 2543 { $$ = ast::AggregateDecl::Monitor; }2441 { $$ = AggregateDecl::Monitor; } 2544 2442 | GENERATOR 2545 { $$ = ast::AggregateDecl::Generator; }2443 { $$ = AggregateDecl::Generator; } 2546 2444 | MUTEX GENERATOR 2547 { 2548 SemanticError( yylloc, "monitor generator is currently unimplemented." ); 2549 $$ = ast::AggregateDecl::NoAggregate; 2550 } 2445 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2551 2446 | COROUTINE 2552 { $$ = ast::AggregateDecl::Coroutine; }2447 { $$ = AggregateDecl::Coroutine; } 2553 2448 | MUTEX COROUTINE 2554 { 2555 SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); 2556 $$ = ast::AggregateDecl::NoAggregate; 2557 } 2449 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2558 2450 | THREAD 2559 { $$ = ast::AggregateDecl::Thread; }2451 { $$ = AggregateDecl::Thread; } 2560 2452 | MUTEX THREAD 2561 { 2562 SemanticError( yylloc, "monitor thread is currently unimplemented." ); 2563 $$ = ast::AggregateDecl::NoAggregate; 2564 } 2453 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2565 2454 ; 2566 2455 … … 2578 2467 $$ = fieldDecl( $1, $2 ); 2579 2468 // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" ); 2580 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {2469 // for ( Attribute * attr: reverseIterate( $$->attributes ) ) { 2581 2470 // printf( "\tattr %s\n", attr->name.c_str() ); 2582 2471 // } // for … … 2584 2473 | EXTENSION type_specifier field_declaring_list_opt ';' // GCC 2585 2474 { $$ = fieldDecl( $2, $3 ); distExt( $$ ); } 2586 | STATIC type_specifier field_declaring_list_opt ';' // CFA2587 { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }2588 2475 | INLINE type_specifier field_abstract_list_opt ';' // CFA 2589 2476 { … … 2596 2483 } 2597 2484 | INLINE aggregate_control ';' // CFA 2598 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }2485 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; } 2599 2486 | typedef_declaration ';' // CFA 2600 2487 | cfa_field_declaring_list ';' // CFA, new style field declaration … … 2622 2509 { $$ = $1->addBitfield( $2 ); } 2623 2510 | variable_type_redeclarator bit_subrange_size_opt 2624 // A semantic check is required to ensure bit_subrange only appears on integral types.2625 { $$ = $1->addBitfield( $2 ); }2626 | function_type_redeclarator bit_subrange_size_opt2627 2511 // A semantic check is required to ensure bit_subrange only appears on integral types. 2628 2512 { $$ = $1->addBitfield( $2 ); } … … 2679 2563 { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); } 2680 2564 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2681 {2682 if ( $3->storageClasses.val != 0 || $3->type->qualifiers. any())2565 { 2566 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) 2683 2567 { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2684 2568 … … 2691 2575 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt 2692 2576 { 2693 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." ); }2577 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2694 2578 typedefTable.makeTypedef( *$6 ); 2695 2579 } … … 2725 2609 enum_type_nobody: // enum - {...} 2726 2610 ENUM attribute_list_opt identifier 2727 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }2611 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); } 2728 2612 | ENUM attribute_list_opt type_name 2729 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }2613 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); } 2730 2614 ; 2731 2615 … … 2867 2751 type_no_function: // sizeof, alignof, cast (constructor) 2868 2752 cfa_abstract_declarator_tuple // CFA 2869 | type_specifier // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing2753 | type_specifier 2870 2754 | type_specifier abstract_declarator 2871 2755 { $$ = $2->addType( $1 ); } … … 2912 2796 designator_list ':' // C99, CFA uses ":" instead of "=" 2913 2797 | identifier_at ':' // GCC, field name 2914 { $$ = new ExpressionNode( build_varref( yylloc,$1 ) ); }2798 { $$ = new ExpressionNode( build_varref( $1 ) ); } 2915 2799 ; 2916 2800 … … 2924 2808 designator: 2925 2809 '.' identifier_at // C99, field name 2926 { $$ = new ExpressionNode( build_varref( yylloc,$2 ) ); }2810 { $$ = new ExpressionNode( build_varref( $2 ) ); } 2927 2811 | '[' push assignment_expression pop ']' // C99, single array element 2928 2812 // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple. … … 2931 2815 { $$ = $3; } 2932 2816 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements 2933 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }2817 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); } 2934 2818 | '.' '[' push field_name_list pop ']' // CFA, tuple field selector 2935 2819 { $$ = $4; } … … 2971 2855 { 2972 2856 typedefTable.addToScope( *$2, TYPEDEFname, "9" ); 2973 if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }2974 if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }2975 if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }2857 if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); } 2858 if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); } 2859 if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); } 2976 2860 } 2977 2861 type_initializer_opt assertion_list_opt … … 2984 2868 { 2985 2869 typedefTable.addToScope( *$2, TYPEDIMname, "9" ); 2986 $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );2870 $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 ); 2987 2871 } 2988 2872 // | type_specifier identifier_parameter_declarator 2989 2873 | assertion_list 2990 { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }2874 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); } 2991 2875 ; 2992 2876 2993 2877 new_type_class: // CFA 2994 2878 // empty 2995 { $$ = ast::TypeDecl::Otype; }2879 { $$ = TypeDecl::Otype; } 2996 2880 | '&' 2997 { $$ = ast::TypeDecl::Dtype; }2881 { $$ = TypeDecl::Dtype; } 2998 2882 | '*' 2999 { $$ = ast::TypeDecl::DStype; } // dtype + sized2883 { $$ = TypeDecl::DStype; } // dtype + sized 3000 2884 // | '(' '*' ')' 3001 // { $$ = ast::TypeDecl::Ftype; }2885 // { $$ = TypeDecl::Ftype; } 3002 2886 | ELLIPSIS 3003 { $$ = ast::TypeDecl::Ttype; }2887 { $$ = TypeDecl::Ttype; } 3004 2888 ; 3005 2889 3006 2890 type_class: // CFA 3007 2891 OTYPE 3008 { $$ = ast::TypeDecl::Otype; }2892 { $$ = TypeDecl::Otype; } 3009 2893 | DTYPE 3010 { $$ = ast::TypeDecl::Dtype; }2894 { $$ = TypeDecl::Dtype; } 3011 2895 | FTYPE 3012 { $$ = ast::TypeDecl::Ftype; }2896 { $$ = TypeDecl::Ftype; } 3013 2897 | TTYPE 3014 { $$ = ast::TypeDecl::Ttype; }2898 { $$ = TypeDecl::Ttype; } 3015 2899 ; 3016 2900 … … 3038 2922 type_list: // CFA 3039 2923 type 3040 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }2924 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3041 2925 | assignment_expression 3042 2926 | type_list ',' type 3043 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }2927 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3044 2928 | type_list ',' assignment_expression 3045 2929 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } … … 3066 2950 { 3067 2951 typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" ); 3068 $$ = DeclarationNode::newTypeDecl( $1, nullptr);2952 $$ = DeclarationNode::newTypeDecl( $1, 0 ); 3069 2953 } 3070 2954 | identifier_or_type_name '(' type_parameter_list ')' … … 3077 2961 trait_specifier: // CFA 3078 2962 TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}' 3079 { 3080 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 3081 $$ = DeclarationNode::newTrait( $2, $4, nullptr ); 3082 } 3083 | forall TRAIT identifier_or_type_name '{' '}' // alternate 3084 { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); } 2963 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); } 3085 2964 | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}' 3086 { 3087 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 3088 $$ = DeclarationNode::newTrait( $2, $4, $8 ); 3089 } 3090 | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate 3091 { $$ = DeclarationNode::newTrait( $3, $1, $6 ); } 2965 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); } 3092 2966 ; 3093 2967 … … 3148 3022 external_definition: 3149 3023 DIRECTIVE 3150 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc,$1 ) ) ); }3024 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); } 3151 3025 | declaration 3152 {3153 // Variable declarations of anonymous types requires creating a unique type-name across multiple translation3154 // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is3155 // disallowed at the moment.3156 if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {3157 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {3158 SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;3159 } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union3160 SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;3161 }3162 }3163 }3164 3026 | IDENTIFIER IDENTIFIER 3165 3027 { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; } … … 3181 3043 } 3182 3044 | ASM '(' string_literal ')' ';' // GCC, global assembler statement 3183 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr) ) ); }3045 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); } 3184 3046 | EXTERN STRINGliteral 3185 3047 { 3186 3048 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3187 linkage = ast::Linkage::update( yylloc, linkage, $2 );3049 linkage = LinkageSpec::update( yylloc, linkage, $2 ); 3188 3050 } 3189 3051 up external_definition down … … 3196 3058 { 3197 3059 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3198 linkage = ast::Linkage::update( yylloc, linkage, $2 );3060 linkage = LinkageSpec::update( yylloc, linkage, $2 ); 3199 3061 } 3200 3062 '{' up external_definition_list_opt down '}' … … 3207 3069 | type_qualifier_list 3208 3070 { 3209 if ( $1->type->qualifiers. any()) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3071 if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3210 3072 if ( $1->type->forall ) forall = true; // remember generic type 3211 3073 } … … 3213 3075 { 3214 3076 distQual( $5, $1 ); 3215 forall = false;3077 forall = false; 3216 3078 $$ = $5; 3217 3079 } 3218 3080 | declaration_qualifier_list 3219 3081 { 3220 if ( $1->type && $1->type->qualifiers. any()) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3082 if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3221 3083 if ( $1->type && $1->type->forall ) forall = true; // remember generic type 3222 3084 } … … 3224 3086 { 3225 3087 distQual( $5, $1 ); 3226 forall = false;3088 forall = false; 3227 3089 $$ = $5; 3228 3090 } 3229 3091 | declaration_qualifier_list type_qualifier_list 3230 3092 { 3231 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." ); }3093 if ( ($1->type && $1->type->qualifiers.val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3232 3094 if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type 3233 3095 } … … 3235 3097 { 3236 3098 distQual( $6, $1->addQualifiers( $2 ) ); 3237 forall = false;3099 forall = false; 3238 3100 $$ = $6; 3239 3101 } … … 3279 3141 $$ = $2->addFunctionBody( $4, $3 )->addType( $1 ); 3280 3142 } 3281 | declaration_specifier function_type_redeclarator with_clause_opt compound_statement3143 | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement 3282 3144 { 3283 3145 rebindForall( $1, $2 ); … … 3315 3177 | variable_type_redeclarator 3316 3178 | function_declarator 3317 | function_type_redeclarator3318 3179 ; 3319 3180 3320 3181 subrange: 3321 3182 constant_expression '~' constant_expression // CFA, integer subrange 3322 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }3183 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); } 3323 3184 ; 3324 3185 … … 3426 3287 variable_ptr: 3427 3288 ptrref_operator variable_declarator 3428 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3289 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3429 3290 | ptrref_operator type_qualifier_list variable_declarator 3430 3291 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3442 3303 | '(' attribute_list variable_ptr ')' array_dimension 3443 3304 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3444 | '(' variable_array ')' multi_array_dimension // redundant parenthesis3305 | '(' variable_array ')' multi_array_dimension // redundant parenthesis 3445 3306 { $$ = $2->addArray( $4 ); } 3446 3307 | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis … … 3490 3351 function_ptr: 3491 3352 ptrref_operator function_declarator 3492 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3353 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3493 3354 | ptrref_operator type_qualifier_list function_declarator 3494 3355 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3542 3403 KR_function_ptr: 3543 3404 ptrref_operator KR_function_declarator 3544 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3405 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3545 3406 | ptrref_operator type_qualifier_list KR_function_declarator 3546 3407 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3566 3427 ; 3567 3428 3568 // This pattern parses a declaration for a variable that redefines a type name, e.g.:3429 // This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.: 3569 3430 // 3570 3431 // typedef int foo; … … 3572 3433 // int foo; // redefine typedef name in new scope 3573 3434 // } 3435 // 3436 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 3437 // and functions versus pointers to arrays and functions. 3574 3438 3575 3439 paren_type: … … 3586 3450 paren_type attribute_list_opt 3587 3451 { $$ = $1->addQualifiers( $2 ); } 3588 | variable_type_ptr3589 | variable_type_array attribute_list_opt3452 | type_ptr 3453 | type_array attribute_list_opt 3590 3454 { $$ = $1->addQualifiers( $2 ); } 3591 | variable_type_function attribute_list_opt3455 | type_function attribute_list_opt 3592 3456 { $$ = $1->addQualifiers( $2 ); } 3593 3457 ; 3594 3458 3595 variable_type_ptr:3459 type_ptr: 3596 3460 ptrref_operator variable_type_redeclarator 3597 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3461 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3598 3462 | ptrref_operator type_qualifier_list variable_type_redeclarator 3599 3463 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3600 | '(' variable_type_ptr ')' attribute_list_opt// redundant parenthesis3464 | '(' type_ptr ')' attribute_list_opt // redundant parenthesis 3601 3465 { $$ = $2->addQualifiers( $4 ); } 3602 | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis3466 | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis 3603 3467 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3604 3468 ; 3605 3469 3606 variable_type_array:3470 type_array: 3607 3471 paren_type array_dimension 3608 3472 { $$ = $1->addArray( $2 ); } 3609 | '(' variable_type_ptr ')' array_dimension3473 | '(' type_ptr ')' array_dimension 3610 3474 { $$ = $2->addArray( $4 ); } 3611 | '(' attribute_list variable_type_ptr ')' array_dimension3475 | '(' attribute_list type_ptr ')' array_dimension 3612 3476 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3613 | '(' variable_type_array ')' multi_array_dimension// redundant parenthesis3477 | '(' type_array ')' multi_array_dimension // redundant parenthesis 3614 3478 { $$ = $2->addArray( $4 ); } 3615 | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis3479 | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis 3616 3480 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3617 | '(' variable_type_array ')'// redundant parenthesis3481 | '(' type_array ')' // redundant parenthesis 3618 3482 { $$ = $2; } 3619 | '(' attribute_list variable_type_array ')'// redundant parenthesis3483 | '(' attribute_list type_array ')' // redundant parenthesis 3620 3484 { $$ = $3->addQualifiers( $2 ); } 3621 3485 ; 3622 3486 3623 variable_type_function: 3624 '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3625 { $$ = $2->addParamList( $6 ); } 3626 | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3627 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3628 | '(' variable_type_function ')' // redundant parenthesis 3629 { $$ = $2; } 3630 | '(' attribute_list variable_type_function ')' // redundant parenthesis 3631 { $$ = $3->addQualifiers( $2 ); } 3632 ; 3633 3634 // This pattern parses a declaration for a function prototype that redefines a type name. It precludes declaring an 3635 // array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to 3636 // arrays and functions. 3637 3638 function_type_redeclarator: 3639 function_type_no_ptr attribute_list_opt 3640 { $$ = $1->addQualifiers( $2 ); } 3641 | function_type_ptr 3642 | function_type_array attribute_list_opt 3643 { $$ = $1->addQualifiers( $2 ); } 3644 ; 3645 3646 function_type_no_ptr: 3487 type_function: 3647 3488 paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3648 3489 { $$ = $1->addParamList( $4 ); } 3649 | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'3490 | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3650 3491 { $$ = $2->addParamList( $6 ); } 3651 | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'3492 | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3652 3493 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3653 | '(' function_type_no_ptr ')'// redundant parenthesis3494 | '(' type_function ')' // redundant parenthesis 3654 3495 { $$ = $2; } 3655 | '(' attribute_list function_type_no_ptr ')' // redundant parenthesis 3656 { $$ = $3->addQualifiers( $2 ); } 3657 ; 3658 3659 function_type_ptr: 3660 ptrref_operator function_type_redeclarator 3661 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); } 3662 | ptrref_operator type_qualifier_list function_type_redeclarator 3663 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3664 | '(' function_type_ptr ')' attribute_list_opt 3665 { $$ = $2->addQualifiers( $4 ); } 3666 | '(' attribute_list function_type_ptr ')' attribute_list_opt 3667 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3668 ; 3669 3670 function_type_array: 3671 '(' function_type_ptr ')' array_dimension 3672 { $$ = $2->addArray( $4 ); } 3673 | '(' attribute_list function_type_ptr ')' array_dimension 3674 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3675 | '(' function_type_array ')' multi_array_dimension // redundant parenthesis 3676 { $$ = $2->addArray( $4 ); } 3677 | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis 3678 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3679 | '(' function_type_array ')' // redundant parenthesis 3680 { $$ = $2; } 3681 | '(' attribute_list function_type_array ')' // redundant parenthesis 3496 | '(' attribute_list type_function ')' // redundant parenthesis 3682 3497 { $$ = $3->addQualifiers( $2 ); } 3683 3498 ; … … 3702 3517 identifier_parameter_ptr: 3703 3518 ptrref_operator identifier_parameter_declarator 3704 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3519 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3705 3520 | ptrref_operator type_qualifier_list identifier_parameter_declarator 3706 3521 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3759 3574 type_parameter_ptr: 3760 3575 ptrref_operator type_parameter_redeclarator 3761 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3576 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3762 3577 | ptrref_operator type_qualifier_list type_parameter_redeclarator 3763 3578 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3802 3617 abstract_ptr: 3803 3618 ptrref_operator 3804 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }3619 { $$ = DeclarationNode::newPointer( 0, $1 ); } 3805 3620 | ptrref_operator type_qualifier_list 3806 3621 { $$ = DeclarationNode::newPointer( $2, $1 ); } 3807 3622 | ptrref_operator abstract_declarator 3808 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3623 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 3809 3624 | ptrref_operator type_qualifier_list abstract_declarator 3810 3625 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 3835 3650 // Only the first dimension can be empty. 3836 3651 '[' ']' 3837 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }3652 { $$ = DeclarationNode::newArray( 0, 0, false ); } 3838 3653 | '[' ']' multi_array_dimension 3839 { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }3654 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); } 3840 3655 // Cannot use constant_expression because of tuples => semantic check 3841 3656 | '[' push assignment_expression pop ',' comma_expression ']' // CFA 3842 { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }3657 { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); } 3843 3658 // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; } 3844 3659 | '[' push array_type_list pop ']' // CFA … … 3849 3664 array_type_list: 3850 3665 basic_type_name 3851 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3666 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3852 3667 | type_name 3853 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $1 ) ) ); }3668 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3854 3669 | assignment_expression upupeq assignment_expression 3855 3670 | array_type_list ',' basic_type_name 3856 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3857 | array_type_list ',' type_name 3858 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc,maybeMoveBuildType( $3 ) ) ) )); }3671 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3672 | array_type_list ',' type_name 3673 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3859 3674 | array_type_list ',' assignment_expression upupeq assignment_expression 3860 3675 ; … … 3865 3680 | ErangeUpEq 3866 3681 { $$ = OperKinds::LEThan; } 3867 ;3682 ; 3868 3683 3869 3684 multi_array_dimension: 3870 3685 '[' push assignment_expression pop ']' 3871 { $$ = DeclarationNode::newArray( $3, nullptr, false ); }3686 { $$ = DeclarationNode::newArray( $3, 0, false ); } 3872 3687 | '[' push '*' pop ']' // C99 3873 3688 { $$ = DeclarationNode::newVarArray( 0 ); } 3874 3689 | multi_array_dimension '[' push assignment_expression pop ']' 3875 { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }3690 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); } 3876 3691 | multi_array_dimension '[' push '*' pop ']' // C99 3877 3692 { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); } … … 3970 3785 array_parameter_1st_dimension: 3971 3786 '[' ']' 3972 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }3787 { $$ = DeclarationNode::newArray( 0, 0, false ); } 3973 3788 // multi_array_dimension handles the '[' '*' ']' case 3974 3789 | '[' push type_qualifier_list '*' pop ']' // remaining C99 3975 3790 { $$ = DeclarationNode::newVarArray( $3 ); } 3976 3791 | '[' push type_qualifier_list pop ']' 3977 { $$ = DeclarationNode::newArray( nullptr, $3, false ); }3792 { $$ = DeclarationNode::newArray( 0, $3, false ); } 3978 3793 // multi_array_dimension handles the '[' assignment_expression ']' case 3979 3794 | '[' push type_qualifier_list assignment_expression pop ']' … … 4004 3819 variable_abstract_ptr: 4005 3820 ptrref_operator 4006 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }3821 { $$ = DeclarationNode::newPointer( 0, $1 ); } 4007 3822 | ptrref_operator type_qualifier_list 4008 3823 { $$ = DeclarationNode::newPointer( $2, $1 ); } 4009 3824 | ptrref_operator variable_abstract_declarator 4010 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3825 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4011 3826 | ptrref_operator type_qualifier_list variable_abstract_declarator 4012 3827 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } … … 4050 3865 // No SUE declaration in parameter list. 4051 3866 ptrref_operator type_specifier_nobody 4052 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3867 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4053 3868 | type_qualifier_list ptrref_operator type_specifier_nobody 4054 3869 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4055 3870 | ptrref_operator cfa_abstract_function 4056 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3871 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4057 3872 | type_qualifier_list ptrref_operator cfa_abstract_function 4058 3873 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4059 3874 | ptrref_operator cfa_identifier_parameter_declarator_tuple 4060 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3875 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4061 3876 | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple 4062 3877 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } … … 4067 3882 // shift/reduce conflict with new-style empty (void) function return type. 4068 3883 '[' ']' type_specifier_nobody 4069 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3884 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4070 3885 | cfa_array_parameter_1st_dimension type_specifier_nobody 4071 3886 { $$ = $2->addNewArray( $1 ); } 4072 3887 | '[' ']' multi_array_dimension type_specifier_nobody 4073 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3888 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4074 3889 | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody 4075 3890 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } … … 4078 3893 4079 3894 | '[' ']' cfa_identifier_parameter_ptr 4080 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3895 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4081 3896 | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr 4082 3897 { $$ = $2->addNewArray( $1 ); } 4083 3898 | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr 4084 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }3899 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 4085 3900 | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr 4086 3901 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } … … 4138 3953 cfa_abstract_ptr: // CFA 4139 3954 ptrref_operator type_specifier 4140 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3955 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4141 3956 | type_qualifier_list ptrref_operator type_specifier 4142 3957 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4143 3958 | ptrref_operator cfa_abstract_function 4144 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3959 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4145 3960 | type_qualifier_list ptrref_operator cfa_abstract_function 4146 3961 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); } 4147 3962 | ptrref_operator cfa_abstract_declarator_tuple 4148 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }3963 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); } 4149 3964 | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple 4150 3965 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
Note:
See TracChangeset
for help on using the changeset viewer.