Ignore:
Timestamp:
Jul 10, 2018, 11:09:19 AM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
Children:
5cacf74
Parents:
aeec6b7
Message:

Add anon flag to TypeData? and remove anonymous members for named aggregates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    raeec6b7 r3d7e53b  
    273273
    274274DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
    275         assert( name );
    276275        DeclarationNode * newnode = new DeclarationNode;
    277276        newnode->type = new TypeData( TypeData::Aggregate );
    278277        newnode->type->aggregate.kind = kind;
    279         newnode->type->aggregate.name = name;
     278        newnode->type->aggregate.name =  name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
    280279        newnode->type->aggregate.actuals = actuals;
    281280        newnode->type->aggregate.fields = fields;
     
    283282        newnode->type->aggregate.tagged = false;
    284283        newnode->type->aggregate.parent = nullptr;
     284        newnode->type->aggregate.anon = name == nullptr;
    285285        return newnode;
    286286} // DeclarationNode::newAggregate
    287287
    288288DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body ) {
    289         assert( name );
    290289        DeclarationNode * newnode = new DeclarationNode;
    291290        newnode->type = new TypeData( TypeData::Enum );
    292         newnode->type->enumeration.name = name;
     291        newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
    293292        newnode->type->enumeration.constants = constants;
    294293        newnode->type->enumeration.body = body;
     294        newnode->type->enumeration.anon = name == nullptr;
    295295        return newnode;
    296296} // DeclarationNode::newEnum
     
    971971        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    972972                try {
     973                        bool extracted = false;
     974                        bool anon = false;
    973975                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
    974976                                // handle the case where a structure declaration is contained within an object or type declaration
    975977                                Declaration * decl = extr->build();
    976978                                if ( decl ) {
     979                                        // hoist the structure declaration
    977980                                        decl->location = cur->location;
    978981                                        * out++ = decl;
     982
     983                                        // need to remember the cases where a declaration contains an anonymous aggregate definition
     984                                        extracted = true;
     985                                        assert( extr->type );
     986                                        if ( extr->type->kind == TypeData::Aggregate ) {
     987                                                anon = extr->type->aggregate.anon;
     988                                        } else if ( extr->type->kind == TypeData::Enum ) {
     989                                                // xxx - is it useful to have an implicit anonymous enum member?
     990                                                anon = extr->type->enumeration.anon;
     991                                        }
    979992                                } // if
    980993                                delete extr;
     
    983996                        Declaration * decl = cur->build();
    984997                        if ( decl ) {
    985                                 decl->location = cur->location;
    986                                 * out++ = decl;
     998                                // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.:
     999                                // struct S {
     1000                                //   struct T { int x; }; // no anonymous member
     1001                                //   struct { int y; };   // anonymous member
     1002                                //   struct T;            // anonymous member
     1003                                // };
     1004                                if ( ! (extracted && decl->name == "" && ! anon) ) {
     1005                                        decl->location = cur->location;
     1006                                        * out++ = decl;
     1007                                }
    9871008                        } // if
    9881009                } catch( SemanticErrorException &e ) {
     
    9961017} // buildList
    9971018
     1019// currently only builds assertions, function parameters, and return values
    9981020void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList ) {
    9991021        SemanticErrorException errors;
     
    10081030                                * out++ = dwt;
    10091031                        } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
    1010                                 // xxx - this might be where anonymous struct members are added - should be conditional on struct name
     1032                                // e.g., int foo(struct S) {}
    10111033                                StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name );
    10121034                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
     
    10151037                                delete agg;
    10161038                        } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
     1039                                // e.g., int foo(union U) {}
    10171040                                UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name );
     1041                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
     1042                                obj->location = cur->location;
     1043                                * out++ = obj;
     1044                        } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) {
     1045                                // e.g., int foo(enum E) {}
     1046                                EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name );
    10181047                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    10191048                                obj->location = cur->location;
Note: See TracChangeset for help on using the changeset viewer.