Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r28307be rb6424d9  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 29 22:30:56 2016
    13 // Update Count     : 327
     12// Last Modified On : Sun Sep 11 09:24:11 2016
     13// Update Count     : 438
    1414//
    1515
     
    3131
    3232// These must remain in the same order as the corresponding DeclarationNode enumerations.
    33 const char *DeclarationNode::storageName[] = { "extern", "static", "auto", "register", "inline", "fortran", "_Noreturn", "_Thread_local", "" };
     33const char *DeclarationNode::storageName[] = { "extern", "static", "auto", "register", "inline", "fortran", "_Noreturn", "_Thread_local", "NoStorageClass" };
    3434const char *DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue", "_Atomic" };
    3535const char *DeclarationNode::basicTypeName[] = { "char", "int", "float", "double", "void", "_Bool", "_Complex", "_Imaginary",  };
     
    4343extern LinkageSpec::Spec linkage;                                               // defined in parser.yy
    4444
    45 DeclarationNode::DeclarationNode()
    46                 : type( 0 )
    47                 , storageClass( NoStorageClass )
    48                 , isInline( false )
    49                 , isNoreturn( false )
    50                 , bitfieldWidth( 0 )
    51                 , initializer( 0 )
    52                 , hasEllipsis( false )
    53                 , linkage( ::linkage )
    54                 , extension( false )
    55                 , error() {
     45DeclarationNode::DeclarationNode() :
     46                type( 0 ),
     47                storageClass( NoStorageClass ),
     48                isInline( false ),
     49                isNoreturn( false ),
     50                bitfieldWidth( 0 ),
     51                initializer( 0 ),
     52                hasEllipsis( false ),
     53                linkage( ::linkage ),
     54                extension( false ) {
     55        variable.tyClass = DeclarationNode::Type;
     56        variable.assertions = nullptr;
     57
    5658        attr.expr = nullptr;
    5759        attr.type = nullptr;
    58 
    59         variable.tyClass = DeclarationNode::Type;
    60         variable.assertions = nullptr;
    6160}
    6261
     
    390389
    391390void DeclarationNode::checkQualifiers( const TypeData *src, const TypeData *dst ) {
    392         TypeData::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers;
    393 
    394         if ( (qsrc & qdst).any() ) {                                            // common bits between qualifier masks ?
    395                 error = "duplicate qualifier ";
    396                 int j = 0;                                                                              // separator detector
    397                 for ( int i = 0; i < DeclarationNode::NoOfQualifier; i += 1 ) {
    398                         if ( qsrc[i] & qdst[i] ) {                                      // find specific qualifiers in common
    399                                 if ( j > 0 ) error += ", ";
    400                                 error += DeclarationNode::qualifierName[i];
    401                                 j += 1;
     391        TypeData::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
     392
     393        if ( (qsrc & qdst).any() ) {                                            // common qualifier ?
     394                for ( int i = 0; i < NoOfQualifier; i += 1 ) {  // find common qualifiers
     395                        if ( qsrc[i] & qdst[i] ) {
     396                                if ( ! error.empty() ) error += ", ";   // separator
     397                                error += string( "duplicate " ) + DeclarationNode::qualifierName[i];
    402398                        } // if
    403399                } // for
    404                 error += " in declaration of ";
    405400        } // if
    406401} // DeclarationNode::checkQualifiers
     402
     403void DeclarationNode::checkStorageClasses( DeclarationNode *q ) {
     404        if ( storageClass != NoStorageClass && q->storageClass != NoStorageClass ) {
     405                if ( ! error.empty() ) error += ", ";                   // separator
     406                if ( storageClass == q->storageClass ) {                // duplicate qualifier
     407                        error += string( "duplicate " ) + storageName[ storageClass ];
     408                } else {                                                                                // only one storage class
     409                        error += string( "conflicting " ) + storageName[ storageClass ] + " & " + storageName[ q->storageClass ];
     410                        q->storageClass = storageClass;                         // FIX ERROR
     411                } // if
     412                if ( ! q->error.empty() ) error += ", " + q->error;     // separator
     413        } else {
     414                if ( ! error.empty() ) {
     415                        if ( ! q->error.empty() ) error += ", " + q->error; // separator
     416                } else if ( ! q->error.empty() ) error += q->error;
     417        } // if
     418} // DeclarationNode::copyStorageClasses
     419
     420DeclarationNode *DeclarationNode::copyStorageClasses( DeclarationNode *q ) {
     421        isInline = isInline | q->isInline;
     422        isNoreturn = isNoreturn | q->isNoreturn;
     423        // do not overwrite an existing value with NoStorageClass
     424        if ( q->storageClass != NoStorageClass ) {
     425                assert( storageClass == NoStorageClass || storageClass == q->storageClass );
     426                storageClass = q->storageClass;
     427        } // if
     428        return this;
     429} // DeclarationNode::copyStorageClasses
    407430
    408431DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
    409432        if ( q ) {
    410                 copyStorageClasses(q);
     433                checkStorageClasses( q );
     434                copyStorageClasses( q );
    411435                if ( q->type ) {
    412436                        if ( ! type ) {
     
    433457        } // if
    434458        delete q;
    435         return this;
    436 }
    437 
    438 DeclarationNode *DeclarationNode::copyStorageClasses( DeclarationNode *q ) {
    439         isInline = isInline || q->isInline;
    440         isNoreturn = isNoreturn || q->isNoreturn;
    441         if ( storageClass == NoStorageClass ) {
    442                 storageClass = q->storageClass;
    443         } else if ( q->storageClass != NoStorageClass ) {
    444                 q->error = "invalid combination of storage classes in declaration of ";
    445         } // if
    446         if ( error.empty() ) error = q->error;
    447459        return this;
    448460}
     
    504516DeclarationNode *DeclarationNode::addType( DeclarationNode *o ) {
    505517        if ( o ) {
     518                checkStorageClasses( o );
    506519                copyStorageClasses( o );
    507520                if ( o->type ) {
     
    751764        } // if
    752765        newnode->type->forall = maybeClone( type->forall );
     766        assert( storageClass == NoStorageClass );
    753767        newnode->copyStorageClasses( this );
    754768        newnode->name = assign_strptr( newName );
     
    791805        DeclarationNode *newnode = new DeclarationNode;
    792806        newnode->type = maybeClone( type );
     807        assert( storageClass == NoStorageClass );
    793808        newnode->copyStorageClasses( this );
    794809        newnode->name = assign_strptr( newName );
     
    798813DeclarationNode *DeclarationNode::cloneType( DeclarationNode *o ) {
    799814        if ( o ) {
     815                assert( storageClass == NoStorageClass );
    800816                o->copyStorageClasses( this );
    801817                if ( type ) {
     
    908924
    909925Declaration *DeclarationNode::build() const {
    910         if ( ! error.empty() ) throw SemanticError( error, this );
     926        if ( ! error.empty() ) throw SemanticError( error + " in declaration of ", this );
    911927        if ( type ) {
    912928                if ( type->kind == TypeData::Variable ) {
     
    922938                return (new ObjectDecl( name, storageClass, linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) ))->set_extension( extension );
    923939        } // if
    924         throw SemanticError( "invalid function specifier in declaration of ", this );
     940        throw SemanticError( "invalid function specifier ", this );
    925941}
    926942
     
    971987}
    972988
    973 // DeclarationNode::StorageClass DeclarationNode::buildStorageClass() const {
    974 //      DeclarationNode::StorageClass ret = DeclarationNode::NoStorageClass;
    975 //      for ( std::list< DeclarationNode::StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
    976 //        if ( *i == DeclarationNode::Inline || *i == DeclarationNode::Noreturn ) continue; // ignore function specifiers
    977 //        if ( ret != DeclarationNode::NoStorageClass ) {       // already have a valid storage class ?
    978 //                      throw SemanticError( "invalid combination of storage classes in declaration of ", this );
    979 //              } // if
    980 //              ret = *i;
    981 //      } // for
    982 //      return ret;
    983 // }
    984 
    985 // bool DeclarationNode::buildFuncSpecifier( DeclarationNode::StorageClass key ) const {
    986 //      std::list< DeclarationNode::StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), key );
    987 //   if ( first == storageClasses.end() ) return false; // not found
    988 //      first = std::find( ++first, storageClasses.end(), key ); // found
    989 //   if ( first == storageClasses.end() ) return true;          // not found again
    990 //      throw SemanticError( "duplicate function specifier in declaration of ", this );
    991 // }
    992 
    993989// Local Variables: //
    994990// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.