Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r284da8c r3d7e53b  
    254254} // DeclarationNode::newFromTypedef
    255255
     256DeclarationNode * DeclarationNode::newFromGlobalScope() {
     257        DeclarationNode * newnode = new DeclarationNode;
     258        newnode->type = new TypeData( TypeData::GlobalScope );
     259        return newnode;
     260}
     261
     262DeclarationNode * DeclarationNode::newQualifiedType( DeclarationNode * parent, DeclarationNode * child) {
     263        DeclarationNode * newnode = new DeclarationNode;
     264        newnode->type = new TypeData( TypeData::Qualified );
     265        newnode->type->qualified.parent = parent->type;
     266        newnode->type->qualified.child = child->type;
     267        parent->type = nullptr;
     268        child->type = nullptr;
     269        delete parent;
     270        delete child;
     271        return newnode;
     272}
     273
    256274DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
    257         assert( name );
    258275        DeclarationNode * newnode = new DeclarationNode;
    259276        newnode->type = new TypeData( TypeData::Aggregate );
    260277        newnode->type->aggregate.kind = kind;
    261         newnode->type->aggregate.name = name;
     278        newnode->type->aggregate.name =  name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
    262279        newnode->type->aggregate.actuals = actuals;
    263280        newnode->type->aggregate.fields = fields;
     
    265282        newnode->type->aggregate.tagged = false;
    266283        newnode->type->aggregate.parent = nullptr;
     284        newnode->type->aggregate.anon = name == nullptr;
    267285        return newnode;
    268286} // DeclarationNode::newAggregate
    269287
    270288DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body ) {
    271         assert( name );
    272289        DeclarationNode * newnode = new DeclarationNode;
    273290        newnode->type = new TypeData( TypeData::Enum );
    274         newnode->type->enumeration.name = name;
     291        newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
    275292        newnode->type->enumeration.constants = constants;
    276293        newnode->type->enumeration.body = body;
     294        newnode->type->enumeration.anon = name == nullptr;
    277295        return newnode;
    278296} // DeclarationNode::newEnum
     
    953971        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    954972                try {
     973                        bool extracted = false;
     974                        bool anon = false;
    955975                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
    956976                                // handle the case where a structure declaration is contained within an object or type declaration
    957977                                Declaration * decl = extr->build();
    958978                                if ( decl ) {
     979                                        // hoist the structure declaration
    959980                                        decl->location = cur->location;
    960981                                        * 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                                        }
    961992                                } // if
    962993                                delete extr;
     
    965996                        Declaration * decl = cur->build();
    966997                        if ( decl ) {
    967                                 decl->location = cur->location;
    968                                 * 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                                }
    9691008                        } // if
    9701009                } catch( SemanticErrorException &e ) {
     
    9781017} // buildList
    9791018
     1019// currently only builds assertions, function parameters, and return values
    9801020void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList ) {
    9811021        SemanticErrorException errors;
     
    9851025                try {
    9861026                        Declaration * decl = cur->build();
    987                         if ( decl ) {
    988                                 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    989                                         dwt->location = cur->location;
    990                                         * out++ = dwt;
    991                                 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
    992                                         StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
    993                                         auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    994                                         obj->location = cur->location;
    995                                         * out++ = obj;
    996                                         delete agg;
    997                                 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
    998                                         UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
    999                                         auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1000                                         obj->location = cur->location;
    1001                                         * out++ = obj;
    1002                                 } // if
     1027                        assert( decl );
     1028                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     1029                                dwt->location = cur->location;
     1030                                * out++ = dwt;
     1031                        } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
     1032                                // e.g., int foo(struct S) {}
     1033                                StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name );
     1034                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
     1035                                obj->location = cur->location;
     1036                                * out++ = obj;
     1037                                delete agg;
     1038                        } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
     1039                                // e.g., int foo(union U) {}
     1040                                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 );
     1047                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
     1048                                obj->location = cur->location;
     1049                                * out++ = obj;
    10031050                        } // if
    10041051                } catch( SemanticErrorException &e ) {
Note: See TracChangeset for help on using the changeset viewer.