Changes in src/Parser/DeclarationNode.cc [bf050c5:a3525c4]
- File:
-
- 1 edited
-
src/Parser/DeclarationNode.cc (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
rbf050c5 ra3525c4 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; 187 189 return newnode; 188 190 } // DeclarationNode::newAggregate … … 197 199 newnode->type->enumeration.typed = typed; 198 200 newnode->type->enumeration.hiding = hiding; 199 if ( base ) { 200 assert( typed ); 201 assert( base->type ); 201 if ( base && base->type ) { 202 202 newnode->type->base = base->type; 203 base->type = nullptr;204 delete base;205 203 } // if 206 204 … … 222 220 223 221 DeclarationNode * DeclarationNode::newEnumValueGeneric( const string * name, InitializerNode * init ) { 224 if ( nullptr == 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 230 } else { 225 231 return newName( name ); 226 } else if ( init->get_expression() ) {227 return newEnumConstant( name, init->get_expression() );228 } else {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 are509 // aligned. However, the attribute transparent_union must be moved from the typedef_name to510 // alias union U. Currently, this is the only know attribute that must be moved from typedef to511 // 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 an531 // 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; } foo537 // 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 an565 // 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 } foo571 // 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 the598 // existing declaration, and may split it into two declarations.599 // This only happens if the wrapped type is actually a declaration of a SUE600 // type. If it does, the DeclarationNode for the SUE declaration is the node601 // returned, make sure later transformations are applied to the right node.602 504 DeclarationNode * DeclarationNode::addTypedef() { 603 505 TypeData * newtype = new TypeData( TypeData::Symbolic ); … … 605 507 newtype->symbolic.isTypedef = true; 606 508 newtype->symbolic.name = name ? new string( *name ) : nullptr; 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 } 509 newtype->base = type; 510 type = newtype; 511 return this; 623 512 } 624 513 … … 822 711 } 823 712 713 // If a typedef wraps an anonymous declaration, name the inner declaration so it has a consistent name across 714 // 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; } foo 729 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 } foo 739 } 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 are 756 // aligned. However, the attribute transparent_union must be moved from the typedef_name to 757 // alias union U. Currently, this is the only know attribute that must be moved from typedef to 758 // 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 824 782 // Get the non-anonymous name of the instance type of the declaration, 825 783 // if one exists. … … 842 800 try { 843 801 bool extracted_named = false; 802 ast::UnionDecl * unionDecl = nullptr; 844 803 845 804 if ( DeclarationNode * extr = cur->extractAggregate() ) { 846 805 assert( cur->type ); 806 nameTypedefedDecl( extr, cur ); 847 807 848 808 if ( ast::Decl * decl = extr->build() ) { 809 // Remember the declaration if it is a union aggregate ? 810 unionDecl = dynamic_cast<ast::UnionDecl *>( decl ); 811 849 812 *out++ = decl; 850 813 … … 865 828 866 829 if ( ast::Decl * decl = cur->build() ) { 830 moveUnionAttribute( decl, unionDecl ); 831 867 832 if ( "" == decl->name && !cur->get_inLine() ) { 868 833 // Don't include anonymous declaration for named aggregates,
Note:
See TracChangeset
for help on using the changeset viewer.