Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    ra7c90d4 r43c89a7  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar  7 08:02:09 2017
    13 // Update Count     : 936
     12// Last Modified On : Thu Feb 23 22:21:06 2017
     13// Update Count     : 775
    1414//
    1515
     
    1919#include <algorithm>
    2020#include <cassert>
    21 #include <strings.h>                                                                    // ffs
    2221
    2322#include "TypeData.h"
     
    3332
    3433// These must remain in the same order as the corresponding DeclarationNode enumerations.
    35 const char * DeclarationNode::storageClassNames[] = { "extern", "static", "auto", "register", "_Thread_local", "NoStorageClassNames" };
    36 const char * DeclarationNode::funcSpecifierNames[] = { "inline", "fortran", "_Noreturn", "NoFunctionSpecifierNames" };
    37 const char * DeclarationNode::typeQualifierNames[] = { "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic", "NoTypeQualifierNames" };
    38 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "float", "double", "long double", "NoBasicTypeNames" };
    39 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "_Imaginary", "NoComplexTypeNames" };
    40 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" };
    41 const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" };
    42 const char * DeclarationNode::aggregateNames[] = { "struct", "union", "context", "NoAggregateNames" };
    43 const char * DeclarationNode::typeClassNames[] = { "otype", "dtype", "ftype", "NoTypeClassNames" };
    44 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "NoBuiltinTypeNames" };
     34const char * DeclarationNode::storageName[] = { "extern", "static", "auto", "register", "inline", "fortran", "_Noreturn", "_Thread_local", "NoStorageClass" };
     35const char * DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue", "_Atomic", "NoQualifier" };
     36const char * DeclarationNode::basicTypeName[] = { "void", "_Bool", "char", "int", "float", "double", "long double", "NoBasicType" };
     37const char * DeclarationNode::complexTypeName[] = { "_Complex", "_Imaginary", "NoComplexType" };
     38const char * DeclarationNode::signednessName[] = { "signed", "unsigned", "NoSignedness" };
     39const char * DeclarationNode::lengthName[] = { "short", "long", "long long", "NoLength" };
     40const char * DeclarationNode::aggregateName[] = { "struct", "union", "context" };
     41const char * DeclarationNode::typeClassName[] = { "otype", "dtype", "ftype" };
     42const char * DeclarationNode::builtinTypeName[] = { "__builtin_va_list" };
    4543
    4644UniqueName DeclarationNode::anonymous( "__anonymous" );
     
    5048DeclarationNode::DeclarationNode() :
    5149                type( nullptr ),
     50                storageClass( NoStorageClass ),
    5251                bitfieldWidth( nullptr ),
     52                isInline( false ),
     53                isNoreturn( false ),
    5354                hasEllipsis( false ),
    5455                linkage( ::linkage ),
     
    8990
    9091        newnode->type = maybeClone( type );
    91         newnode->storageClasses = storageClasses;
     92        newnode->storageClass = storageClass;
    9293        newnode->bitfieldWidth = maybeClone( bitfieldWidth );
    93         newnode->funcSpecs = funcSpecs;
     94        newnode->isInline = isInline;
     95        newnode->isNoreturn = isNoreturn;
    9496        newnode->enumeratorValue.reset( maybeClone( enumeratorValue.get() ) );
    9597        newnode->hasEllipsis = hasEllipsis;
     
    116118}
    117119
    118 void DeclarationNode::print_StorageClass( std::ostream & output, StorageClasses storageClasses ) {
    119         if ( storageClasses.any() ) {                                                           // function specifiers?
    120                 for ( unsigned int i = 0; i < DeclarationNode::NoStorageClass; i += 1 ) {
    121                         if ( storageClasses[i] ) {
    122                                 output << DeclarationNode::storageClassNames[i] << ' ';
    123                         } // if
    124                 } // for
    125         } // if
    126 } // print_StorageClass
    127 
    128 void DeclarationNode::print_FuncSpec( std::ostream & output, DeclarationNode::FuncSpecifiers funcSpec ) {
    129         if ( funcSpec.any() ) {                                                         // function specifiers?
    130                 for ( unsigned int i = 0; i < DeclarationNode::NoFuncSpecifier; i += 1 ) {
    131                         if ( funcSpec[i] ) {
    132                                 output << DeclarationNode::funcSpecifierNames[i] << ' ';
    133                         } // if
    134                 } // for
    135         } // if
    136 } // print_FuncSpec
    137 
    138120void DeclarationNode::print( std::ostream &os, int indent ) const {
    139121        os << string( indent, ' ' );
     
    148130        } // if
    149131
    150         print_StorageClass( os, storageClasses );
    151         print_FuncSpec( os, funcSpecs );
    152 
     132        if ( storageClass != NoStorageClass ) os << DeclarationNode::storageName[storageClass] << ' ';
     133        if ( isInline ) os << DeclarationNode::storageName[Inline] << ' ';
     134        if ( isNoreturn ) os << DeclarationNode::storageName[Noreturn] << ' ';
    153135        if ( type ) {
    154136                type->print( os, indent );
     
    201183} // DeclarationNode::newFunction
    202184
     185DeclarationNode * DeclarationNode::newQualifier( Qualifier q ) {
     186        DeclarationNode * newnode = new DeclarationNode;
     187        newnode->type = new TypeData();
     188        newnode->type->qualifiers[ q ] = 1;
     189        return newnode;
     190} // DeclarationNode::newQualifier
     191
     192DeclarationNode * DeclarationNode::newForall( DeclarationNode * forall ) {
     193        DeclarationNode * newnode = new DeclarationNode;
     194        newnode->type = new TypeData( TypeData::Unknown );
     195        newnode->type->forall = forall;
     196        return newnode;
     197} // DeclarationNode::newForall
    203198
    204199DeclarationNode * DeclarationNode::newStorageClass( DeclarationNode::StorageClass sc ) {
    205200        DeclarationNode * newnode = new DeclarationNode;
    206         newnode->storageClasses[ sc ] = true;
     201        newnode->storageClass = sc;
    207202        return newnode;
    208203} // DeclarationNode::newStorageClass
    209 
    210 DeclarationNode * DeclarationNode::newFuncSpecifier( DeclarationNode::FuncSpecifier fs ) {
    211         DeclarationNode * newnode = new DeclarationNode;
    212         newnode->funcSpecs[ fs ] = true;
    213         return newnode;
    214 } // DeclarationNode::newFuncSpecifier
    215 
    216 DeclarationNode * DeclarationNode::newTypeQualifier( TypeQualifier tq ) {
    217         DeclarationNode * newnode = new DeclarationNode;
    218         newnode->type = new TypeData();
    219         newnode->type->typeQualifiers[ tq ] = true;
    220         return newnode;
    221 } // DeclarationNode::newQualifier
    222204
    223205DeclarationNode * DeclarationNode::newBasicType( BasicType bt ) {
     
    248230        return newnode;
    249231} // DeclarationNode::newLength
    250 
    251 DeclarationNode * DeclarationNode::newForall( DeclarationNode * forall ) {
    252         DeclarationNode * newnode = new DeclarationNode;
    253         newnode->type = new TypeData( TypeData::Unknown );
    254         newnode->type->forall = forall;
    255         return newnode;
    256 } // DeclarationNode::newForall
    257232
    258233DeclarationNode * DeclarationNode::newFromTypedef( string * name ) {
     
    453428
    454429void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) {
    455         const TypeData::TypeQualifiers qsrc = src->typeQualifiers, qdst = dst->typeQualifiers; // optimization
     430        TypeData::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
    456431
    457432        if ( (qsrc & qdst).any() ) {                                            // common qualifier ?
    458                 for ( unsigned int i = 0; i < NoTypeQualifier; i += 1 ) { // find common qualifiers
     433                for ( int i = 0; i < NoQualifier; i += 1 ) {    // find common qualifiers
    459434                        if ( qsrc[i] && qdst[i] ) {
    460                                 appendError( error, string( "duplicate " ) + DeclarationNode::typeQualifierNames[i] );
     435                                appendError( error, string( "duplicate " ) + DeclarationNode::qualifierName[i] );
    461436                        } // if
    462437                } // for
    463         } // for
     438        } // if
    464439} // DeclarationNode::checkQualifiers
    465440
    466 void DeclarationNode::checkSpecifiers( DeclarationNode * src ) {
    467         if ( (funcSpecs & src->funcSpecs).any() ) {                     // common specifier ?
    468                 for ( unsigned int i = 0; i < NoFuncSpecifier; i += 1 ) { // find common specifier
    469                         if ( funcSpecs[i] && src->funcSpecs[i] ) {
    470                                 appendError( error, string( "duplicate " ) + DeclarationNode::funcSpecifierNames[i] );
    471                         } // if
    472                 } // for
    473         } // if
    474 
    475         if ( storageClasses != 0 && src->storageClasses != 0 ) { // any reason to check ?
    476                 if ( (storageClasses & src->storageClasses).any() ) { // duplicates ?
    477                         for ( unsigned int i = 0; i < NoStorageClass; i += 1 ) { // find duplicates
    478                                 if ( storageClasses[i] && src->storageClasses[i] ) {
    479                                         appendError( error, string( "duplicate " ) + storageClassNames[i] );
    480                                 } // if
    481                         } // for
    482                         // src is the new item being added and has a single bit
    483                 } else if ( ! src->storageClasses[ Threadlocal ] ) { // conflict ?
    484                         appendError( error, string( "conflicting " ) + storageClassNames[ffs( storageClasses.to_ulong() ) - 1] +
    485                                                  " & " + storageClassNames[ffs( src->storageClasses.to_ulong() ) - 1] );
    486                         src->storageClasses.reset();                            // FIX to preserve invariant of one basic storage specifier
    487                 } // if
    488         } // if
    489 
    490         appendError( error, src->error );
    491 } // DeclarationNode::checkSpecifiers
    492 
    493 DeclarationNode * DeclarationNode::copySpecifiers( DeclarationNode * q ) {
    494         funcSpecs = funcSpecs | q->funcSpecs;
    495         storageClasses = storageClasses | q->storageClasses;
     441void DeclarationNode::checkStorageClasses( DeclarationNode * q ) {
     442        if ( storageClass != NoStorageClass && q->storageClass != NoStorageClass ) {
     443                if ( storageClass == q->storageClass ) {                // duplicate qualifier
     444                        appendError( error, string( "duplicate " ) + storageName[ storageClass ] );
     445                } else {                                                                                // only one storage class
     446                        appendError( error, string( "conflicting " ) + storageName[ storageClass ] + " & " + storageName[ q->storageClass ] );
     447                        q->storageClass = storageClass;                         // FIX ERROR, prevent assertions from triggering
     448                } // if
     449        } // if
     450        appendError( error, q->error );
     451} // DeclarationNode::checkStorageClasses
     452
     453DeclarationNode * DeclarationNode::copyStorageClasses( DeclarationNode * q ) {
     454        isInline = isInline || q->isInline;
     455        isNoreturn = isNoreturn || q->isNoreturn;
     456        // do not overwrite an existing value with NoStorageClass
     457        if ( q->storageClass != NoStorageClass ) {
     458                assert( storageClass == NoStorageClass || storageClass == q->storageClass );
     459                storageClass = q->storageClass;
     460        } // if
    496461
    497462        for ( Attribute *attr: reverseIterate( q->attributes ) ) {
     
    499464        } // for
    500465        return this;
    501 } // DeclarationNode::copySpecifiers
     466} // DeclarationNode::copyStorageClasses
    502467
    503468static void addQualifiersToType( TypeData *&src, TypeData * dst ) {
     
    516481                src = nullptr;
    517482        } else {
    518                 dst->typeQualifiers |= src->typeQualifiers;
     483                dst->qualifiers |= src->qualifiers;
    519484        } // if
    520485} // addQualifiersToType
     
    523488        if ( ! q ) { delete q; return this; }
    524489
    525         checkSpecifiers( q );
    526         copySpecifiers( q );
     490        checkStorageClasses( q );
     491        copyStorageClasses( q );
    527492
    528493        if ( ! q->type ) {
     
    553518        } // if
    554519
    555         checkQualifiers( type, q->type );
     520        checkQualifiers( q->type, type );
    556521        addQualifiersToType( q->type, type );
    557522
     
    574539                switch ( dst->kind ) {
    575540                  case TypeData::Unknown:
    576                         src->typeQualifiers |= dst->typeQualifiers;
     541                        src->qualifiers |= dst->qualifiers;
    577542                        dst = src;
    578543                        src = nullptr;
    579544                        break;
    580545                  case TypeData::Basic:
    581                         dst->typeQualifiers |= src->typeQualifiers;
     546                        dst->qualifiers |= src->qualifiers;
    582547                        if ( src->kind != TypeData::Unknown ) {
    583548                                assert( src->kind == TypeData::Basic );
     
    586551                                        dst->basictype = src->basictype;
    587552                                } else if ( src->basictype != DeclarationNode::NoBasicType )
    588                                         throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::basicTypeNames[ src->basictype ] + " in type: ", src );
     553                                        throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::basicTypeName[ src->basictype ] + " in type: ", src );
    589554
    590555                                if ( dst->complextype == DeclarationNode::NoComplexType ) {
    591556                                        dst->complextype = src->complextype;
    592557                                } else if ( src->complextype != DeclarationNode::NoComplexType )
    593                                         throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::complexTypeNames[ src->complextype ] + " in type: ", src );
     558                                        throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::complexTypeName[ src->complextype ] + " in type: ", src );
    594559
    595560                                if ( dst->signedness == DeclarationNode::NoSignedness ) {
    596561                                        dst->signedness = src->signedness;
    597562                                } else if ( src->signedness != DeclarationNode::NoSignedness )
    598                                         throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::signednessNames[ src->signedness ] + " in type: ", src );
     563                                        throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::signednessName[ src->signedness ] + " in type: ", src );
    599564
    600565                                if ( dst->length == DeclarationNode::NoLength ) {
     
    603568                                        dst->length = DeclarationNode::LongLong;
    604569                                } else if ( src->length != DeclarationNode::NoLength )
    605                                         throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::lengthNames[ src->length ] + " in type: ", src );
     570                                        throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::lengthName[ src->length ] + " in type: ", src );
    606571                        } // if
    607572                        break;
     
    615580                                        dst->base->aggInst.params = maybeClone( src->aggregate.actuals );
    616581                                } // if
    617                                 dst->base->typeQualifiers |= src->typeQualifiers;
     582                                dst->base->qualifiers |= src->qualifiers;
    618583                                src = nullptr;
    619584                                break;
     
    634599DeclarationNode * DeclarationNode::addType( DeclarationNode * o ) {
    635600        if ( o ) {
    636                 checkSpecifiers( o );
    637                 copySpecifiers( o );
     601                checkStorageClasses( o );
     602                copyStorageClasses( o );
    638603                if ( o->type ) {
    639604                        if ( ! type ) {
     
    647612                                                type->aggInst.hoistType = o->type->enumeration.body;
    648613                                        } // if
    649                                         type->typeQualifiers |= o->type->typeQualifiers;
     614                                        type->qualifiers |= o->type->qualifiers;
    650615                                } else {
    651616                                        type = o->type;
     
    803768                                        p->type->base->aggInst.params = maybeClone( type->aggregate.actuals );
    804769                                } // if
    805                                 p->type->base->typeQualifiers |= type->typeQualifiers;
     770                                p->type->base->qualifiers |= type->qualifiers;
    806771                                break;
    807772
     
    840805                                        lastArray->base->aggInst.params = maybeClone( type->aggregate.actuals );
    841806                                } // if
    842                                 lastArray->base->typeQualifiers |= type->typeQualifiers;
     807                                lastArray->base->qualifiers |= type->qualifiers;
    843808                                break;
    844809                          default:
     
    889854        DeclarationNode * newnode = new DeclarationNode;
    890855        newnode->type = maybeClone( type );
    891         newnode->copySpecifiers( this );
     856        assert( storageClass == NoStorageClass );
     857        newnode->copyStorageClasses( this );
    892858        assert( newName );
    893859        newnode->name = newName;
     
    898864        if ( ! o ) return nullptr;
    899865
    900         o->copySpecifiers( this );
     866        o->copyStorageClasses( this );
    901867        if ( type ) {
    902868                TypeData * srcType = type;
     
    990956                                } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
    991957                                        StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
    992                                         auto obj = new ObjectDecl( "", DeclarationNode::StorageClasses(), linkage, nullptr, inst, nullptr );
     958                                        auto obj = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, nullptr, inst, nullptr );
    993959                                        obj->location = cur->location;
    994960                                        * out++ = obj;
     
    996962                                } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
    997963                                        UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
    998                                         auto obj = new ObjectDecl( "", DeclarationNode::StorageClasses(), linkage, nullptr, inst, nullptr );
     964                                        auto obj = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, nullptr, inst, nullptr );
    999965                                        obj->location = cur->location;
    1000966                                        * out++ = obj;
     
    10391005        } // if
    10401006
     1007//      if ( variable.name ) {
    10411008        if ( variable.tyClass != NoTypeClass ) {
    10421009                static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype };
    10431010                assertf( sizeof(kindMap)/sizeof(kindMap[0] == NoTypeClass-1), "DeclarationNode::build: kindMap is out of sync." );
    10441011                assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
    1045                 TypeDecl * ret = new TypeDecl( *name, DeclarationNode::StorageClasses(), nullptr, kindMap[ variable.tyClass ] );
     1012//              TypeDecl * ret = new TypeDecl( *variable.name, DeclarationNode::NoStorageClass, nullptr, kindMap[ variable.tyClass ] );
     1013                TypeDecl * ret = new TypeDecl( *name, DeclarationNode::NoStorageClass, nullptr, kindMap[ variable.tyClass ] );
    10461014                buildList( variable.assertions, ret->get_assertions() );
    10471015                return ret;
     
    10491017
    10501018        if ( type ) {
    1051                 // Function specifiers can only appear on a function definition/declaration.
    1052                 //
    1053                 //    inline _Noreturn int f();                 // allowed
    1054                 //    inline _Noreturn int g( int i );  // allowed
    1055                 //    inline _Noreturn int i;                   // disallowed
    1056                 if ( type->kind != TypeData::Function && funcSpecs.any() ) {
    1057                         throw SemanticError( "invalid function specifier for ", this );
    1058                 } // if
    1059                 return buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
    1060         } // if
    1061 
    1062         // SUE's cannot have function specifiers, either
    1063         //
    1064         //    inlne _Noreturn struct S { ... };         // disallowed
    1065         //    inlne _Noreturn enum   E { ... };         // disallowed
    1066         if ( funcSpecs.any() ) {
    1067                 throw SemanticError( "invalid function specifier for ", this );
    1068         } // if
    1069         assertf( name, "ObjectDecl must a have name\n" );
    1070         return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild< Expression >( bitfieldWidth ), nullptr, maybeBuild< Initializer >( initializer ) ))->set_asmName( asmName )->set_extension( extension );
     1019                return buildDecl( type, name ? *name : string( "" ), storageClass, maybeBuild< Expression >( bitfieldWidth ), isInline, isNoreturn, linkage, asmName, maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
     1020        } // if
     1021
     1022        if ( ! isInline && ! isNoreturn ) {
     1023                assertf( name, "ObjectDecl are assumed to have names\n" );
     1024                return (new ObjectDecl( *name, storageClass, linkage, maybeBuild< Expression >( bitfieldWidth ), nullptr, maybeBuild< Initializer >( initializer ) ))->set_asmName( asmName )->set_extension( extension );
     1025        } // if
     1026
     1027        throw SemanticError( "invalid function specifier ", this );
    10711028}
    10721029
     
    10751032
    10761033        if ( attr.expr ) {
     1034//              return new AttrType( buildQualifiers( type ), *attr.name, attr.expr->build() );
    10771035                return new AttrType( buildQualifiers( type ), *name, attr.expr->build(), attributes );
    10781036        } else if ( attr.type ) {
     1037//              return new AttrType( buildQualifiers( type ), *attr.name, attr.type->buildType() );
    10791038                return new AttrType( buildQualifiers( type ), *name, attr.type->buildType(), attributes );
    10801039        } // if
Note: See TracChangeset for help on using the changeset viewer.