Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    rb6424d9 r28307be  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep 11 09:24:11 2016
    13 // Update Count     : 438
     12// Last Modified On : Mon Aug 29 22:30:56 2016
     13// Update Count     : 327
    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", "NoStorageClass" };
     33const char *DeclarationNode::storageName[] = { "extern", "static", "auto", "register", "inline", "fortran", "_Noreturn", "_Thread_local", "" };
    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 ) {
     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                , error() {
     56        attr.expr = nullptr;
     57        attr.type = nullptr;
     58
    5559        variable.tyClass = DeclarationNode::Type;
    5660        variable.assertions = nullptr;
    57 
    58         attr.expr = nullptr;
    59         attr.type = nullptr;
    6061}
    6162
     
    389390
    390391void DeclarationNode::checkQualifiers( const TypeData *src, const TypeData *dst ) {
    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];
     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;
    398402                        } // if
    399403                } // for
     404                error += " in declaration of ";
    400405        } // if
    401406} // DeclarationNode::checkQualifiers
    402 
    403 void 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 
    420 DeclarationNode *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
    430407
    431408DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
    432409        if ( q ) {
    433                 checkStorageClasses( q );
    434                 copyStorageClasses( q );
     410                copyStorageClasses(q);
    435411                if ( q->type ) {
    436412                        if ( ! type ) {
     
    457433        } // if
    458434        delete q;
     435        return this;
     436}
     437
     438DeclarationNode *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;
    459447        return this;
    460448}
     
    516504DeclarationNode *DeclarationNode::addType( DeclarationNode *o ) {
    517505        if ( o ) {
    518                 checkStorageClasses( o );
    519506                copyStorageClasses( o );
    520507                if ( o->type ) {
     
    764751        } // if
    765752        newnode->type->forall = maybeClone( type->forall );
    766         assert( storageClass == NoStorageClass );
    767753        newnode->copyStorageClasses( this );
    768754        newnode->name = assign_strptr( newName );
     
    805791        DeclarationNode *newnode = new DeclarationNode;
    806792        newnode->type = maybeClone( type );
    807         assert( storageClass == NoStorageClass );
    808793        newnode->copyStorageClasses( this );
    809794        newnode->name = assign_strptr( newName );
     
    813798DeclarationNode *DeclarationNode::cloneType( DeclarationNode *o ) {
    814799        if ( o ) {
    815                 assert( storageClass == NoStorageClass );
    816800                o->copyStorageClasses( this );
    817801                if ( type ) {
     
    924908
    925909Declaration *DeclarationNode::build() const {
    926         if ( ! error.empty() ) throw SemanticError( error + " in declaration of ", this );
     910        if ( ! error.empty() ) throw SemanticError( error, this );
    927911        if ( type ) {
    928912                if ( type->kind == TypeData::Variable ) {
     
    938922                return (new ObjectDecl( name, storageClass, linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) ))->set_extension( extension );
    939923        } // if
    940         throw SemanticError( "invalid function specifier ", this );
     924        throw SemanticError( "invalid function specifier in declaration of ", this );
    941925}
    942926
     
    987971}
    988972
     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
    989993// Local Variables: //
    990994// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.