Changeset 67467a3 for src/Parser


Ignore:
Timestamp:
Mar 26, 2024, 3:17:51 PM (5 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
544b799
Parents:
84886499
Message:

Fused TypeData::Enum and TypeData::Aggregate, an enumeration is a kind of aggregate after all. There will always be some unused fields in Aggregate_t (but less in TypeData? overall) but the code is almost always simpler.

Location:
src/Parser
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r84886499 r67467a3  
    189189
    190190DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base, EnumHiding hiding ) {
    191         DeclarationNode * newnode = new DeclarationNode;
    192         newnode->type = new TypeData( TypeData::Enum );
    193         newnode->type->enumeration.anon = name == nullptr;
    194         newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
    195         newnode->type->enumeration.constants = constants;
    196         newnode->type->enumeration.body = body;
    197         newnode->type->enumeration.typed = typed;
    198         newnode->type->enumeration.hiding = hiding;
     191        DeclarationNode * newnode = newAggregate( ast::AggregateDecl::Enum, name, nullptr, constants, body );
     192        newnode->type->aggregate.typed = typed;
     193        newnode->type->aggregate.hiding = hiding;
    199194        if ( base ) {
    200195                assert( typed );
     
    549544        newaggr->aggregate.body = false;
    550545        newaggr->aggregate.anon = oldaggr->aggregate.anon;
     546        newaggr->aggregate.typed = oldaggr->aggregate.typed;
     547        newaggr->aggregate.hiding = oldaggr->aggregate.hiding;
    551548        swap( newaggr, oldaggr );
    552549
     
    558555
    559556        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;
    593557
    594558        return newdecl;
     
    610574                        && type->aggInst.aggregate->aggregate.body ) {
    611575                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 );
    617576        // There is no internal declaration, just a type.
    618577        } else {
     
    854813                                                // typedef struct { int A } B is the only case?
    855814                                                extracted_named = ! extr->type->aggregate.anon;
    856                                         } else if ( extr->type->kind == TypeData::Enum ) {
    857                                                 // typedef enum { A } B is the only case?
    858                                                 extracted_named = ! extr->type->enumeration.anon;
    859815                                        } else {
    860816                                                extracted_named = true;
     
    10631019
    10641020        switch ( type->kind ) {
    1065         case TypeData::Enum:
    10661021        case TypeData::Aggregate: {
    10671022                ast::BaseInstType * ret =
  • src/Parser/TypeData.cc

    r84886499 r67467a3  
    7575                function.withExprs = nullptr;
    7676                break;
    77         case Enum:
    78                 enumeration.name = nullptr;
    79                 enumeration.constants = nullptr;
    80                 enumeration.body = false;
    81                 enumeration.anon = false;
    82                 break;
    8377        case Aggregate:
    8478                aggregate.kind = ast::AggregateDecl::NoAggregate;
     
    8983                aggregate.body = false;
    9084                aggregate.anon = false;
     85                aggregate.typed = false;
     86                aggregate.hiding = EnumHiding::Visible;
    9187                break;
    9288        case AggregateInst:
     
    153149                delete aggInst.aggregate;
    154150                delete aggInst.params;
    155                 break;
    156         case Enum:
    157                 delete enumeration.name;
    158                 delete enumeration.constants;
    159151                break;
    160152        case Symbolic:
     
    231223                newtype->aggInst.hoistType = aggInst.hoistType;
    232224                break;
    233         case Enum:
    234                 newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr;
    235                 newtype->enumeration.constants = maybeCopy( enumeration.constants );
    236                 newtype->enumeration.body = enumeration.body;
    237                 newtype->enumeration.anon = enumeration.anon;
    238                 break;
    239225        case Symbolic:
    240226        case SymbolicInst:
     
    375361                        os << string( indent + 2, ' ' ) << "with parameters" << endl;
    376362                        aggInst.params->printList( os, indent + 2 );
    377                 } // if
    378                 break;
    379         case Enum:
    380                 os << "enumeration " << *enumeration.name << endl;;
    381                 if ( enumeration.constants ) {
    382                         os << "with constants" << endl;
    383                         enumeration.constants->printList( os, indent + 2 );
    384                 } // if
    385                 if ( enumeration.body ) {
    386                         os << string( indent + 2, ' ' ) << "with body" << endl;
    387                 } // if
    388                 if ( base ) {
    389                         os << "for ";
    390                         base->print( os, indent + 2 );
    391363                } // if
    392364                break;
     
    483455        case Aggregate:
    484456                return aggregate.name;
    485         case Enum:
    486                 return enumeration.name;
    487457        case Symbolic:
    488458        case SymbolicInst:
     
    673643                switch ( src->kind ) {
    674644                case TypeData::Aggregate:
    675                 case TypeData::Enum:
    676645                        dst->base = new TypeData( TypeData::AggregateInst );
    677646                        dst->base->aggInst.aggregate = src;
     
    701670                return rtype;
    702671        } else {
    703                 if ( ltype->kind == TypeData::Aggregate || ltype->kind == TypeData::Enum ) {
     672                if ( ltype->kind == TypeData::Aggregate ) {
    704673                        // Hide type information aggregate instances.
    705674                        rtype = new TypeData( TypeData::AggregateInst );
    706675                        rtype->aggInst.aggregate = ltype;
    707676                        rtype->aggInst.aggregate->aggregate.attributes.swap( attributes ); // change ownership
    708                         if ( ltype->kind == TypeData::Aggregate ) {
    709                                 rtype->aggInst.hoistType = ltype->aggregate.body;
    710                                 rtype->aggInst.params = maybeCopy( ltype->aggregate.actuals );
    711                         } else {
    712                                 rtype->aggInst.hoistType = ltype->enumeration.body;
    713                         } // if
     677                        rtype->aggInst.hoistType = ltype->aggregate.body;
     678                        rtype->aggInst.params = maybeCopy( ltype->aggregate.actuals );
    714679                        rtype->qualifiers |= ltype->qualifiers;
    715680                } else {
     
    730695        if ( newType->kind == TypeData::AggregateInst ) {
    731696                // don't duplicate members
    732                 if ( newType->aggInst.aggregate->kind == TypeData::Enum ) {
    733                         delete newType->aggInst.aggregate->enumeration.constants;
    734                         newType->aggInst.aggregate->enumeration.constants = nullptr;
    735                         newType->aggInst.aggregate->enumeration.body = false;
    736                 } else {
    737                         assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
    738                         delete newType->aggInst.aggregate->aggregate.fields;
    739                         newType->aggInst.aggregate->aggregate.fields = nullptr;
    740                         newType->aggInst.aggregate->aggregate.body = false;
    741                 } // if
     697                assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
     698                delete newType->aggInst.aggregate->aggregate.fields;
     699                newType->aggInst.aggregate->aggregate.fields = nullptr;
     700                newType->aggInst.aggregate->aggregate.body = false;
    742701                // don't hoist twice
    743702                newType->aggInst.hoistType = false;
     
    755714TypeData * makeNewBase( TypeData * type ) {
    756715        switch ( type->kind ) {
    757         case TypeData::Aggregate:
    758         case TypeData::Enum: {
     716        case TypeData::Aggregate: {
    759717                TypeData * out = new TypeData( TypeData::AggregateInst );
    760718                out->aggInst.aggregate = type;
     
    11231081                );
    11241082        case TypeData::Symbolic:
    1125         case TypeData::Enum:
    11261083        case TypeData::Aggregate:
    11271084                assert( false );
     
    11381095        case TypeData::Aggregate:
    11391096                if ( ! toplevel && td->aggregate.body ) {
    1140                         ret = td->clone();
    1141                 } // if
    1142                 break;
    1143         case TypeData::Enum:
    1144                 if ( ! toplevel && td->enumeration.body ) {
    11451097                        ret = td->clone();
    11461098                } // if
     
    13451297                buildForall( td->aggregate.params, at->params );
    13461298                break;
     1299        case ast::AggregateDecl::Enum:
     1300                return buildEnum( td, std::move( attributes ), linkage );
    13471301        case ast::AggregateDecl::Trait:
    13481302                at = new ast::TraitDecl( td->location,
     
    13691323                ast::Linkage::Spec linkage ) {
    13701324        switch ( td->kind ) {
    1371         case TypeData::Enum:
    1372                 if ( td->enumeration.body ) {
    1373                         ast::EnumDecl * typedecl =
    1374                                 buildEnum( td, std::move( attributes ), linkage );
    1375                         return new ast::EnumInstType(
    1376                                 typedecl,
    1377                                 buildQualifiers( td )
    1378                         );
    1379                 } else {
    1380                         return new ast::EnumInstType(
    1381                                 *td->enumeration.name,
    1382                                 buildQualifiers( td )
    1383                         );
    1384                 } // if
    1385                 break;
    13861325        case TypeData::Aggregate:
    13871326                if ( td->aggregate.body ) {
     
    14001339                                return new ast::UnionInstType(
    14011340                                        strict_dynamic_cast<ast::UnionDecl *>( typedecl ),
     1341                                        buildQualifiers( td )
     1342                                );
     1343                        case ast::AggregateDecl::Enum:
     1344                                return new ast::EnumInstType(
     1345                                        strict_dynamic_cast<ast::EnumDecl *>( typedecl ),
    14021346                                        buildQualifiers( td )
    14031347                                );
     
    14231367                                        buildQualifiers( td )
    14241368                                );
     1369                        case ast::AggregateDecl::Enum:
     1370                                return new ast::EnumInstType(
     1371                                        *td->aggregate.name,
     1372                                        buildQualifiers( td )
     1373                                );
    14251374                        case ast::AggregateDecl::Trait:
    14261375                                return new ast::TraitInstType(
     
    14471396        TypeData * type = td->aggInst.aggregate;
    14481397        switch ( type->kind ) {
    1449         case TypeData::Enum:
    1450                 return new ast::EnumInstType(
    1451                         *type->enumeration.name,
    1452                         buildQualifiers( type )
    1453                 );
    14541398        case TypeData::Aggregate:
    14551399                switch ( type->aggregate.kind ) {
     
    14651409                case ast::AggregateDecl::Union:
    14661410                        ret = new ast::UnionInstType(
     1411                                *type->aggregate.name,
     1412                                buildQualifiers( type )
     1413                        );
     1414                        break;
     1415                case ast::AggregateDecl::Enum:
     1416                        ret = new ast::EnumInstType(
    14671417                                *type->aggregate.name,
    14681418                                buildQualifiers( type )
     
    15261476                std::vector<ast::ptr<ast::Attribute>> && attributes,
    15271477                ast::Linkage::Spec linkage ) {
    1528         assert( td->kind == TypeData::Enum );
     1478        assert( td->kind == TypeData::Aggregate );
     1479        assert( td->aggregate.kind == ast::AggregateDecl::Enum );
    15291480        ast::Type * baseType = td->base ? typebuild(td->base) : nullptr;
    15301481        ast::EnumDecl * ret = new ast::EnumDecl(
    15311482                td->location,
    1532                 *td->enumeration.name,
    1533                 td->enumeration.typed,
     1483                *td->aggregate.name,
     1484                td->aggregate.typed,
    15341485                std::move( attributes ),
    15351486                linkage,
    15361487                baseType
    15371488        );
    1538         buildList( td->enumeration.constants, ret->members );
     1489        buildList( td->aggregate.fields, ret->members );
    15391490        auto members = ret->members.begin();
    1540         ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
    1541         for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = cur->next, ++members ) {
     1491        ret->hide = td->aggregate.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
     1492        for ( const DeclarationNode * cur = td->aggregate.fields ; cur != nullptr ; cur = cur->next, ++members ) {
    15421493                if ( cur->enumInLine ) {
    15431494                        // Do Nothing
     
    15601511                // if
    15611512        } // for
    1562         ret->body = td->enumeration.body;
     1513        ret->body = td->aggregate.body;
    15631514        return ret;
    15641515} // buildEnum
     
    17041655        } else if ( td->kind == TypeData::Aggregate ) {
    17051656                return buildAggregate( td, std::move( attributes ), linkage );
    1706         } else if ( td->kind == TypeData::Enum ) {
    1707                 return buildEnum( td, std::move( attributes ), linkage );
    17081657        } else if ( td->kind == TypeData::Symbolic ) {
    17091658                return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
  • src/Parser/TypeData.h

    r84886499 r67467a3  
    4242        static const char * builtinTypeNames[];
    4343
    44         enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
     44        enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, EnumConstant, Symbolic,
    4545                                SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };
    4646
     
    4848                ast::AggregateDecl::Aggregate kind;
    4949                const std::string * name = nullptr;
     50                // Polymorphics parameters. (Polymorphic types only.)
    5051                DeclarationNode * params = nullptr;
    51                 ExpressionNode * actuals = nullptr;                             // holds actual parameters later applied to AggInst
     52                // Arguments later applied to AggInst. (Polymorphic types only.)
     53                ExpressionNode * actuals = nullptr;
     54                // Only set if body is true. (Constants for enumerations.)
    5255                DeclarationNode * fields = nullptr;
    5356                std::vector<ast::ptr<ast::Attribute>> attributes;
     57                // Is this a declaration with a body (may have fields)?
    5458                bool body;
     59                // Is this type anonymous? (Name can still be set to generated name.)
    5560                bool anon;
     61                // Is this a typed enumeration? Type may be stored in base.
     62                bool typed;
     63                EnumHiding hiding;
    5664        };
    5765
     
    6674                bool isVarLen;
    6775                bool isStatic;
    68         };
    69 
    70         struct Enumeration_t {
    71                 const std::string * name = nullptr;
    72                 DeclarationNode * constants = nullptr;
    73                 bool body;
    74                 bool anon;
    75                 bool typed;
    76                 EnumHiding hiding;
    7776        };
    7877
     
    114113        AggInst_t aggInst;
    115114        Array_t array;
    116         Enumeration_t enumeration;
    117115        Function_t function;
    118116        Symbolic_t symbolic;
  • src/Parser/parser.yy

    r84886499 r67467a3  
    202202
    203203DeclarationNode * fieldDecl( DeclarationNode * typeSpec, DeclarationNode * fieldList ) {
    204         if ( ! fieldList ) {                                                            // field declarator ?
    205                 if ( ! ( typeSpec->type && (typeSpec->type->kind == TypeData::Aggregate || typeSpec->type->kind == TypeData::Enum) ) ) {
     204        if ( nullptr == fieldList ) {
     205                if ( !( typeSpec->type && typeSpec->type->kind == TypeData::Aggregate ) ) {
    206206                        stringstream ss;
    207207                        // printf( "fieldDecl1 typeSpec %p\n", typeSpec ); typeSpec->type->print( std::cout );
     
    21732173                {
    21742174                        SemanticError( yylloc, "syntax error, expecting ';' at end of \"%s\" declaration.",
    2175                                                    $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ) );
     2175                                                   ast::AggregateDecl::aggrString( $1->type->aggregate.kind ) );
    21762176                        $$ = nullptr;
    21772177                }
     
    32453245                        if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static &&
    32463246                                 $1->type && $1->type->kind == TypeData::AggregateInst ) {
    3247                                 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {
    3248                                         SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;
    3249                                 } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union
    3250                                         SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;
     3247                                if ( $1->type->aggInst.aggregate->aggregate.anon ) {
     3248                                        SemanticError( yylloc, "extern anonymous aggregate is currently unimplemented." ); $$ = nullptr;
    32513249                                }
    32523250                        }
Note: See TracChangeset for help on using the changeset viewer.