- Timestamp:
- Mar 6, 2024, 6:06:43 AM (19 months ago)
- Branches:
- master
- Children:
- 647d633
- Parents:
- bbf2cb1 (diff), af60383 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
rbbf2cb1 rf6e8c67 82 82 83 83 DeclarationNode::~DeclarationNode() { 84 delete name; 85 84 86 // delete variable.name; 85 87 delete variable.assertions; … … 99 101 DeclarationNode * DeclarationNode::clone() const { 100 102 DeclarationNode * newnode = new DeclarationNode; 101 newnode-> set_next( maybeCopy( get_next() ));103 newnode->next = maybeCopy( next ); 102 104 newnode->name = name ? new string( *name ) : nullptr; 103 105 104 newnode->builtin = NoBuiltinType;105 106 newnode->type = maybeCopy( type ); 106 107 newnode->inLine = inLine; … … 170 171 171 172 void DeclarationNode::printList( std::ostream & os, int indent ) const { 172 Parse Node::printList( os, indent );173 ParseList::printList( os, indent ); 173 174 if ( hasEllipsis ) { 174 175 os << string( indent, ' ' ) << "and a variable number of other arguments" << endl; … … 433 434 DeclarationNode * newnode = new DeclarationNode; 434 435 newnode->type = new TypeData( TypeData::Builtin ); 435 newnode->builtin = bt; 436 newnode->type->builtintype = newnode->builtin; 436 newnode->type->builtintype = bt; 437 437 return newnode; 438 438 } // DeclarationNode::newBuiltinType … … 554 554 } // DeclarationNode::copySpecifiers 555 555 556 static void addQualifiersToType( TypeData *& src, TypeData * dst ) {557 if ( dst->base ) {558 addQualifiersToType( src, dst->base );559 } else if ( dst->kind == TypeData::Function ) {560 dst->base = src;561 src = nullptr;562 } else {563 dst->qualifiers |= src->qualifiers;564 } // if565 } // addQualifiersToType566 567 556 DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode * q ) { 568 557 if ( ! q ) { return this; } // empty qualifier … … 580 569 } // if 581 570 582 if ( q->type->forall ) { // forall qualifier ?583 if ( type->forall ) { // polymorphic routine ?584 type->forall->appendList( q->type->forall ); // augment forall qualifier585 } else {586 if ( type->kind == TypeData::Aggregate ) { // struct/union ?587 if ( type->aggregate.params ) { // polymorphic ?588 type->aggregate.params->appendList( q->type->forall ); // augment forall qualifier589 } else { // not polymorphic590 type->aggregate.params = q->type->forall; // set forall qualifier591 } // if592 } else { // not polymorphic593 type->forall = q->type->forall; // make polymorphic routine594 } // if595 } // if596 q->type->forall = nullptr; // forall qualifier moved597 } // if598 599 571 checkQualifiers( type, q->type ); 572 BuiltinType const builtin = type->builtintype; 600 573 if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) { 601 574 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] ); 602 575 } // if 603 addQualifiersToType( q->type, type ); 576 type = ::addQualifiers( q->type, type ); 577 q->type = nullptr; 604 578 605 579 delete q; … … 607 581 } // addQualifiers 608 582 609 static void addTypeToType( TypeData *& src, TypeData *& dst ) {610 if ( src->forall && dst->kind == TypeData::Function ) {611 if ( dst->forall ) {612 dst->forall->appendList( src->forall );613 } else {614 dst->forall = src->forall;615 } // if616 src->forall = nullptr;617 } // if618 if ( dst->base ) {619 addTypeToType( src, dst->base );620 } else {621 switch ( dst->kind ) {622 case TypeData::Unknown:623 src->qualifiers |= dst->qualifiers;624 dst = src;625 src = nullptr;626 break;627 case TypeData::Basic:628 dst->qualifiers |= src->qualifiers;629 if ( src->kind != TypeData::Unknown ) {630 assert( src->kind == TypeData::Basic );631 632 if ( dst->basictype == DeclarationNode::NoBasicType ) {633 dst->basictype = src->basictype;634 } else if ( src->basictype != DeclarationNode::NoBasicType )635 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",636 DeclarationNode::basicTypeNames[ dst->basictype ],637 DeclarationNode::basicTypeNames[ src->basictype ] );638 if ( dst->complextype == DeclarationNode::NoComplexType ) {639 dst->complextype = src->complextype;640 } else if ( src->complextype != DeclarationNode::NoComplexType )641 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",642 DeclarationNode::complexTypeNames[ src->complextype ],643 DeclarationNode::complexTypeNames[ src->complextype ] );644 if ( dst->signedness == DeclarationNode::NoSignedness ) {645 dst->signedness = src->signedness;646 } else if ( src->signedness != DeclarationNode::NoSignedness )647 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",648 DeclarationNode::signednessNames[ dst->signedness ],649 DeclarationNode::signednessNames[ src->signedness ] );650 if ( dst->length == DeclarationNode::NoLength ) {651 dst->length = src->length;652 } else if ( dst->length == DeclarationNode::Long && src->length == DeclarationNode::Long ) {653 dst->length = DeclarationNode::LongLong;654 } else if ( src->length != DeclarationNode::NoLength )655 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",656 DeclarationNode::lengthNames[ dst->length ],657 DeclarationNode::lengthNames[ src->length ] );658 } // if659 break;660 default:661 switch ( src->kind ) {662 case TypeData::Aggregate:663 case TypeData::Enum:664 dst->base = new TypeData( TypeData::AggregateInst );665 dst->base->aggInst.aggregate = src;666 if ( src->kind == TypeData::Aggregate ) {667 dst->base->aggInst.params = maybeCopy( src->aggregate.actuals );668 } // if669 dst->base->qualifiers |= src->qualifiers;670 src = nullptr;671 break;672 default:673 if ( dst->forall ) {674 dst->forall->appendList( src->forall );675 } else {676 dst->forall = src->forall;677 } // if678 src->forall = nullptr;679 dst->base = src;680 src = nullptr;681 } // switch682 } // switch683 } // if684 }685 686 583 DeclarationNode * DeclarationNode::addType( DeclarationNode * o, bool copyattr ) { 687 if ( o ) { 688 checkSpecifiers( o ); 689 copySpecifiers( o, copyattr ); 690 if ( o->type ) { 691 if ( ! type ) { 692 if ( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) { 693 // Hide type information aggregate instances. 694 type = new TypeData( TypeData::AggregateInst ); 695 type->aggInst.aggregate = o->type; // change ownership 696 type->aggInst.aggregate->aggregate.attributes.swap( o->attributes ); // change ownership 697 if ( o->type->kind == TypeData::Aggregate ) { 698 type->aggInst.hoistType = o->type->aggregate.body; 699 type->aggInst.params = maybeCopy( o->type->aggregate.actuals ); 700 } else { 701 type->aggInst.hoistType = o->type->enumeration.body; 702 } // if 703 type->qualifiers |= o->type->qualifiers; 704 } else { 705 type = o->type; 706 } // if 707 o->type = nullptr; // change ownership 708 } else { 709 addTypeToType( o->type, type ); 710 } // if 711 } // if 712 if ( o->bitfieldWidth ) { 713 bitfieldWidth = o->bitfieldWidth; 714 } // if 715 716 // there may be typedefs chained onto the type 717 if ( o->get_next() ) { 718 set_last( o->get_next()->clone() ); 719 } // if 720 } // if 584 if ( !o ) return this; 585 586 checkSpecifiers( o ); 587 copySpecifiers( o, copyattr ); 588 if ( o->type ) { 589 type = ::addType( o->type, type, o->attributes ); 590 o->type = nullptr; 591 } // if 592 if ( o->bitfieldWidth ) { 593 bitfieldWidth = o->bitfieldWidth; 594 } // if 595 596 // there may be typedefs chained onto the type 597 if ( o->next ) { 598 set_last( o->next->clone() ); 599 } // if 600 721 601 delete o; 722 723 602 return this; 724 603 } 725 604 726 605 DeclarationNode * DeclarationNode::addEnumBase( DeclarationNode * o ) { 727 if ( o && o->type ){728 type->base = o->type;606 if ( o && o->type ) { 607 type->base = o->type; 729 608 } // if 730 609 delete o; … … 745 624 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) { 746 625 if ( variable.assertions ) { 747 variable.assertions-> appendList( assertions );626 variable.assertions->set_last( assertions ); 748 627 } else { 749 628 variable.assertions = assertions; … … 756 635 case TypeData::Symbolic: 757 636 if ( type->symbolic.assertions ) { 758 type->symbolic.assertions-> appendList( assertions );637 type->symbolic.assertions->set_last( assertions ); 759 638 } else { 760 639 type->symbolic.assertions = assertions; … … 810 689 DeclarationNode * DeclarationNode::setBase( TypeData * newType ) { 811 690 if ( type ) { 812 TypeData * prevBase = type; 813 TypeData * curBase = type->base; 814 while ( curBase != nullptr ) { 815 prevBase = curBase; 816 curBase = curBase->base; 817 } // while 818 prevBase->base = newType; 691 type->setLastBase( newType ); 819 692 } else { 820 693 type = newType; … … 857 730 assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference ); 858 731 if ( type ) { 859 switch ( type->kind ) { 860 case TypeData::Aggregate: 861 case TypeData::Enum: 862 p->type->base = new TypeData( TypeData::AggregateInst ); 863 p->type->base->aggInst.aggregate = type; 864 if ( type->kind == TypeData::Aggregate ) { 865 p->type->base->aggInst.params = maybeCopy( type->aggregate.actuals ); 866 } // if 867 p->type->base->qualifiers |= type->qualifiers; 868 break; 869 870 default: 871 p->type->base = type; 872 } // switch 732 p->type->base = makeNewBase( type ); 873 733 type = nullptr; 874 734 } // if … … 880 740 } 881 741 882 static TypeData * findLast( TypeData * a ) {883 assert( a );884 TypeData * cur = a;885 while ( cur->base ) {886 cur = cur->base;887 } // while888 return cur;889 }890 891 742 DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) { 892 743 if ( ! a ) return this; 893 744 assert( a->type->kind == TypeData::Array ); 894 TypeData * lastArray = findLast( a->type );895 745 if ( type ) { 896 switch ( type->kind ) { 897 case TypeData::Aggregate: 898 case TypeData::Enum: 899 lastArray->base = new TypeData( TypeData::AggregateInst ); 900 lastArray->base->aggInst.aggregate = type; 901 if ( type->kind == TypeData::Aggregate ) { 902 lastArray->base->aggInst.params = maybeCopy( type->aggregate.actuals ); 903 } // if 904 lastArray->base->qualifiers |= type->qualifiers; 905 break; 906 default: 907 lastArray->base = type; 908 } // switch 746 a->type->setLastBase( makeNewBase( type ) ); 909 747 type = nullptr; 910 748 } // if … … 960 798 DeclarationNode * DeclarationNode::cloneBaseType( DeclarationNode * o, bool copyattr ) { 961 799 if ( ! o ) return nullptr; 962 963 800 o->copySpecifiers( this, copyattr ); 964 801 if ( type ) { 965 TypeData * srcType = type; 966 967 // search for the base type by scanning off pointers and array designators 968 while ( srcType->base ) { 969 srcType = srcType->base; 970 } // while 971 972 TypeData * newType = srcType->clone(); 973 if ( newType->kind == TypeData::AggregateInst ) { 974 // don't duplicate members 975 if ( newType->aggInst.aggregate->kind == TypeData::Enum ) { 976 delete newType->aggInst.aggregate->enumeration.constants; 977 newType->aggInst.aggregate->enumeration.constants = nullptr; 978 newType->aggInst.aggregate->enumeration.body = false; 979 } else { 980 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate ); 981 delete newType->aggInst.aggregate->aggregate.fields; 982 newType->aggInst.aggregate->aggregate.fields = nullptr; 983 newType->aggInst.aggregate->aggregate.body = false; 984 } // if 985 // don't hoist twice 986 newType->aggInst.hoistType = false; 987 } // if 988 989 newType->forall = maybeCopy( type->forall ); 990 if ( ! o->type ) { 991 o->type = newType; 992 } else { 993 addTypeToType( newType, o->type ); 994 delete newType; 995 } // if 802 o->type = ::cloneBaseType( type, o->type ); 996 803 } // if 997 804 return o; … … 1099 906 std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList ); 1100 907 1101 for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur )) {908 for ( const DeclarationNode * cur = firstNode ; cur ; cur = cur->next ) { 1102 909 try { 1103 910 bool extracted_named = false; … … 1167 974 std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList ); 1168 975 1169 for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur )) {976 for ( const DeclarationNode * cur = firstNode; cur; cur = cur->next ) { 1170 977 try { 1171 978 ast::Decl * decl = cur->build(); … … 1217 1024 std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList ); 1218 1025 1219 for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur )) {1026 for ( const DeclarationNode * cur = firstNode ; cur ; cur = cur->next ) { 1220 1027 try { 1221 1028 * out++ = cur->buildType(); -
src/Parser/DeclarationNode.h
rbbf2cb1 rf6e8c67 19 19 20 20 struct TypeData; 21 classInitializerNode;22 23 struct DeclarationNode : public ParseNode{21 struct InitializerNode; 22 23 struct DeclarationNode final : public ParseList<DeclarationNode> { 24 24 // These enumerations must harmonize with their names in DeclarationNode.cc. 25 25 enum BasicType { … … 108 108 DeclarationNode * cloneBaseType( DeclarationNode * newdecl, bool = true ); 109 109 110 DeclarationNode * appendList( DeclarationNode * node ) {111 return (DeclarationNode *)set_last( node );112 }113 114 110 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override; 115 111 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override; … … 129 125 DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; } 130 126 131 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }127 const std::string * name = nullptr; 132 128 133 129 struct Variable_t { … … 144 140 }; 145 141 StaticAssert_t assert; 146 147 BuiltinType builtin = NoBuiltinType;148 142 149 143 TypeData * type = nullptr; … … 177 171 } 178 172 179 template<typename NodeType>180 NodeType * strict_next( NodeType * node ) {181 ParseNode * next = node->get_next();182 if ( nullptr == next ) return nullptr;183 if ( NodeType * ret = dynamic_cast<NodeType *>( next ) ) return ret;184 SemanticError( next->location, "internal error, non-homogeneous nodes founds in buildList processing." );185 }186 187 173 // This generic buildList is here along side its overloads. 188 174 template<typename AstType, typename NodeType, … … 193 179 std::back_insert_iterator<Container<ast::ptr<AstType>, Args...>> out( output ); 194 180 195 for ( NodeType * cur = firstNode ; cur ; cur = strict_next( cur )) {181 for ( NodeType * cur = firstNode ; cur ; cur = cur->next ) { 196 182 try { 197 183 AstType * node = dynamic_cast<AstType *>( maybeBuild( cur ) ); -
src/Parser/ExpressionNode.h
rbbf2cb1 rf6e8c67 18 18 #include "ParseNode.h" 19 19 20 classInitializerNode;20 struct InitializerNode; 21 21 22 class ExpressionNode final : public ParseNode { 23 public: 22 struct ExpressionNode final : public ParseList<ExpressionNode> { 24 23 ExpressionNode( ast::Expr * expr = nullptr ) : expr( expr ) {} 25 24 virtual ~ExpressionNode() {} 26 25 virtual ExpressionNode * clone() const override { 27 26 if ( nullptr == expr ) return nullptr; 28 return static_cast<ExpressionNode*>( 29 (new ExpressionNode( ast::shallowCopy( expr.get() ) ))->set_next( maybeCopy( get_next() ) )); 27 ExpressionNode * node = new ExpressionNode( ast::shallowCopy( expr.get() ) ); 28 node->next = maybeCopy( next ); 29 return node; 30 30 } 31 31 -
src/Parser/InitializerNode.cc
rbbf2cb1 rf6e8c67 36 36 : expr( _expr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ), isDelete( false ) { 37 37 if ( aggrp ) 38 kids = dynamic_cast< InitializerNode * >( get_next() );38 kids = next; 39 39 40 40 if ( kids ) … … 48 48 49 49 if ( aggrp ) 50 kids = dynamic_cast< InitializerNode * >( get_next() );50 kids = next; 51 51 52 52 if ( kids ) 53 set_next( nullptr );53 next = nullptr; 54 54 } // InitializerNode::InitializerNode 55 55 … … 73 73 while ( curdes != nullptr) { 74 74 curdes->printOneLine(os); 75 curdes = (ExpressionNode *)(curdes->get_next());75 curdes = curdes->next; 76 76 if ( curdes ) os << ", "; 77 77 } // while … … 87 87 88 88 InitializerNode *moreInit; 89 if ( ( moreInit = dynamic_cast< InitializerNode * >( get_next() )) ) {89 if ( ( moreInit = next ) ) { 90 90 moreInit->printOneLine( os ); 91 91 } // if … … 98 98 std::vector<ast::ptr<ast::Designation>> designlist; 99 99 InitializerNode * child = next_init(); 100 for ( ; child != nullptr ; child = dynamic_cast< InitializerNode * >( child->get_next() )) {100 for ( ; child != nullptr ; child = child->next ) { 101 101 std::deque<ast::ptr<ast::Expr>> desList; 102 102 buildList( child->designator, desList ); -
src/Parser/InitializerNode.h
rbbf2cb1 rf6e8c67 18 18 #include "ParseNode.h" 19 19 20 class InitializerNode : public ParseNode { 21 public: 20 struct InitializerNode final : public ParseList<InitializerNode> { 22 21 InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr ); 23 22 InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr ); -
src/Parser/ParseNode.h
rbbf2cb1 rf6e8c67 33 33 34 34 struct DeclarationNode; 35 classInitializerNode;36 classExpressionNode;35 struct InitializerNode; 36 struct ExpressionNode; 37 37 struct StatementNode; 38 38 … … 45 45 extern YYLTYPE yylloc; 46 46 47 class ParseNode { 48 public: 49 ParseNode() {}; 50 virtual ~ParseNode() { delete next; delete name; }; 47 struct ParseNode { 48 ParseNode() {} 49 virtual ~ParseNode() {} 51 50 virtual ParseNode * clone() const = 0; 52 51 53 ParseNode * get_next() const { return next; } 54 ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; } 52 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {} 55 53 56 ParseNode * get_last() { 57 ParseNode * current; 58 for ( current = this; current->get_next() != nullptr; current = current->get_next() ); 54 static int indent_by; 55 56 CodeLocation location = yylloc; 57 }; // ParseNode 58 59 /// Only ever use in the form `struct NAME final : public ParseList<NAME>`! 60 template<typename Next> 61 struct ParseList : public ParseNode { 62 ParseList() {} 63 virtual ~ParseList() { delete next; }; 64 virtual ParseList<Next> * clone() const = 0; 65 66 Next * get_last() { 67 Next * current = static_cast<Next *>( this ); 68 while ( current->next != nullptr ) current = current->next; 59 69 return current; 60 70 } 61 ParseNode * set_last( ParseNode* newlast ) {62 if ( newlast != nullptr ) get_last()-> set_next( newlast );63 return this;71 Next * set_last( Next * newlast ) { 72 if ( newlast != nullptr ) get_last()->next = newlast; 73 return static_cast<Next *>( this ); 64 74 } 65 75 66 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}67 76 virtual void printList( std::ostream & os, int indent = 0 ) const { 68 77 print( os, indent ); … … 70 79 } 71 80 72 static int indent_by; 73 74 ParseNode * next = nullptr; 75 const std::string * name = nullptr; 76 CodeLocation location = yylloc; 77 }; // ParseNode 81 Next * next = nullptr; 82 }; 78 83 79 84 // Must harmonize with OperName. -
src/Parser/StatementNode.cc
rbbf2cb1 rf6e8c67 54 54 StatementNode * nextStmt = new StatementNode( 55 55 new ast::DeclStmt( decl->location, maybeBuild( decl ) ) ); 56 set_next( nextStmt );57 if ( decl-> get_next()) {58 get_next()->set_next( new StatementNode( dynamic_cast< DeclarationNode * >(decl->get_next()) ));59 decl-> set_next( 0 );56 next = nextStmt; 57 if ( decl->next ) { 58 next->next = new StatementNode( decl->next ); 59 decl->next = nullptr; 60 60 } // if 61 61 } else { 62 if ( decl-> get_next()) {63 set_next( new StatementNode( dynamic_cast< DeclarationNode * >( decl->get_next() ) ));64 decl-> set_next( 0 );62 if ( decl->next ) { 63 next = new StatementNode( decl->next ); 64 decl->next = nullptr; 65 65 } // if 66 66 agg = decl; … … 87 87 ClauseNode * prev = this; 88 88 // find end of list and maintain previous pointer 89 for ( ClauseNode * curr = prev; curr != nullptr; curr = (ClauseNode *)curr->get_next()) {90 ClauseNode * node = strict_dynamic_cast< ClauseNode * >(curr);89 for ( ClauseNode * curr = prev; curr != nullptr; curr = curr->next ) { 90 ClauseNode * node = curr; 91 91 assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) ); 92 92 prev = curr; 93 93 } // for 94 ClauseNode * node = dynamic_cast< ClauseNode * >(prev);94 ClauseNode * node = prev; 95 95 // convert from StatementNode list to Statement list 96 96 std::vector<ast::ptr<ast::Stmt>> stmts; … … 332 332 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 333 333 334 ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );335 targetExpr-> set_next( nullptr );334 ExpressionNode * next = targetExpr->next; 335 targetExpr->next = nullptr; 336 336 buildMoveList( next, clause->target_args ); 337 337 -
src/Parser/StatementNode.h
rbbf2cb1 rf6e8c67 18 18 #include "ParseNode.h" 19 19 20 struct StatementNode final : public Parse Node{20 struct StatementNode final : public ParseList<StatementNode> { 21 21 StatementNode() : stmt( nullptr ) {} 22 22 StatementNode( ast::Stmt * stmt ) : stmt( stmt ) {} … … 39 39 }; // StatementNode 40 40 41 struct ClauseNode final : public Parse Node{41 struct ClauseNode final : public ParseList<ClauseNode> { 42 42 ClauseNode( ast::StmtClause * clause ) : clause( clause ) {} 43 43 virtual ~ClauseNode() {} 44 45 ClauseNode * set_last( ParseNode * newlast ) {46 ParseNode::set_last( newlast );47 return this;48 }49 44 50 45 virtual ClauseNode * clone() const final { assert( false ); return nullptr; } -
src/Parser/TypeData.cc
rbbf2cb1 rf6e8c67 479 479 480 480 481 TypeData * TypeData::getLastBase() { 482 TypeData * cur = this; 483 while ( cur->base ) cur = cur->base; 484 return cur; 485 } 486 487 void TypeData::setLastBase( TypeData * newBase ) { 488 getLastBase()->base = newBase; 489 } 490 491 // Takes ownership of src. 492 static void addQualifiersToType( TypeData * dst, TypeData * src ) { 493 if ( dst->base ) { 494 addQualifiersToType( dst->base, src ); 495 } else if ( dst->kind == TypeData::Function ) { 496 dst->base = src; 497 src = nullptr; 498 } else { 499 dst->qualifiers |= src->qualifiers; 500 delete src; 501 } // if 502 } 503 504 // Takes ownership of all arguments, gives ownership of return value. 505 TypeData * addQualifiers( TypeData * ltype, TypeData * rtype ) { 506 if ( ltype->forall ) { 507 if ( rtype->forall ) { 508 rtype->forall->set_last( ltype->forall ); 509 } else if ( TypeData::Aggregate != rtype->kind ) { 510 rtype->forall = ltype->forall; 511 } else if ( rtype->aggregate.params ) { 512 rtype->aggregate.params->set_last( ltype->forall ); 513 } else { 514 rtype->aggregate.params = ltype->forall; 515 } 516 ltype->forall = nullptr; 517 } 518 519 addQualifiersToType( rtype, ltype ); 520 return rtype; 521 } 522 523 // Helper for addType and cloneBaseType. 524 static void addTypeToType( TypeData *& dst, TypeData *& src ) { 525 if ( src->forall && dst->kind == TypeData::Function ) { 526 if ( dst->forall ) { 527 dst->forall->set_last( src->forall ); 528 } else { 529 dst->forall = src->forall; 530 } // if 531 src->forall = nullptr; 532 } // if 533 if ( dst->base ) { 534 addTypeToType( dst->base, src ); 535 return; 536 } 537 switch ( dst->kind ) { 538 case TypeData::Unknown: 539 src->qualifiers |= dst->qualifiers; 540 // LEAKS dst? 541 dst = src; 542 src = nullptr; 543 break; 544 case TypeData::Basic: 545 dst->qualifiers |= src->qualifiers; 546 if ( src->kind != TypeData::Unknown ) { 547 assert( src->kind == TypeData::Basic ); 548 549 if ( dst->basictype == DeclarationNode::NoBasicType ) { 550 dst->basictype = src->basictype; 551 } else if ( src->basictype != DeclarationNode::NoBasicType ) { 552 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".", 553 DeclarationNode::basicTypeNames[ dst->basictype ], 554 DeclarationNode::basicTypeNames[ src->basictype ] ); 555 } 556 if ( dst->complextype == DeclarationNode::NoComplexType ) { 557 dst->complextype = src->complextype; 558 } else if ( src->complextype != DeclarationNode::NoComplexType ) { 559 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".", 560 DeclarationNode::complexTypeNames[ src->complextype ], 561 DeclarationNode::complexTypeNames[ src->complextype ] ); 562 } 563 if ( dst->signedness == DeclarationNode::NoSignedness ) { 564 dst->signedness = src->signedness; 565 } else if ( src->signedness != DeclarationNode::NoSignedness ) { 566 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".", 567 DeclarationNode::signednessNames[ dst->signedness ], 568 DeclarationNode::signednessNames[ src->signedness ] ); 569 } 570 if ( dst->length == DeclarationNode::NoLength ) { 571 dst->length = src->length; 572 } else if ( dst->length == DeclarationNode::Long && src->length == DeclarationNode::Long ) { 573 dst->length = DeclarationNode::LongLong; 574 } else if ( src->length != DeclarationNode::NoLength ) { 575 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".", 576 DeclarationNode::lengthNames[ dst->length ], 577 DeclarationNode::lengthNames[ src->length ] ); 578 } 579 } // if 580 break; 581 default: 582 switch ( src->kind ) { 583 case TypeData::Aggregate: 584 case TypeData::Enum: 585 dst->base = new TypeData( TypeData::AggregateInst ); 586 dst->base->aggInst.aggregate = src; 587 if ( src->kind == TypeData::Aggregate ) { 588 dst->base->aggInst.params = maybeCopy( src->aggregate.actuals ); 589 } // if 590 dst->base->qualifiers |= src->qualifiers; 591 src = nullptr; 592 break; 593 default: 594 if ( dst->forall ) { 595 dst->forall->set_last( src->forall ); 596 } else { 597 dst->forall = src->forall; 598 } // if 599 src->forall = nullptr; 600 dst->base = src; 601 src = nullptr; 602 } // switch 603 } // switch 604 } 605 606 // Takes ownership of all arguments, gives ownership of return value. 607 TypeData * addType( TypeData * ltype, TypeData * rtype, std::vector<ast::ptr<ast::Attribute>> & attributes ) { 608 if ( rtype ) { 609 addTypeToType( rtype, ltype ); 610 return rtype; 611 } else { 612 if ( ltype->kind == TypeData::Aggregate || ltype->kind == TypeData::Enum ) { 613 // Hide type information aggregate instances. 614 rtype = new TypeData( TypeData::AggregateInst ); 615 rtype->aggInst.aggregate = ltype; 616 rtype->aggInst.aggregate->aggregate.attributes.swap( attributes ); // change ownership 617 if ( ltype->kind == TypeData::Aggregate ) { 618 rtype->aggInst.hoistType = ltype->aggregate.body; 619 rtype->aggInst.params = maybeCopy( ltype->aggregate.actuals ); 620 } else { 621 rtype->aggInst.hoistType = ltype->enumeration.body; 622 } // if 623 rtype->qualifiers |= ltype->qualifiers; 624 } else { 625 rtype = ltype; 626 } // if 627 return rtype; 628 } // if 629 } 630 631 // Takes ownership of both arguments, gives ownership of return value. 632 TypeData * cloneBaseType( TypeData * type, TypeData * other ) { 633 TypeData * newType = type->getLastBase()->clone(); 634 if ( newType->kind == TypeData::AggregateInst ) { 635 // don't duplicate members 636 if ( newType->aggInst.aggregate->kind == TypeData::Enum ) { 637 delete newType->aggInst.aggregate->enumeration.constants; 638 newType->aggInst.aggregate->enumeration.constants = nullptr; 639 newType->aggInst.aggregate->enumeration.body = false; 640 } else { 641 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate ); 642 delete newType->aggInst.aggregate->aggregate.fields; 643 newType->aggInst.aggregate->aggregate.fields = nullptr; 644 newType->aggInst.aggregate->aggregate.body = false; 645 } // if 646 // don't hoist twice 647 newType->aggInst.hoistType = false; 648 } // if 649 newType->forall = maybeCopy( type->forall ); 650 651 if ( other ) { 652 addTypeToType( other, newType ); 653 delete newType; 654 return other; 655 } // if 656 return newType; 657 } 658 659 TypeData * makeNewBase( TypeData * type ) { 660 switch ( type->kind ) { 661 case TypeData::Aggregate: 662 case TypeData::Enum: { 663 TypeData * out = new TypeData( TypeData::AggregateInst ); 664 out->aggInst.aggregate = type; 665 if ( TypeData::Aggregate == type->kind ) { 666 out->aggInst.params = maybeCopy( type->aggregate.actuals ); 667 } 668 out->qualifiers |= type->qualifiers; 669 return out; 670 } 671 default: 672 return type; 673 } // switch 674 } 675 676 481 677 void buildForall( 482 678 const DeclarationNode * firstNode, … … 494 690 for ( auto i = outputList.begin() ; 495 691 i != outputList.end() ; 496 ++i, n = (DeclarationNode*)n->get_next()) {692 ++i, n = n->next ) { 497 693 // Only the object type class adds additional assertions. 498 694 if ( n->variable.tyClass != ast::TypeDecl::Otype ) { … … 639 835 for ( auto i = outputForall.begin() ; 640 836 i != outputForall.end() ; 641 ++i, n = (DeclarationNode*)n->get_next()) {837 ++i, n = n->next ) { 642 838 // Only the object type class adds additional assertions. 643 839 if ( n->variable.tyClass != ast::TypeDecl::Otype ) { … … 1272 1468 auto members = ret->members.begin(); 1273 1469 ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible; 1274 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {1470 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = cur->next, ++members ) { 1275 1471 if ( cur->enumInLine ) { 1276 1472 // Do Nothing … … 1500 1696 assert( ! function.params ); 1501 1697 // loop over declaration first as it is easier to spot errors 1502 for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = d ynamic_cast< DeclarationNode * >( decl->get_next() )) {1698 for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = decl->next ) { 1503 1699 // scan ALL parameter names for each declaration name to check for duplicates 1504 for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode * >( param->get_next() )) {1700 for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) { 1505 1701 if ( *decl->name == *param->name ) { 1506 1702 // type set => parameter name already transformed by a declaration names so there is a duplicate … … 1524 1720 // rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {} 1525 1721 1526 for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode * >( param->get_next() )) {1722 for ( DeclarationNode * param = function.idList; param != nullptr; param = param->next ) { 1527 1723 if ( ! param->type ) { // generate type int for empty parameter type 1528 1724 param->type = new TypeData( TypeData::Basic ); -
src/Parser/TypeData.h
rbbf2cb1 rf6e8c67 111 111 112 112 const std::string * leafName() const; 113 114 TypeData * getLastBase(); 115 void setLastBase( TypeData * ); 113 116 }; 117 118 TypeData * addQualifiers( TypeData * ltype, TypeData * rtype ); 119 TypeData * addType( TypeData * ltype, TypeData * rtype, std::vector<ast::ptr<ast::Attribute>> & ); 120 TypeData * cloneBaseType( TypeData * type, TypeData * other ); 121 TypeData * makeNewBase( TypeData * type ); 114 122 115 123 ast::Type * typebuild( const TypeData * ); -
src/Parser/lex.ll
rbbf2cb1 rf6e8c67 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Tue Oct 3 17:10:57 202313 * Update Count : 77 312 * Last Modified On : Sat Feb 24 11:47:24 2024 13 * Update Count : 777 14 14 */ 15 15 … … 407 407 ";" { ASCIIOP_RETURN(); } 408 408 "." { ASCIIOP_RETURN(); } // also operator 409 "@@" { NAMEDOP_RETURN(ATTR); } // CFA, attribute shorthand 409 410 "..." { NAMEDOP_RETURN(ELLIPSIS); } 410 411 -
src/Parser/parser.yy
rbbf2cb1 rf6e8c67 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 23 18:25:46202413 // Update Count : 6 48412 // Last Modified On : Mon Mar 4 08:44:25 2024 13 // Update Count : 6562 14 14 // 15 15 … … 126 126 DeclarationNode * cl = (new DeclarationNode)->addType( typeSpec ); // typeSpec IS DELETED!!! 127 127 128 // Start at second variable in declaration list and clone the type specifiers for each variable. .129 for ( DeclarationNode * cur = d ynamic_cast<DeclarationNode *>( declList->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() )) {128 // Start at second variable in declaration list and clone the type specifiers for each variable. 129 for ( DeclarationNode * cur = declList->next ; cur != nullptr; cur = cur->next ) { 130 130 cl->cloneBaseType( cur, copyattr ); // cur is modified 131 131 } // for … … 139 139 void distExt( DeclarationNode * declaration ) { 140 140 // distribute EXTENSION across all declarations 141 for ( DeclarationNode *iter = declaration ; iter != nullptr; iter = (DeclarationNode *)iter->get_next()) {141 for ( DeclarationNode *iter = declaration ; iter != nullptr ; iter = iter->next ) { 142 142 iter->set_extension( true ); 143 143 } // for … … 146 146 void distInl( DeclarationNode * declaration ) { 147 147 // distribute INLINE across all declarations 148 for ( DeclarationNode *iter = declaration ; iter != nullptr; iter = (DeclarationNode *)iter->get_next()) {148 for ( DeclarationNode *iter = declaration ; iter != nullptr ; iter = iter->next ) { 149 149 iter->set_inLine( true ); 150 150 } // for … … 153 153 void distQual( DeclarationNode * declaration, DeclarationNode * qualifiers ) { 154 154 // distribute qualifiers across all non-variable declarations in a distribution statemement 155 for ( DeclarationNode * iter = declaration ; iter != nullptr; iter = (DeclarationNode *)iter->get_next()) {155 for ( DeclarationNode * iter = declaration ; iter != nullptr ; iter = iter->next ) { 156 156 // SKULLDUGGERY: Distributions are parsed inside out, so qualifiers are added to declarations inside out. Since 157 157 // addQualifiers appends to the back of the list, the forall clauses are in the wrong order (right to left). To … … 389 389 %token LE GE EQ NE // <= >= == != 390 390 %token ANDAND OROR // && || 391 %token ELLIPSIS //...391 %token ATTR ELLIPSIS // @@ ... 392 392 393 393 %token EXPassign MULTassign DIVassign MODassign // \= *= /= %= … … 433 433 %type<stmt> statement labeled_statement compound_statement 434 434 %type<stmt> statement_decl statement_decl_list statement_list_nodecl 435 %type<stmt> selection_statement if_statement435 %type<stmt> selection_statement 436 436 %type<clause> switch_clause_list_opt switch_clause_list 437 437 %type<expr> case_value … … 500 500 %type<decl> cfa_identifier_parameter_declarator_tuple cfa_identifier_parameter_ptr 501 501 502 %type<decl> cfa_parameter_declaration cfa_parameter_list cfa_parameter_ ellipsis_list_opt502 %type<decl> cfa_parameter_declaration cfa_parameter_list cfa_parameter_list_ellipsis_opt 503 503 504 504 %type<decl> cfa_typedef_declaration cfa_variable_declaration cfa_variable_specifier … … 508 508 %type<decl> KR_parameter_list KR_parameter_list_opt 509 509 510 %type<decl> parameter_declaration parameter_list parameter_ type_list_opt510 %type<decl> parameter_declaration parameter_list parameter_list_ellipsis_opt 511 511 512 512 %type<decl> paren_identifier paren_type … … 530 530 %type<decl> type_parameter type_parameter_list type_initializer_opt 531 531 532 %type<expr> type_parameters_opt type_list array_type_list 532 %type<expr> type_parameters_opt type_list array_type_list // array_dimension_list 533 533 534 534 %type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list … … 1246 1246 ; 1247 1247 1248 // if, switch, and choose require parenthesis around the conditional because it can be followed by a statement. 1249 // For example, without parenthesis: 1250 // 1251 // if x + y + z; => "if ( x + y ) + z" or "if ( x ) + y + z" 1252 // switch ( S ) { ... } => switch ( S ) { compound literal... } ... or 1253 1248 1254 selection_statement: 1249 // pop causes a S/R conflict without separating the IF statement into a non-terminal even after resolving 1250 // the inherent S/R conflict with THEN/ELSE. 1251 push if_statement pop 1252 { $$ = $2; } 1255 IF '(' conditional_declaration ')' statement %prec THEN 1256 // explicitly deal with the shift/reduce conflict on if/else 1257 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); } 1258 | IF '(' conditional_declaration ')' statement ELSE statement 1259 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc, $7 ) ) ); } 1253 1260 | SWITCH '(' comma_expression ')' case_clause 1254 1261 { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); } … … 1274 1281 | CHOOSE '(' comma_expression ')' '{' error '}' // CFA, invalid syntax rule 1275 1282 { SemanticError( yylloc, "syntax error, declarations can only appear before the list of case clauses." ); $$ = nullptr; } 1276 ;1277 1278 if_statement:1279 IF '(' conditional_declaration ')' statement %prec THEN1280 // explicitly deal with the shift/reduce conflict on if/else1281 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); }1282 | IF '(' conditional_declaration ')' statement ELSE statement1283 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc, $7 ) ) ); }1284 1283 ; 1285 1284 … … 1897 1896 declaration_list: 1898 1897 declaration 1899 | declaration_list declaration { $$ = $1->appendList( $2 ); } 1898 | declaration_list declaration 1899 { $$ = $1->set_last( $2 ); } 1900 1900 ; 1901 1901 … … 1910 1910 { $$ = $1; } 1911 1911 | KR_parameter_list c_declaration ';' 1912 { $$ = $1-> appendList( $2 ); }1912 { $$ = $1->set_last( $2 ); } 1913 1913 ; 1914 1914 … … 1968 1968 { $$ = $2->addQualifiers( $1 )->addInitializer( $3 ); } 1969 1969 | cfa_variable_declaration pop ',' push identifier_or_type_name initializer_opt 1970 { $$ = $1-> appendList( $1->cloneType( $5 )->addInitializer( $6 ) ); }1970 { $$ = $1->set_last( $1->cloneType( $5 )->addInitializer( $6 ) ); } 1971 1971 ; 1972 1972 … … 1990 1990 | declaration_qualifier_list type_qualifier_list cfa_function_specifier 1991 1991 { $$ = $3->addQualifiers( $1 )->addQualifiers( $2 ); } 1992 | cfa_function_declaration ',' identifier_or_type_name '(' push cfa_parameter_ ellipsis_list_opt pop ')'1992 | cfa_function_declaration ',' identifier_or_type_name '(' push cfa_parameter_list_ellipsis_opt pop ')' 1993 1993 { 1994 1994 // Append the return type at the start (left-hand-side) to each identifier in the list. 1995 1995 DeclarationNode * ret = new DeclarationNode; 1996 1996 ret->type = maybeCopy( $1->type->base ); 1997 $$ = $1-> appendList( DeclarationNode::newFunction( $3, ret, $6, nullptr ) );1997 $$ = $1->set_last( DeclarationNode::newFunction( $3, ret, $6, nullptr ) ); 1998 1998 } 1999 1999 ; 2000 2000 2001 2001 cfa_function_specifier: // CFA 2002 // '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict 2003 // { 2004 // $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true ); 2005 // } 2006 // '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')' 2007 // { 2008 // typedefTable.setNextIdentifier( *$5 ); 2009 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true ); 2010 // } 2011 // | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')' 2012 // { 2013 // typedefTable.setNextIdentifier( *$5 ); 2014 // $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true ); 2015 // } 2016 // | '[' ']' typegen_name 2002 '[' ']' identifier '(' push cfa_parameter_list_ellipsis_opt pop ')' attribute_list_opt 2003 { $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( nullptr ), $6, nullptr )->addQualifiers( $9 ); } 2004 | '[' ']' TYPEDEFname '(' push cfa_parameter_list_ellipsis_opt pop ')' attribute_list_opt 2005 { $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( nullptr ), $6, nullptr )->addQualifiers( $9 ); } 2006 // | '[' ']' TYPEGENname '(' push cfa_parameter_list_ellipsis_opt pop ')' attribute_list_opt 2007 // { $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( nullptr ), $6, nullptr )->addQualifiers( $9 ); } 2008 2017 2009 // identifier_or_type_name must be broken apart because of the sequence: 2018 2010 // 2019 // '[' ']' identifier_or_type_name '(' cfa_parameter_ ellipsis_list_opt ')'2011 // '[' ']' identifier_or_type_name '(' cfa_parameter_list_ellipsis_opt ')' 2020 2012 // '[' ']' type_specifier 2021 2013 // 2022 2014 // type_specifier can resolve to just TYPEDEFname (e.g., typedef int T; int f( T );). Therefore this must be 2023 2015 // flattened to allow lookahead to the '(' without having to reduce identifier_or_type_name. 2024 cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt2016 | cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_list_ellipsis_opt pop ')' attribute_list_opt 2025 2017 // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator). 2026 2018 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); } 2027 | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ ellipsis_list_opt pop ')' attribute_list_opt2019 | cfa_function_return identifier_or_type_name '(' push cfa_parameter_list_ellipsis_opt pop ')' attribute_list_opt 2028 2020 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); } 2029 2021 ; … … 2032 2024 '[' push cfa_parameter_list pop ']' 2033 2025 { $$ = DeclarationNode::newTuple( $3 ); } 2034 | '[' push cfa_parameter_list pop ',' pushcfa_abstract_parameter_list pop ']'2026 | '[' push cfa_parameter_list ',' cfa_abstract_parameter_list pop ']' 2035 2027 // To obtain LR(1 ), the last cfa_abstract_parameter_list is added into this flattened rule to lookahead to the ']'. 2036 { $$ = DeclarationNode::newTuple( $3-> appendList( $7) ); }2028 { $$ = DeclarationNode::newTuple( $3->set_last( $5 ) ); } 2037 2029 ; 2038 2030 … … 2048 2040 $$ = $2->addTypedef(); 2049 2041 } 2050 | cfa_typedef_declaration pop ',' pushidentifier2051 { 2052 typedefTable.addToEnclosingScope( *$ 5, TYPEDEFname, "cfa_typedef_declaration 3" );2053 $$ = $1-> appendList( $1->cloneType( $5) );2042 | cfa_typedef_declaration ',' identifier 2043 { 2044 typedefTable.addToEnclosingScope( *$3, TYPEDEFname, "cfa_typedef_declaration 3" ); 2045 $$ = $1->set_last( $1->cloneType( $3 ) ); 2054 2046 } 2055 2047 ; … … 2069 2061 { 2070 2062 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "typedef_declaration 2" ); 2071 $$ = $1-> appendList( $1->cloneBaseType( $3 )->addTypedef() );2063 $$ = $1->set_last( $1->cloneBaseType( $3 )->addTypedef() ); 2072 2064 } 2073 2065 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 ) … … 2123 2115 2124 2116 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 2125 { $$ = $1-> appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); }2117 { $$ = $1->set_last( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); } 2126 2118 ; 2127 2119 … … 2587 2579 { $$ = nullptr; } 2588 2580 | field_declaration_list_opt field_declaration 2589 { $$ = $1 ? $1-> appendList( $2 ) : $2; }2581 { $$ = $1 ? $1->set_last( $2 ) : $2; } 2590 2582 ; 2591 2583 … … 2635 2627 | field_declarator 2636 2628 | field_declaring_list_opt ',' attribute_list_opt field_declarator 2637 { $$ = $1-> appendList( $4->addQualifiers( $3 ) ); }2629 { $$ = $1->set_last( $4->addQualifiers( $3 ) ); } 2638 2630 ; 2639 2631 … … 2657 2649 | field_abstract 2658 2650 | field_abstract_list_opt ',' attribute_list_opt field_abstract 2659 { $$ = $1-> appendList( $4->addQualifiers( $3 ) ); }2651 { $$ = $1->set_last( $4->addQualifiers( $3 ) ); } 2660 2652 ; 2661 2653 … … 2670 2662 { $$ = $1->addName( $2 ); } 2671 2663 | cfa_field_declaring_list ',' identifier_or_type_name 2672 { $$ = $1-> appendList( $1->cloneType( $3 ) ); }2664 { $$ = $1->set_last( $1->cloneType( $3 ) ); } 2673 2665 ; 2674 2666 … … 2677 2669 cfa_abstract_declarator_tuple 2678 2670 | cfa_field_abstract_list ',' 2679 { $$ = $1-> appendList( $1->cloneType( 0 ) ); }2671 { $$ = $1->set_last( $1->cloneType( 0 ) ); } 2680 2672 ; 2681 2673 … … 2690 2682 { $$ = $2; } 2691 2683 ; 2684 2685 // *********** 2686 // Enumeration 2687 // *********** 2692 2688 2693 2689 enum_type: … … 2719 2715 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt 2720 2716 { 2721 if ( $3 && ($3->storageClasses.any() || $3->type->qualifiers.val != 0 )) {2717 if ( $3 && ($3->storageClasses.any() || $3->type->qualifiers.val != 0) ) { 2722 2718 SemanticError( yylloc, "syntax error, storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); 2723 2719 } … … 2769 2765 { $$ = DeclarationNode::newEnumInLine( *$2->type->symbolic.name ); } 2770 2766 | enumerator_list ',' visible_hide_opt identifier_or_type_name enumerator_value_opt 2771 { $$ = $1-> appendList( DeclarationNode::newEnumValueGeneric( $4, $5 ) ); }2767 { $$ = $1->set_last( DeclarationNode::newEnumValueGeneric( $4, $5 ) ); } 2772 2768 | enumerator_list ',' INLINE type_name enumerator_value_opt 2773 { $$ = $1-> appendList( DeclarationNode::newEnumValueGeneric( new string("inline"), nullptr ) ); }2769 { $$ = $1->set_last( DeclarationNode::newEnumValueGeneric( new string("inline"), nullptr ) ); } 2774 2770 ; 2775 2771 … … 2789 2785 ; 2790 2786 2791 cfa_parameter_ellipsis_list_opt: // CFA, abstract + real 2792 // empty 2793 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); } 2794 | ELLIPSIS 2795 { $$ = nullptr; } 2796 | cfa_abstract_parameter_list 2797 | cfa_parameter_list 2798 | cfa_parameter_list pop ',' push cfa_abstract_parameter_list 2799 { $$ = $1->appendList( $5 ); } 2800 | cfa_abstract_parameter_list pop ',' push ELLIPSIS 2801 { $$ = $1->addVarArgs(); } 2802 | cfa_parameter_list pop ',' push ELLIPSIS 2803 { $$ = $1->addVarArgs(); } 2804 ; 2805 2806 cfa_parameter_list: // CFA 2807 // To obtain LR(1) between cfa_parameter_list and cfa_abstract_tuple, the last cfa_abstract_parameter_list is 2808 // factored out from cfa_parameter_list, flattening the rules to get lookahead to the ']'. 2809 cfa_parameter_declaration 2810 | cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration 2811 { $$ = $1->appendList( $5 ); } 2812 | cfa_parameter_list pop ',' push cfa_parameter_declaration 2813 { $$ = $1->appendList( $5 ); } 2814 | cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration 2815 { $$ = $1->appendList( $5 )->appendList( $9 ); } 2816 ; 2817 2818 cfa_abstract_parameter_list: // CFA, new & old style abstract 2819 cfa_abstract_parameter_declaration 2820 | cfa_abstract_parameter_list pop ',' push cfa_abstract_parameter_declaration 2821 { $$ = $1->appendList( $5 ); } 2822 ; 2823 2824 parameter_type_list_opt: 2787 // ******************* 2788 // Function parameters 2789 // ******************* 2790 2791 parameter_list_ellipsis_opt: 2825 2792 // empty 2826 2793 { $$ = nullptr; } … … 2833 2800 2834 2801 parameter_list: // abstract + real 2835 abstract_parameter_declaration 2836 | parameter_declaration 2802 parameter_declaration 2803 | abstract_parameter_declaration 2804 | parameter_list ',' parameter_declaration 2805 { $$ = $1->set_last( $3 ); } 2837 2806 | parameter_list ',' abstract_parameter_declaration 2838 { $$ = $1->appendList( $3 ); } 2839 | parameter_list ',' parameter_declaration 2840 { $$ = $1->appendList( $3 ); } 2807 { $$ = $1->set_last( $3 ); } 2808 ; 2809 2810 cfa_parameter_list_ellipsis_opt: // CFA, abstract + real 2811 // empty 2812 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); } 2813 | ELLIPSIS 2814 { $$ = nullptr; } 2815 | cfa_parameter_list 2816 | cfa_abstract_parameter_list 2817 | cfa_parameter_list ',' cfa_abstract_parameter_list 2818 { $$ = $1->set_last( $3 ); } 2819 | cfa_parameter_list ',' ELLIPSIS 2820 { $$ = $1->addVarArgs(); } 2821 | cfa_abstract_parameter_list ',' ELLIPSIS 2822 { $$ = $1->addVarArgs(); } 2823 ; 2824 2825 cfa_parameter_list: // CFA 2826 // To obtain LR(1) between cfa_parameter_list and cfa_abstract_tuple, the last cfa_abstract_parameter_list is 2827 // factored out from cfa_parameter_list, flattening the rules to get lookahead to the ']'. 2828 cfa_parameter_declaration 2829 | cfa_abstract_parameter_list ',' cfa_parameter_declaration 2830 { $$ = $1->set_last( $3 ); } 2831 | cfa_parameter_list ',' cfa_parameter_declaration 2832 { $$ = $1->set_last( $3 ); } 2833 | cfa_parameter_list ',' cfa_abstract_parameter_list ',' cfa_parameter_declaration 2834 { $$ = $1->set_last( $3 )->set_last( $5 ); } 2835 ; 2836 2837 cfa_abstract_parameter_list: // CFA, new & old style abstract 2838 cfa_abstract_parameter_declaration 2839 | cfa_abstract_parameter_list ',' cfa_abstract_parameter_declaration 2840 { $$ = $1->set_last( $3 ); } 2841 2841 ; 2842 2842 2843 2843 // Provides optional identifier names (abstract_declarator/variable_declarator), no initialization, different semantics 2844 2844 // for typedef name by using type_parameter_redeclarator instead of typedef_redeclarator, and function prototypes. 2845 2846 parameter_declaration: 2847 // No SUE declaration in parameter list. 2848 declaration_specifier_nobody identifier_parameter_declarator default_initializer_opt 2849 { $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr ); } 2850 | declaration_specifier_nobody type_parameter_redeclarator default_initializer_opt 2851 { $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr ); } 2852 ; 2853 2854 abstract_parameter_declaration: 2855 declaration_specifier_nobody default_initializer_opt 2856 { $$ = $1->addInitializer( $2 ? new InitializerNode( $2 ) : nullptr ); } 2857 | declaration_specifier_nobody abstract_parameter_declarator default_initializer_opt 2858 { $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr ); } 2859 ; 2845 2860 2846 2861 cfa_parameter_declaration: // CFA, new & old style parameter declaration … … 2866 2881 ; 2867 2882 2868 parameter_declaration:2869 // No SUE declaration in parameter list.2870 declaration_specifier_nobody identifier_parameter_declarator default_initializer_opt2871 { $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr ); }2872 | declaration_specifier_nobody type_parameter_redeclarator default_initializer_opt2873 { $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr ); }2874 ;2875 2876 abstract_parameter_declaration:2877 declaration_specifier_nobody default_initializer_opt2878 { $$ = $1->addInitializer( $2 ? new InitializerNode( $2 ) : nullptr ); }2879 | declaration_specifier_nobody abstract_parameter_declarator default_initializer_opt2880 { $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr ); }2881 ;2882 2883 2883 // ISO/IEC 9899:1999 Section 6.9.1(6) : "An identifier declared as a typedef name shall not be redeclared as a 2884 2884 // parameter." Because the scope of the K&R-style parameter-list sees the typedef first, the following is based only on … … 2889 2889 { $$ = DeclarationNode::newName( $1 ); } 2890 2890 | identifier_list ',' identifier 2891 { $$ = $1-> appendList( DeclarationNode::newName( $3 ) ); }2891 { $$ = $1->set_last( DeclarationNode::newName( $3 ) ); } 2892 2892 ; 2893 2893 … … 2990 2990 type_parameter 2991 2991 | type_parameter_list ',' type_parameter 2992 { $$ = $1-> appendList( $3 ); }2992 { $$ = $1->set_last( $3 ); } 2993 2993 ; 2994 2994 … … 3063 3063 assertion 3064 3064 | assertion_list assertion 3065 { $$ = $1-> appendList( $2 ); }3065 { $$ = $1->set_last( $2 ); } 3066 3066 ; 3067 3067 … … 3091 3091 { $$ = $3->addQualifiers( $1 ); } 3092 3092 | type_declaring_list ',' type_declarator 3093 { $$ = $1-> appendList( $3->copySpecifiers( $1 ) ); }3093 { $$ = $1->set_last( $3->copySpecifiers( $1 ) ); } 3094 3094 ; 3095 3095 … … 3134 3134 trait_declaration 3135 3135 | trait_declaration_list pop push trait_declaration 3136 { $$ = $1-> appendList( $4 ); }3136 { $$ = $1->set_last( $4 ); } 3137 3137 ; 3138 3138 … … 3146 3146 | cfa_function_specifier 3147 3147 | cfa_trait_declaring_list pop ',' push identifier_or_type_name 3148 { $$ = $1-> appendList( $1->cloneType( $5 ) ); }3148 { $$ = $1->set_last( $1->cloneType( $5 ) ); } 3149 3149 ; 3150 3150 … … 3153 3153 { $$ = $2->addType( $1 ); } 3154 3154 | trait_declaring_list pop ',' push declarator 3155 { $$ = $1-> appendList( $1->cloneBaseType( $5 ) ); }3155 { $$ = $1->set_last( $1->cloneBaseType( $5 ) ); } 3156 3156 ; 3157 3157 … … 3161 3161 // empty, input file 3162 3162 | external_definition_list 3163 { parseTree = parseTree ? parseTree-> appendList( $1 ) : $1; }3163 { parseTree = parseTree ? parseTree->set_last( $1 ) : $1; } 3164 3164 ; 3165 3165 … … 3168 3168 { $$ = $2; } 3169 3169 | external_definition_list push external_definition pop 3170 { $$ = $1 ? $1-> appendList( $3 ) : $3; }3170 { $$ = $1 ? $1->set_last( $3 ) : $3; } 3171 3171 ; 3172 3172 … … 3395 3395 ATTRIBUTE '(' '(' attribute_name_list ')' ')' 3396 3396 { $$ = $4; } 3397 | ATTRIBUTE '(' attribute_name_list ')' // CFA 3398 { $$ = $3; } 3399 | ATTR '(' attribute_name_list ')' // CFA 3400 { $$ = $3; } 3397 3401 ; 3398 3402 … … 3499 3503 3500 3504 variable_function: 3501 '(' variable_ptr ')' '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3505 '(' variable_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3502 3506 { $$ = $2->addParamList( $5 ); } 3503 | '(' attribute_list variable_ptr ')' '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3507 | '(' attribute_list variable_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3504 3508 { $$ = $3->addQualifiers( $2 )->addParamList( $6 ); } 3505 3509 | '(' variable_function ')' // redundant parenthesis … … 3522 3526 3523 3527 function_no_ptr: 3524 paren_identifier '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3528 paren_identifier '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3525 3529 { $$ = $1->addParamList( $3 ); } 3526 | '(' function_ptr ')' '(' parameter_ type_list_opt ')'3530 | '(' function_ptr ')' '(' parameter_list_ellipsis_opt ')' 3527 3531 { $$ = $2->addParamList( $5 ); } 3528 | '(' attribute_list function_ptr ')' '(' parameter_ type_list_opt ')'3532 | '(' attribute_list function_ptr ')' '(' parameter_list_ellipsis_opt ')' 3529 3533 { $$ = $3->addQualifiers( $2 )->addParamList( $6 ); } 3530 3534 | '(' function_no_ptr ')' // redundant parenthesis … … 3576 3580 paren_identifier '(' identifier_list ')' // function_declarator handles empty parameter 3577 3581 { $$ = $1->addIdList( $3 ); } 3578 | '(' KR_function_ptr ')' '(' parameter_ type_list_opt ')'3582 | '(' KR_function_ptr ')' '(' parameter_list_ellipsis_opt ')' 3579 3583 { $$ = $2->addParamList( $5 ); } 3580 | '(' attribute_list KR_function_ptr ')' '(' parameter_ type_list_opt ')'3584 | '(' attribute_list KR_function_ptr ')' '(' parameter_list_ellipsis_opt ')' 3581 3585 { $$ = $3->addQualifiers( $2 )->addParamList( $6 ); } 3582 3586 | '(' KR_function_no_ptr ')' // redundant parenthesis … … 3668 3672 3669 3673 variable_type_function: 3670 '(' variable_type_ptr ')' '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3674 '(' variable_type_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3671 3675 { $$ = $2->addParamList( $5 ); } 3672 | '(' attribute_list variable_type_ptr ')' '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3676 | '(' attribute_list variable_type_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3673 3677 { $$ = $3->addQualifiers( $2 )->addParamList( $6 ); } 3674 3678 | '(' variable_type_function ')' // redundant parenthesis … … 3691 3695 3692 3696 function_type_no_ptr: 3693 paren_type '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3697 paren_type '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3694 3698 { $$ = $1->addParamList( $3 ); } 3695 | '(' function_type_ptr ')' '(' parameter_ type_list_opt ')'3699 | '(' function_type_ptr ')' '(' parameter_list_ellipsis_opt ')' 3696 3700 { $$ = $2->addParamList( $5 ); } 3697 | '(' attribute_list function_type_ptr ')' '(' parameter_ type_list_opt ')'3701 | '(' attribute_list function_type_ptr ')' '(' parameter_list_ellipsis_opt ')' 3698 3702 { $$ = $3->addQualifiers( $2 )->addParamList( $6 ); } 3699 3703 | '(' function_type_no_ptr ')' // redundant parenthesis … … 3738 3742 { $$ = $1->addQualifiers( $2 ); } 3739 3743 | '&' MUTEX paren_identifier attribute_list_opt 3740 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( ast::CV::Mutex ), OperKinds::AddressOf ) )->addQualifiers( $4 ); } 3744 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( ast::CV::Mutex ), 3745 OperKinds::AddressOf ) )->addQualifiers( $4 ); } 3741 3746 | identifier_parameter_ptr 3742 3747 | identifier_parameter_array attribute_list_opt … … 3767 3772 3768 3773 identifier_parameter_function: 3769 paren_identifier '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3774 paren_identifier '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3770 3775 { $$ = $1->addParamList( $3 ); } 3771 | '(' identifier_parameter_ptr ')' '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3776 | '(' identifier_parameter_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3772 3777 { $$ = $2->addParamList( $5 ); } 3773 3778 | '(' identifier_parameter_function ')' // redundant parenthesis … … 3788 3793 { $$ = $1->addQualifiers( $2 ); } 3789 3794 | '&' MUTEX typedef_name attribute_list_opt 3790 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( ast::CV::Mutex ), OperKinds::AddressOf ) )->addQualifiers( $4 ); } 3795 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( ast::CV::Mutex ), 3796 OperKinds::AddressOf ) )->addQualifiers( $4 ); } 3791 3797 | type_parameter_ptr 3792 3798 | type_parameter_array attribute_list_opt … … 3820 3826 3821 3827 type_parameter_function: 3822 typedef_name '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3828 typedef_name '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3823 3829 { $$ = $1->addParamList( $3 ); } 3824 | '(' type_parameter_ptr ')' '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3830 | '(' type_parameter_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3825 3831 { $$ = $2->addParamList( $5 ); } 3826 3832 ; … … 3870 3876 3871 3877 abstract_function: 3872 '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3878 '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3873 3879 { $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); } 3874 | '(' abstract_ptr ')' '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)3880 | '(' abstract_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3875 3881 { $$ = $2->addParamList( $5 ); } 3876 3882 | '(' abstract_function ')' // redundant parenthesis … … 3888 3894 { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); } 3889 3895 // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; } 3896 3897 // If needed, the following parses and does not use comma_expression, so the array structure can be built. 3898 // | '[' push assignment_expression pop ',' push array_dimension_list pop ']' // CFA 3899 3890 3900 | '[' push array_type_list pop ']' // CFA 3891 3901 { $$ = DeclarationNode::newArray( $3, nullptr, false ); } 3892 3902 | multi_array_dimension 3893 3903 ; 3904 3905 // array_dimension_list: 3906 // assignment_expression 3907 // | array_dimension_list ',' assignment_expression 3908 // ; 3894 3909 3895 3910 array_type_list: … … 3993 4008 3994 4009 abstract_parameter_function: 3995 '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)4010 '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3996 4011 { $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); } 3997 | '(' abstract_parameter_ptr ')' '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)4012 | '(' abstract_parameter_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 3998 4013 { $$ = $2->addParamList( $5 ); } 3999 4014 | '(' abstract_parameter_function ')' // redundant parenthesis … … 4072 4087 4073 4088 variable_abstract_function: 4074 '(' variable_abstract_ptr ')' '(' parameter_ type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)4089 '(' variable_abstract_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3) 4075 4090 { $$ = $2->addParamList( $5 ); } 4076 4091 | '(' variable_abstract_function ')' // redundant parenthesis … … 4158 4173 // 4159 4174 // cfa_abstract_tuple identifier_or_type_name 4160 // '[' cfa_parameter_list ']' identifier_or_type_name '(' cfa_parameter_ ellipsis_list_opt ')'4175 // '[' cfa_parameter_list ']' identifier_or_type_name '(' cfa_parameter_list_ellipsis_opt ')' 4161 4176 // 4162 4177 // since a function return type can be syntactically identical to a tuple type: … … 4224 4239 4225 4240 cfa_abstract_function: // CFA 4226 // '[' ']' '(' cfa_parameter_ellipsis_list_opt ')'4227 //{ $$ = DeclarationNode::newFunction( nullptr, DeclarationNode::newTuple( nullptr ), $4, nullptr ); }4228 cfa_abstract_tuple '(' push cfa_parameter_ellipsis_list_opt pop ')'4241 '[' ']' '(' cfa_parameter_list_ellipsis_opt ')' 4242 { $$ = DeclarationNode::newFunction( nullptr, DeclarationNode::newTuple( nullptr ), $4, nullptr ); } 4243 | cfa_abstract_tuple '(' push cfa_parameter_list_ellipsis_opt pop ')' 4229 4244 { $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); } 4230 | cfa_function_return '(' push cfa_parameter_ ellipsis_list_opt pop ')'4245 | cfa_function_return '(' push cfa_parameter_list_ellipsis_opt pop ')' 4231 4246 { $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); } 4232 4247 ; -
src/ResolvExpr/Resolver.cc
rbbf2cb1 rf6e8c67 412 412 413 413 void resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd); 414 bool shouldGenCtorInit( const ast::ObjectDecl * ) const; 414 415 415 416 void beginScope() { managedTypes.beginScope(); } … … 581 582 } 582 583 584 bool Resolver::shouldGenCtorInit( ast::ObjectDecl const * decl ) const { 585 // If we shouldn't try to construct it, then don't. 586 if ( !InitTweak::tryConstruct( decl ) ) return false; 587 // Otherwise, if it is a managed type, we may construct it. 588 if ( managedTypes.isManaged( decl ) ) return true; 589 // Skip construction if it is trivial at compile-time. 590 if ( InitTweak::isConstExpr( decl->init ) ) return false; 591 // Skip construction for local declarations. 592 return ( !isInFunction() || decl->storage.is_static ); 593 } 594 583 595 const ast::ObjectDecl * Resolver::previsit( const ast::ObjectDecl * objectDecl ) { 584 596 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], … … 615 627 // this object in visitor pass, thus disabling CtorInit codegen. 616 628 // this happens on aggregate members and function parameters. 617 if ( InitTweak::tryConstruct( mutDecl ) && ( managedTypes.isManaged( mutDecl ) || ((! isInFunction() || mutDecl->storage.is_static ) && ! InitTweak::isConstExpr( mutDecl->init ) )) ) {629 if ( shouldGenCtorInit( mutDecl ) ) { 618 630 // constructed objects cannot be designated 619 631 if ( InitTweak::isDesignated( mutDecl->init ) ) {
Note:
See TracChangeset
for help on using the changeset viewer.