Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r843054c2 rde62360d  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May 21 09:28:54 2015
    13 // Update Count     : 13
     12// Last Modified On : Wed Jun 24 15:29:19 2015
     13// Update Count     : 86
    1414//
    1515
     
    2121
    2222#include "TypeData.h"
     23
     24#include "SynTree/Declaration.h"
    2325#include "SynTree/Expression.h"
    2426
     27#include "Parser.h"
     28#include "TypedefTable.h"
     29extern TypedefTable typedefTable;
    2530
    2631using namespace std;
    2732
    2833// These must remain in the same order as the corresponding DeclarationNode enumerations.
     34const char *DeclarationNode::storageName[] = { "extern", "static", "auto", "register", "inline", "fortran", "_Noreturn", "_Thread_local", "" };
    2935const char *DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue", "_Atomic" };
    3036const char *DeclarationNode::basicTypeName[] = { "char", "int", "float", "double", "void", "_Bool", "_Complex", "_Imaginary" };
    31 const char *DeclarationNode::modifierName[] = { "signed", "unsigned", "short", "long" };
    32 const char *DeclarationNode::tyConName[] = { "struct", "union", "context" };
     37const char *DeclarationNode::modifierName[]  = { "signed", "unsigned", "short", "long" };
     38const char *DeclarationNode::aggregateName[] = { "struct", "union", "context" };
    3339const char *DeclarationNode::typeClassName[] = { "type", "dtype", "ftype" };
    3440
     
    6369}
    6470
    65 const char *storageClassName[] = {
    66         // order must correspond with DeclarationNode::StorageClass
    67         "extern",
    68         "static",
    69         "auto",
    70         "register",
    71         "inline",
    72         "fortran",
    73 };
    74 
    7571void DeclarationNode::print( std::ostream &os, int indent ) const {
    76         os << string(indent, ' ' );
     72        os << string( indent, ' ' );
    7773        if ( name == "" ) {
    7874                os << "unnamed: ";
    7975        } else {
    8076                os << name << ": ";
    81         }
     77        } // if
    8278
    8379        if ( linkage != LinkageSpec::Cforall ) {
    8480                os << LinkageSpec::toString( linkage ) << " ";
    85         }
    86 
    87         printEnums( storageClasses.begin(), storageClasses.end(), storageClassName, os );
     81        } // if
     82
     83        printEnums( storageClasses.begin(), storageClasses.end(), DeclarationNode::storageName, os );
    8884        if ( type ) {
    8985                type->print( os, indent );
    9086        } else {
    9187                os << "untyped entity ";
    92         }
     88        } // if
    9389
    9490        if ( bitfieldWidth ) {
    95                 os << endl << string(indent+2,  ' ') << "with bitfield width ";
     91                os << endl << string( indent + 2, ' ' ) << "with bitfield width ";
    9692                bitfieldWidth->printOneLine( os );
    97         }
     93        } // if
    9894
    9995        if ( initializer != 0 ) {
    100                 os << endl << string(indent+2,  ' ') << "with initializer ";
     96                os << endl << string( indent + 2, ' ' ) << "with initializer ";
    10197                initializer->printOneLine( os );
    102         }
     98        } // if
    10399
    104100        os << endl;
     
    109105        if ( hasEllipsis ) {
    110106                os << string( indent, ' ' )  << "and a variable number of other arguments" << endl;
    111         }
     107        } // if
    112108}
    113109
     
    123119        if ( body ) {
    124120                newnode->type->function->hasBody = true;
    125         }
     121        } // if
    126122
    127123        if ( ret ) {
     
    129125                ret->type = 0;
    130126                delete ret;
    131         }
     127        } // if
    132128
    133129        return newnode;
     
    141137}
    142138
    143 DeclarationNode *DeclarationNode::newStorageClass( StorageClass sc ) {
     139DeclarationNode *DeclarationNode::newStorageClass( DeclarationNode::StorageClass sc ) {
    144140        DeclarationNode *newnode = new DeclarationNode;
    145141        newnode->storageClasses.push_back( sc );
     
    161157}
    162158
    163 DeclarationNode *DeclarationNode::newForall( DeclarationNode* forall ) {
     159DeclarationNode *DeclarationNode::newForall( DeclarationNode *forall ) {
    164160        DeclarationNode *newnode = new DeclarationNode;
    165161        newnode->type = new TypeData( TypeData::Unknown );
     
    168164}
    169165
    170 DeclarationNode *DeclarationNode::newFromTypedef( std::string* name ) {
     166DeclarationNode *DeclarationNode::newFromTypedef( std::string *name ) {
    171167        DeclarationNode *newnode = new DeclarationNode;
    172168        newnode->type = new TypeData( TypeData::SymbolicInst );
     
    177173}
    178174
    179 DeclarationNode *DeclarationNode::newAggregate( TyCon kind, std::string* name, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields ) {
     175DeclarationNode *DeclarationNode::newAggregate( Aggregate kind, std::string *name, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields ) {
    180176        DeclarationNode *newnode = new DeclarationNode;
    181177        newnode->type = new TypeData( TypeData::Aggregate );
     
    184180        if ( newnode->type->aggregate->name == "" ) {
    185181                newnode->type->aggregate->name = DeclarationNode::anonymous.newName();
    186         }
     182        } // if
     183
     184        // SKULLDUGGERY: generate a typedef for the aggregate name so that the aggregate does not have to be qualified by
     185        // "struct"
     186        typedefTable.addToEnclosingScope( newnode->type->aggregate->name, TypedefTable::TD );
     187        DeclarationNode *typedf = new DeclarationNode;
     188        typedf->name = newnode->type->aggregate->name;
     189        newnode->appendList( typedf->addType( newnode->clone() )->addTypedef() );
     190
    187191        newnode->type->aggregate->params = formals;
    188192        newnode->type->aggregate->actuals = actuals;
     
    198202        if ( newnode->type->enumeration->name == "" ) {
    199203                newnode->type->enumeration->name = DeclarationNode::anonymous.newName();
    200         }
     204        } // if
     205
     206        // SKULLDUGGERY: generate a typedef for the enumeration name so that the enumeration does not have to be qualified
     207        // by "enum"
     208        typedefTable.addToEnclosingScope( newnode->type->enumeration->name, TypedefTable::TD );
     209        DeclarationNode *typedf = new DeclarationNode;
     210        typedf->name = newnode->type->enumeration->name;
     211        newnode->appendList( typedf->addType( newnode->clone() )->addTypedef() );
     212
    201213        newnode->type->enumeration->constants = constants;
    202214        return newnode;
    203215}
    204216
    205 DeclarationNode *DeclarationNode::newEnumConstant( std::string* name, ExpressionNode *constant ) {
     217DeclarationNode *DeclarationNode::newEnumConstant( std::string *name, ExpressionNode *constant ) {
    206218        DeclarationNode *newnode = new DeclarationNode;
    207219        newnode->name = assign_strptr( name );
     
    210222}
    211223
    212 DeclarationNode *DeclarationNode::newName( std::string* name ) {
     224DeclarationNode *DeclarationNode::newName( std::string *name ) {
    213225        DeclarationNode *newnode = new DeclarationNode;
    214226        newnode->name = assign_strptr( name );
     
    216228}
    217229
    218 DeclarationNode *DeclarationNode::newFromTypeGen( std::string* name, ExpressionNode *params ) {
     230DeclarationNode *DeclarationNode::newFromTypeGen( std::string *name, ExpressionNode *params ) {
    219231        DeclarationNode *newnode = new DeclarationNode;
    220232        newnode->type = new TypeData( TypeData::SymbolicInst );
     
    225237}
    226238
    227 DeclarationNode *DeclarationNode::newTypeParam( TypeClass tc, std::string* name ) {
     239DeclarationNode *DeclarationNode::newTypeParam( TypeClass tc, std::string *name ) {
    228240        DeclarationNode *newnode = new DeclarationNode;
    229241        newnode->name = assign_strptr( name );
     
    331343                        } else {
    332344                                dst->forall = src->forall;
    333                         }
     345                        } // if
    334346                        src->forall = 0;
    335                 }
     347                } // if
    336348                if ( dst->base ) {
    337349                        addQualifiersToType( src, dst->base );
     
    341353                } else {
    342354                        dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
    343                 }
    344         }
     355                } // if
     356        } // if
    345357}
    346358         
     
    351363                        if ( ! type ) {
    352364                                type = new TypeData;
    353                         }
     365                        } // if
    354366                        addQualifiersToType( q->type, type );
    355367                        if ( q->type && q->type->forall ) {
     
    357369                                        type->forall->appendList( q->type->forall );
    358370                                } else {
    359                                         type->forall = q->type->forall;
    360                                 }
     371                                        if ( type->kind == TypeData::Aggregate ) {
     372                                                type->aggregate->params = q->type->forall;
     373                                        } else {
     374                                                type->forall = q->type->forall;
     375                                        } // if
     376                                } // if
    361377                                q->type->forall = 0;
    362                         }
    363                 }
    364         }
     378                        } // if
     379                } // if
     380        } // if
    365381        delete q;
    366382        return this;
     
    379395                        } else {
    380396                                dst->forall = src->forall;
    381                         }
     397                        } // if
    382398                        src->forall = 0;
    383                 }
     399                } // if
    384400                if ( dst->base ) {
    385401                        addTypeToType( src, dst->base );
     
    398414                                        dst->basic->modifiers.splice( dst->basic->modifiers.end(), src->basic->modifiers );
    399415                                        dst->basic->typeSpec.splice( dst->basic->typeSpec.end(), src->basic->typeSpec );
    400                                 }
     416                                } // if
    401417                                break;
    402418
     
    409425                                        if ( src->kind == TypeData::Aggregate ) {
    410426                                                dst->base->aggInst->params = maybeClone( src->aggregate->actuals );
    411                                         }
     427                                        } // if
    412428                                        dst->base->qualifiers.splice( dst->base->qualifiers.end(), src->qualifiers );
    413429                                        src = 0;
     
    419435                                        } else {
    420436                                                dst->forall = src->forall;
    421                                         }
     437                                        } // if
    422438                                        src->forall = 0;
    423439                                        dst->base = src;
    424440                                        src = 0;
    425                                 }
    426                         }
    427                 }
    428         }
     441                                } // switch
     442                        } // switch
     443                } // if
     444        } // if
    429445}
    430446
     
    439455                                        if ( o->type->kind == TypeData::Aggregate ) {
    440456                                                type->aggInst->params = maybeClone( o->type->aggregate->actuals );
    441                                         }
     457                                        } // if
    442458                                        type->qualifiers.splice( type->qualifiers.end(), o->type->qualifiers );
    443459                                } else {
    444460                                        type = o->type;
    445                                 }
     461                                } // if
    446462                                o->type = 0;
    447463                        } else {
    448464                                addTypeToType( o->type, type );
    449                         }
    450                 }
     465                        } // if
     466                } // if
    451467                if ( o->bitfieldWidth ) {
    452468                        bitfieldWidth = o->bitfieldWidth;
    453                 }
    454         }
     469                } // if
     470        } // if
    455471        delete o;
    456472        return this;
     
    467483}
    468484
    469 DeclarationNode *DeclarationNode::addAssertions( DeclarationNode* assertions ) {
     485DeclarationNode *DeclarationNode::addAssertions( DeclarationNode *assertions ) {
    470486        assert( type );
    471487        switch ( type->kind ) {
     
    475491                } else {
    476492                        type->symbolic->assertions = assertions;
    477                 }
     493                } // if
    478494                break;
    479        
    480495          case TypeData::Variable:
    481496                if ( type->variable->assertions ) {
     
    483498                } else {
    484499                        type->variable->assertions = assertions;
    485                 }
     500                } // if
    486501                break;
    487        
    488502          default:
    489503                assert( false );
    490         }
     504        } // switch
    491505       
    492506        return this;
    493507}
    494508
    495 DeclarationNode *DeclarationNode::addName( std::string* newname ) {
     509DeclarationNode *DeclarationNode::addName( std::string *newname ) {
    496510        name = assign_strptr( newname );
    497511        return this;
     
    526540}
    527541
    528 static void
    529 setBase( TypeData *&type, TypeData *newType ) {
     542static void setBase( TypeData *&type, TypeData *newType ) {
    530543        if ( type ) {
    531544                TypeData *prevBase = type;
     
    534547                        prevBase = curBase;
    535548                        curBase = curBase->base;
    536                 }
     549                } // while
    537550                prevBase->base = newType;
    538551        } else {
    539552                type = newType;
    540         }
     553        } // if
    541554}
    542555
     
    547560                p->type = 0;
    548561                delete p;
    549         }
     562        } // if
    550563        return this;
    551564}
     
    557570                a->type = 0;
    558571                delete a;
    559         }
     572        } // if
    560573        return this;
    561574}
     
    572585                                if ( type->kind == TypeData::Aggregate ) {
    573586                                        p->type->base->aggInst->params = maybeClone( type->aggregate->actuals );
    574                                 }
     587                                } // if
    575588                                p->type->base->qualifiers.splice( p->type->base->qualifiers.end(), type->qualifiers );
    576589                                break;
     
    578591                          default:
    579592                                p->type->base = type;
    580                         }
     593                        } // switch
    581594                        type = 0;
    582                 }
     595                } // if
    583596                delete this;
    584597                return p;
    585598        } else {
    586599                return this;
    587         }
     600        } // if
    588601}
    589602
     
    593606        while ( cur->base ) {
    594607                cur = cur->base;
    595         }
     608        } // while
    596609        return cur;
    597610}
     
    609622                                if ( type->kind == TypeData::Aggregate ) {
    610623                                        lastArray->base->aggInst->params = maybeClone( type->aggregate->actuals );
    611                                 }
     624                                } // if
    612625                                lastArray->base->qualifiers.splice( lastArray->base->qualifiers.end(), type->qualifiers );
    613626                                break;
    614627                          default:
    615628                                lastArray->base = type;
    616                         }
     629                        } // switch
    617630                        type = 0;
    618                 }
     631                } // if
    619632                delete this;
    620633                return a;
    621634        } else {
    622635                return this;
    623         }
     636        } // if
    624637}
    625638
     
    637650                } else {
    638651                        type->function->idList = ids;
    639                 }
     652                } // if
    640653                return type;
    641654        } else {
     
    643656                newtype->function->idList = ids;
    644657                return newtype;
    645         }
     658        } // if
    646659}
    647660       
     
    662675        while ( srcType->base ) {
    663676                srcType = srcType->base;
    664         }
     677        } // while
    665678        newnode->type = maybeClone( srcType );
    666679        if ( newnode->type->kind == TypeData::AggregateInst ) {
     
    673686                        delete newnode->type->aggInst->aggregate->aggregate->members;
    674687                        newnode->type->aggInst->aggregate->aggregate->members = 0;
    675                 }
    676         }
     688                } // if
     689        } // if
    677690        newnode->type->forall = maybeClone( type->forall );
    678691        newnode->storageClasses = storageClasses;
     
    688701                        while ( srcType->base ) {
    689702                                srcType = srcType->base;
    690                         }
     703                        } // while
    691704                        TypeData *newType = srcType->clone();
    692705                        if ( newType->kind == TypeData::AggregateInst ) {
     
    699712                                        delete newType->aggInst->aggregate->aggregate->members;
    700713                                        newType->aggInst->aggregate->aggregate->members = 0;
    701                                 }
    702                         }
     714                                } // if
     715                        } // if
    703716                        newType->forall = maybeClone( type->forall );
    704717                        if ( ! o->type ) {
     
    707720                                addTypeToType( newType, o->type );
    708721                                delete newType;
    709                         }
    710                 }
    711         }
     722                        } // if
     723                } // if
     724        } // if
    712725        return o;
    713726}
     
    731744                                addTypeToType( newType, o->type );
    732745                                delete newType;
    733                         }
    734                 }
    735         }
     746                        } // if
     747                } // if
     748        } // if
    736749        return o;
    737750}
     
    740753        if ( node != 0 ) {
    741754                set_link( node );
    742         }
     755        } // if
    743756        return this;
    744757}
     
    756769}
    757770
    758 void buildList( const DeclarationNode *firstNode, std::list< Declaration* > &outputList ) {
     771void buildList( const DeclarationNode *firstNode, std::list< Declaration * > &outputList ) {
    759772        SemanticError errors;
    760         std::back_insert_iterator< std::list< Declaration* > > out( outputList );
     773        std::back_insert_iterator< std::list< Declaration *> > out( outputList );
    761774        const DeclarationNode *cur = firstNode;
    762775        while ( cur ) {
     
    776789                        errors.append( e );
    777790                } // try
    778                 cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
     791                cur = dynamic_cast< DeclarationNode *>( cur->get_link() );
    779792        } // while
    780793        if ( ! errors.isEmpty() ) {
     
    783796}
    784797
    785 void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType* > &outputList ) {
     798void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType *> &outputList ) {
    786799        SemanticError errors;
    787         std::back_insert_iterator< std::list< DeclarationWithType* > > out( outputList );
     800        std::back_insert_iterator< std::list< DeclarationWithType *> > out( outputList );
    788801        const DeclarationNode *cur = firstNode;
    789802        while ( cur ) {
     
    799812                        Declaration *decl = cur->build();
    800813                        if ( decl ) {
    801                                 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
     814                                if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType *>( decl ) ) {
    802815                                        *out++ = dwt;
    803                                 } else if ( StructDecl *agg = dynamic_cast< StructDecl* >( decl ) ) {
     816                                } else if ( StructDecl *agg = dynamic_cast< StructDecl *>( decl ) ) {
    804817                                        StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
    805                                         *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
     818                                        *out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 );
    806819                                        delete agg;
    807                                 } else if ( UnionDecl *agg = dynamic_cast< UnionDecl* >( decl ) ) {
     820                                } else if ( UnionDecl *agg = dynamic_cast< UnionDecl *>( decl ) ) {
    808821                                        UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
    809                                         *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
     822                                        *out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 );
    810823                                } // if
    811824                        } // if
     
    813826                        errors.append( e );
    814827                } // try
    815                 cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
     828                cur = dynamic_cast< DeclarationNode *>( cur->get_link() );
    816829        } // while
    817830        if ( ! errors.isEmpty() ) {
     
    820833}
    821834
    822 void buildTypeList( const DeclarationNode *firstNode, std::list< Type* > &outputList ) {
     835void buildTypeList( const DeclarationNode *firstNode, std::list< Type *> &outputList ) {
    823836        SemanticError errors;
    824         std::back_insert_iterator< std::list< Type* > > out( outputList );
     837        std::back_insert_iterator< std::list< Type *> > out( outputList );
    825838        const DeclarationNode *cur = firstNode;
    826839        while ( cur ) {
     
    830843                        errors.append( e );
    831844                } // try
    832                 cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
     845                cur = dynamic_cast< DeclarationNode *>( cur->get_link() );
    833846        } // while
    834847        if ( ! errors.isEmpty() ) {
     
    839852Declaration *DeclarationNode::build() const {
    840853        if ( type ) {
    841                 Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildInline(), linkage, maybeBuild< Initializer >(initializer) );
     854                Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildFuncSpecifier( Inline ), buildFuncSpecifier( Noreturn ), linkage, maybeBuild< Initializer >(initializer) );
    842855                return newDecl;
    843856        } // if
    844         if ( ! buildInline() ) {
     857        if ( ! buildFuncSpecifier( Inline ) && ! buildFuncSpecifier( Noreturn ) ) {
    845858                return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) );
    846859        } // if
    847         throw SemanticError( "invalid inline specification in declaration of ", this );
     860        throw SemanticError( "invalid function specifier in declaration of ", this );
    848861}
    849862
     
    882895}
    883896
    884 Declaration::StorageClass DeclarationNode::buildStorageClass() const {
    885         static const Declaration::StorageClass scMap[] = { 
    886                 Declaration::Extern,
    887                 Declaration::Static,
    888                 Declaration::Auto,
    889                 Declaration::Register,
    890                 Declaration::Inline,
    891                 Declaration::Fortran
    892         }; 
    893  
    894         Declaration::StorageClass ret = Declaration::NoStorageClass;
    895         for ( std::list< StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
    896                 assert( unsigned( *i ) < sizeof( scMap ) / sizeof( scMap[0] ) );
    897           if ( *i == Inline ) continue;
    898           if ( ret != Declaration::NoStorageClass ) {
     897DeclarationNode::StorageClass DeclarationNode::buildStorageClass() const {
     898        DeclarationNode::StorageClass ret = DeclarationNode::NoStorageClass;
     899        for ( std::list< DeclarationNode::StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
     900          if ( *i == DeclarationNode::Inline || *i == DeclarationNode::Noreturn ) continue; // ignore function specifiers
     901          if ( ret != DeclarationNode::NoStorageClass ) {       // already have a valid storage class ?
    899902                        throw SemanticError( "invalid combination of storage classes in declaration of ", this );
    900                 }
    901                 ret = scMap[ *i ];
    902         }
     903                } // if
     904                ret = *i;
     905        } // for
    903906        return ret;
    904907}
    905908
    906 bool DeclarationNode::buildInline() const {
    907         std::list< StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), Inline );
    908   if ( first == storageClasses.end() ) return false;
    909         std::list< StorageClass >::const_iterator next = std::find( ++first, storageClasses.end(), Inline );
    910   if ( next == storageClasses.end() ) return true;
    911         throw SemanticError( "duplicate inline specification in declaration of ", this );
     909bool DeclarationNode::buildFuncSpecifier( DeclarationNode::StorageClass key ) const {
     910        std::list< DeclarationNode::StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), key );
     911  if ( first == storageClasses.end() ) return false;    // not found
     912        first = std::find( ++first, storageClasses.end(), key ); // found
     913  if ( first == storageClasses.end() ) return true;             // not found again
     914        throw SemanticError( "duplicate function specifier in declaration of ", this );
    912915}
    913916
Note: See TracChangeset for help on using the changeset viewer.