- Timestamp:
- Mar 25, 2024, 7:15:30 PM (9 months ago)
- Branches:
- master
- Children:
- d734fa1
- Parents:
- df78cce (diff), bf050c5 (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:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cpp
rdf78cce r486caad 192 192 } 193 193 194 assert( decl->returns.size() < 2 );195 194 if ( 1 == decl->returns.size() ) { 196 195 ast::ptr<ast::Type> const & type = decl->returns[0]->get_type(); 197 196 output << genTypeNoAttr( type, acc.str(), subOptions ); 198 } else {197 } else if ( 0 == decl->returns.size() ) { 199 198 output << "void " + acc.str(); 199 } else { 200 assertf( !options.genC, "Multi-return should not reach code generation." ); 201 ast::ptr<ast::Type> type = new ast::TupleType( copy( decl->type->returns ) ); 202 output << genTypeNoAttr( type, acc.str(), subOptions ); 200 203 } 201 204 -
src/Parser/DeclarationNode.cc
rdf78cce r486caad 185 185 newnode->type->aggregate.fields = fields; 186 186 newnode->type->aggregate.body = body; 187 newnode->type->aggregate.tagged = false;188 newnode->type->aggregate.parent = nullptr;189 187 return newnode; 190 188 } // DeclarationNode::newAggregate … … 199 197 newnode->type->enumeration.typed = typed; 200 198 newnode->type->enumeration.hiding = hiding; 201 if ( base && base->type ) { 199 if ( base ) { 200 assert( typed ); 201 assert( base->type ); 202 202 newnode->type->base = base->type; 203 base->type = nullptr; 204 delete base; 203 205 } // if 204 206 … … 220 222 221 223 DeclarationNode * DeclarationNode::newEnumValueGeneric( const string * name, InitializerNode * init ) { 222 if ( init ) { 223 if ( init->get_expression() ) { 224 return newEnumConstant( name, init->get_expression() ); 225 } else { 226 DeclarationNode * newnode = newName( name ); 227 newnode->initializer = init; 228 return newnode; 229 } // if 224 if ( nullptr == init ) { 225 return newName( name ); 226 } else if ( init->get_expression() ) { 227 return newEnumConstant( name, init->get_expression() ); 230 228 } else { 231 return newName( name ); 229 DeclarationNode * newnode = newName( name ); 230 newnode->initializer = init; 231 return newnode; 232 232 } // if 233 233 } // DeclarationNode::newEnumValueGeneric … … 502 502 } 503 503 504 // This code handles a special issue with the attribute transparent_union. 505 // 506 // typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union )) 507 // 508 // Here the attribute aligned goes with the typedef_name, so variables declared of this type are 509 // aligned. However, the attribute transparent_union must be moved from the typedef_name to 510 // alias union U. Currently, this is the only know attribute that must be moved from typedef to 511 // alias. 512 static void moveUnionAttribute( DeclarationNode * decl, DeclarationNode * unionDecl ) { 513 assert( decl->type->kind == TypeData::Symbolic ); 514 assert( decl->type->symbolic.isTypedef ); 515 assert( unionDecl->type->kind == TypeData::Aggregate ); 516 517 if ( unionDecl->type->aggregate.kind != ast::AggregateDecl::Union ) return; 518 519 // Ignore the Aggregate_t::attributes. Why did we add that before the rework? 520 for ( auto attr = decl->attributes.begin() ; attr != decl->attributes.end() ; ) { 521 if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) { 522 unionDecl->attributes.emplace_back( attr->release() ); 523 attr = decl->attributes.erase( attr ); 524 } else { 525 ++attr; 526 } 527 } 528 } 529 530 // Helper for addTypedef, handles the case where the typedef wraps an 531 // aggregate declaration (not a type), returns a chain of nodes. 532 static DeclarationNode * addTypedefAggr( 533 DeclarationNode * olddecl, TypeData * newtype ) { 534 TypeData *& oldaggr = olddecl->type->aggInst.aggregate; 535 536 // Handle anonymous aggregates: typedef struct { int i; } foo 537 // Give the typedefed type a consistent name across translation units. 538 if ( oldaggr->aggregate.anon ) { 539 delete oldaggr->aggregate.name; 540 oldaggr->aggregate.name = new string( "__anonymous_" + *olddecl->name ); 541 oldaggr->aggregate.anon = false; 542 oldaggr->qualifiers.reset(); 543 } 544 545 // Replace the wrapped TypeData with a forward declaration. 546 TypeData * newaggr = new TypeData( TypeData::Aggregate ); 547 newaggr->aggregate.kind = oldaggr->aggregate.kind; 548 newaggr->aggregate.name = oldaggr->aggregate.name ? new string( *oldaggr->aggregate.name ) : nullptr; 549 newaggr->aggregate.body = false; 550 newaggr->aggregate.anon = oldaggr->aggregate.anon; 551 swap( newaggr, oldaggr ); 552 553 newtype->base = olddecl->type; 554 olddecl->type = newtype; 555 DeclarationNode * newdecl = new DeclarationNode; 556 newdecl->type = newaggr; 557 newdecl->next = olddecl; 558 559 moveUnionAttribute( olddecl, newdecl ); 560 561 return newdecl; 562 } 563 564 // Helper for addTypedef, handles the case where the typedef wraps an 565 // enumeration declaration (not a type), returns a chain of nodes. 566 static DeclarationNode * addTypedefEnum( 567 DeclarationNode * olddecl, TypeData * newtype ) { 568 TypeData *& oldenum = olddecl->type->aggInst.aggregate; 569 570 // Handle anonymous enumeration: typedef enum { A, B, C } foo 571 // Give the typedefed type a consistent name across translation units. 572 if ( oldenum->enumeration.anon ) { 573 delete oldenum->enumeration.name; 574 oldenum->enumeration.name = new string( "__anonymous_" + *olddecl->name ); 575 oldenum->enumeration.anon = false; 576 oldenum->qualifiers.reset(); 577 } 578 579 // Replace the wrapped TypeData with a forward declaration. 580 TypeData * newenum = new TypeData( TypeData::Enum ); 581 newenum->enumeration.name = oldenum->enumeration.name ? new string( *oldenum->enumeration.name ) : nullptr; 582 newenum->enumeration.body = false; 583 newenum->enumeration.anon = oldenum->enumeration.anon; 584 newenum->enumeration.typed = oldenum->enumeration.typed; 585 newenum->enumeration.hiding = oldenum->enumeration.hiding; 586 swap( newenum, oldenum ); 587 588 newtype->base = olddecl->type; 589 olddecl->type = newtype; 590 DeclarationNode * newdecl = new DeclarationNode; 591 newdecl->type = newenum; 592 newdecl->next = olddecl; 593 594 return newdecl; 595 } 596 597 // Wrap the declaration in a typedef. It actually does that by modifying the 598 // existing declaration, and may split it into two declarations. 599 // This only happens if the wrapped type is actually a declaration of a SUE 600 // type. If it does, the DeclarationNode for the SUE declaration is the node 601 // returned, make sure later transformations are applied to the right node. 504 602 DeclarationNode * DeclarationNode::addTypedef() { 505 603 TypeData * newtype = new TypeData( TypeData::Symbolic ); … … 507 605 newtype->symbolic.isTypedef = true; 508 606 newtype->symbolic.name = name ? new string( *name ) : nullptr; 509 newtype->base = type; 510 type = newtype; 511 return this; 607 // If this typedef is wrapping an aggregate, separate them out. 608 if ( TypeData::AggregateInst == type->kind 609 && TypeData::Aggregate == type->aggInst.aggregate->kind 610 && type->aggInst.aggregate->aggregate.body ) { 611 return addTypedefAggr( this, newtype ); 612 // If this typedef is wrapping an enumeration, separate them out. 613 } else if ( TypeData::AggregateInst == type->kind 614 && TypeData::Enum == type->aggInst.aggregate->kind 615 && type->aggInst.aggregate->enumeration.body ) { 616 return addTypedefEnum( this, newtype ); 617 // There is no internal declaration, just a type. 618 } else { 619 newtype->base = type; 620 type = newtype; 621 return this; 622 } 512 623 } 513 624 … … 711 822 } 712 823 713 // If a typedef wraps an anonymous declaration, name the inner declaration so it has a consistent name across714 // translation units.715 static void nameTypedefedDecl(716 DeclarationNode * innerDecl,717 const DeclarationNode * outerDecl ) {718 TypeData * outer = outerDecl->type;719 assert( outer );720 // First make sure this is a typedef:721 if ( outer->kind != TypeData::Symbolic || !outer->symbolic.isTypedef ) {722 return;723 }724 TypeData * inner = innerDecl->type;725 assert( inner );726 // Always clear any CVs associated with the aggregate:727 inner->qualifiers.reset();728 // Handle anonymous aggregates: typedef struct { int i; } foo729 if ( inner->kind == TypeData::Aggregate && inner->aggregate.anon ) {730 delete inner->aggregate.name;731 inner->aggregate.name = new string( "__anonymous_" + *outerDecl->name );732 inner->aggregate.anon = false;733 assert( outer->base );734 delete outer->base->aggInst.aggregate->aggregate.name;735 outer->base->aggInst.aggregate->aggregate.name = new string( "__anonymous_" + *outerDecl->name );736 outer->base->aggInst.aggregate->aggregate.anon = false;737 outer->base->aggInst.aggregate->qualifiers.reset();738 // Handle anonymous enumeration: typedef enum { A, B, C } foo739 } else if ( inner->kind == TypeData::Enum && inner->enumeration.anon ) {740 delete inner->enumeration.name;741 inner->enumeration.name = new string( "__anonymous_" + *outerDecl->name );742 inner->enumeration.anon = false;743 assert( outer->base );744 delete outer->base->aggInst.aggregate->enumeration.name;745 outer->base->aggInst.aggregate->enumeration.name = new string( "__anonymous_" + *outerDecl->name );746 outer->base->aggInst.aggregate->enumeration.anon = false;747 // No qualifiers.reset() here.748 }749 }750 751 // This code handles a special issue with the attribute transparent_union.752 //753 // typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union ))754 //755 // Here the attribute aligned goes with the typedef_name, so variables declared of this type are756 // aligned. However, the attribute transparent_union must be moved from the typedef_name to757 // alias union U. Currently, this is the only know attribute that must be moved from typedef to758 // alias.759 static void moveUnionAttribute( ast::Decl * decl, ast::UnionDecl * unionDecl ) {760 if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) {761 // Is the typedef alias a union aggregate?762 if ( nullptr == unionDecl ) return;763 764 // If typedef is an alias for a union, then its alias type was hoisted above and remembered.765 if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) {766 auto instType = ast::mutate( unionInstType );767 // Remove all transparent_union attributes from typedef and move to alias union.768 for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) {769 assert( *attr );770 if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) {771 unionDecl->attributes.emplace_back( attr->release() );772 attr = instType->attributes.erase( attr );773 } else {774 attr++;775 }776 }777 typedefDecl->base = instType;778 }779 }780 }781 782 824 // Get the non-anonymous name of the instance type of the declaration, 783 825 // if one exists. … … 800 842 try { 801 843 bool extracted_named = false; 802 ast::UnionDecl * unionDecl = nullptr;803 844 804 845 if ( DeclarationNode * extr = cur->extractAggregate() ) { 805 846 assert( cur->type ); 806 nameTypedefedDecl( extr, cur );807 847 808 848 if ( ast::Decl * decl = extr->build() ) { 809 // Remember the declaration if it is a union aggregate ?810 unionDecl = dynamic_cast<ast::UnionDecl *>( decl );811 812 849 *out++ = decl; 813 850 … … 828 865 829 866 if ( ast::Decl * decl = cur->build() ) { 830 moveUnionAttribute( decl, unionDecl );831 832 867 if ( "" == decl->name && !cur->get_inLine() ) { 833 868 // Don't include anonymous declaration for named aggregates, -
src/Parser/TypeData.cc
rdf78cce r486caad 88 88 aggregate.fields = nullptr; 89 89 aggregate.body = false; 90 aggregate.tagged = false;91 aggregate.parent = nullptr;92 90 aggregate.anon = false; 93 91 break; … … 221 219 newtype->aggregate.kind = aggregate.kind; 222 220 newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr; 223 newtype->aggregate.parent = aggregate.parent ? new string( *aggregate.parent ) : nullptr;224 221 newtype->aggregate.params = maybeCopy( aggregate.params ); 225 222 newtype->aggregate.actuals = maybeCopy( aggregate.actuals ); … … 228 225 newtype->aggregate.body = aggregate.body; 229 226 newtype->aggregate.anon = aggregate.anon; 230 newtype->aggregate.tagged = aggregate.tagged;231 227 break; 232 228 case AggregateInst: -
src/Parser/TypeData.h
rdf78cce r486caad 48 48 ast::AggregateDecl::Aggregate kind; 49 49 const std::string * name = nullptr; 50 const std::string * parent = nullptr;51 50 DeclarationNode * params = nullptr; 52 51 ExpressionNode * actuals = nullptr; // holds actual parameters later applied to AggInst … … 55 54 bool body; 56 55 bool anon; 57 bool tagged;58 56 }; 59 57 -
src/Parser/parser.yy
rdf78cce r486caad 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 11 18:30:03 202413 // Update Count : 6 58912 // Last Modified On : Sat Mar 16 18:19:23 2024 13 // Update Count : 6617 14 14 // 15 15 … … 485 485 %type<decl> elaborated_type elaborated_type_nobody 486 486 487 %type<decl> enumerator_list enum_type enum_type_nobody 487 %type<decl> enumerator_list enum_type enum_type_nobody enumerator_type 488 488 %type<init> enumerator_value_opt 489 489 … … 2742 2742 2743 2743 enum_type: 2744 ENUM attribute_list_opt '{' enumerator_list comma_opt '}' 2745 { $$ = DeclarationNode::newEnum( nullptr, $4, true, false )->addQualifiers( $2 ); } 2746 | ENUM attribute_list_opt '!' '{' enumerator_list comma_opt '}' // invalid syntax rule 2747 { SemanticError( yylloc, "syntax error, hiding ('!') the enumerator names of an anonymous enumeration means the names are inaccessible." ); $$ = nullptr; } 2744 // anonymous, no type name 2745 ENUM attribute_list_opt hide_opt '{' enumerator_list comma_opt '}' 2746 { 2747 if ( $3 == EnumHiding::Hide ) { 2748 SemanticError( yylloc, "syntax error, hiding ('!') the enumerator names of an anonymous enumeration means the names are inaccessible." ); $$ = nullptr; 2749 } // if 2750 $$ = DeclarationNode::newEnum( nullptr, $5, true, false )->addQualifiers( $2 ); 2751 } 2752 | ENUM enumerator_type attribute_list_opt hide_opt '{' enumerator_list comma_opt '}' 2753 { 2754 if ( $2 && ($2->storageClasses.val != 0 || $2->type->qualifiers.any()) ) { 2755 SemanticError( yylloc, "syntax error, storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); 2756 } 2757 if ( $4 == EnumHiding::Hide ) { 2758 SemanticError( yylloc, "syntax error, hiding ('!') the enumerator names of an anonymous enumeration means the names are inaccessible." ); $$ = nullptr; 2759 } // if 2760 $$ = DeclarationNode::newEnum( nullptr, $6, true, true, $2 )->addQualifiers( $3 ); 2761 } 2762 2763 // named type 2748 2764 | ENUM attribute_list_opt identifier 2749 2765 { typedefTable.makeTypedef( *$3, "enum_type 1" ); } … … 2752 2768 | ENUM attribute_list_opt typedef_name hide_opt '{' enumerator_list comma_opt '}' // unqualified type name 2753 2769 { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); } 2754 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'2755 { 2756 if ( $ 3->storageClasses.val != 0 || $3->type->qualifiers.any() ) {2770 | ENUM enumerator_type attribute_list_opt identifier attribute_list_opt 2771 { 2772 if ( $2 && ($2->storageClasses.any() || $2->type->qualifiers.val != 0) ) { 2757 2773 SemanticError( yylloc, "syntax error, storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); 2758 2774 } 2759 $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 ); 2760 } 2761 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '!' '{' enumerator_list comma_opt '}' // unqualified type name 2762 { SemanticError( yylloc, "syntax error, hiding ('!') the enumerator names of an anonymous enumeration means the names are inaccessible." ); $$ = nullptr; } 2763 | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2764 { 2765 $$ = DeclarationNode::newEnum( nullptr, $6, true, true )->addQualifiers( $4 ); 2766 } 2767 | ENUM '(' ')' attribute_list_opt '!' '{' enumerator_list comma_opt '}' // invalid syntax rule 2768 { SemanticError( yylloc, "syntax error, hiding ('!') the enumerator names of an anonymous enumeration means the names are inaccessible." ); $$ = nullptr; } 2769 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt 2770 { 2771 if ( $3 && ($3->storageClasses.any() || $3->type->qualifiers.val != 0) ) { 2772 SemanticError( yylloc, "syntax error, storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); 2773 } 2774 typedefTable.makeTypedef( *$6, "enum_type 2" ); 2775 typedefTable.makeTypedef( *$4, "enum_type 2" ); 2775 2776 } 2776 2777 hide_opt '{' enumerator_list comma_opt '}' 2777 { 2778 $$ = DeclarationNode::newEnum( $6, $11, true, true, $3, $9 )->addQualifiers( $5 )->addQualifiers( $7 ); 2779 } 2780 | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt hide_opt '{' enumerator_list comma_opt '}' 2781 { 2782 $$ = DeclarationNode::newEnum( $5, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 ); 2783 } 2784 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt hide_opt '{' enumerator_list comma_opt '}' 2785 { 2786 $$ = DeclarationNode::newEnum( $6->name, $10, true, true, $3, $8 )->addQualifiers( $5 )->addQualifiers( $7 ); 2787 } 2788 | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt hide_opt '{' enumerator_list comma_opt '}' 2789 { 2790 $$ = DeclarationNode::newEnum( $5->name, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 ); 2791 } 2778 { $$ = DeclarationNode::newEnum( $4, $9, true, true, $2, $7 )->addQualifiers( $3 )->addQualifiers( $5 ); } 2779 | ENUM enumerator_type attribute_list_opt typedef_name attribute_list_opt hide_opt '{' enumerator_list comma_opt '}' 2780 { $$ = DeclarationNode::newEnum( $4->name, $8, true, true, $2, $6 )->addQualifiers( $3 )->addQualifiers( $5 ); } 2781 2782 // forward declaration 2792 2783 | enum_type_nobody 2784 ; 2785 2786 enumerator_type: 2787 '(' ')' // pure enumeration 2788 { $$ = nullptr; } 2789 | '(' cfa_abstract_parameter_declaration ')' // typed enumeration 2790 { $$ = $2; } 2793 2791 ; 2794 2792 -
src/main.cc
rdf78cce r486caad 101 101 } 102 102 103 // Helpers for checkInvariant:104 void checkInvariants( std::list< Declaration * > & ) {}105 using ast::checkInvariants;106 107 103 #define PASS( name, pass, unit, ... ) \ 108 104 if ( errorp ) { cerr << name << endl; } \ … … 112 108 Stats::Time::StopBlock(); \ 113 109 if ( invariant ) { \ 114 checkInvariants(unit);\110 ast::checkInvariants(unit); \ 115 111 } 116 112
Note: See TracChangeset
for help on using the changeset viewer.