Changes in src/Parser/DeclarationNode.cc [a7c90d4:43c89a7]
- File:
-
- 1 edited
-
src/Parser/DeclarationNode.cc (modified) (29 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
ra7c90d4 r43c89a7 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Mar 7 08:02:09201713 // Update Count : 93612 // Last Modified On : Thu Feb 23 22:21:06 2017 13 // Update Count : 775 14 14 // 15 15 … … 19 19 #include <algorithm> 20 20 #include <cassert> 21 #include <strings.h> // ffs22 21 23 22 #include "TypeData.h" … … 33 32 34 33 // 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" }; 34 const char * DeclarationNode::storageName[] = { "extern", "static", "auto", "register", "inline", "fortran", "_Noreturn", "_Thread_local", "NoStorageClass" }; 35 const char * DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue", "_Atomic", "NoQualifier" }; 36 const char * DeclarationNode::basicTypeName[] = { "void", "_Bool", "char", "int", "float", "double", "long double", "NoBasicType" }; 37 const char * DeclarationNode::complexTypeName[] = { "_Complex", "_Imaginary", "NoComplexType" }; 38 const char * DeclarationNode::signednessName[] = { "signed", "unsigned", "NoSignedness" }; 39 const char * DeclarationNode::lengthName[] = { "short", "long", "long long", "NoLength" }; 40 const char * DeclarationNode::aggregateName[] = { "struct", "union", "context" }; 41 const char * DeclarationNode::typeClassName[] = { "otype", "dtype", "ftype" }; 42 const char * DeclarationNode::builtinTypeName[] = { "__builtin_va_list" }; 45 43 46 44 UniqueName DeclarationNode::anonymous( "__anonymous" ); … … 50 48 DeclarationNode::DeclarationNode() : 51 49 type( nullptr ), 50 storageClass( NoStorageClass ), 52 51 bitfieldWidth( nullptr ), 52 isInline( false ), 53 isNoreturn( false ), 53 54 hasEllipsis( false ), 54 55 linkage( ::linkage ), … … 89 90 90 91 newnode->type = maybeClone( type ); 91 newnode->storageClass es = storageClasses;92 newnode->storageClass = storageClass; 92 93 newnode->bitfieldWidth = maybeClone( bitfieldWidth ); 93 newnode->funcSpecs = funcSpecs; 94 newnode->isInline = isInline; 95 newnode->isNoreturn = isNoreturn; 94 96 newnode->enumeratorValue.reset( maybeClone( enumeratorValue.get() ) ); 95 97 newnode->hasEllipsis = hasEllipsis; … … 116 118 } 117 119 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 } // if124 } // for125 } // if126 } // print_StorageClass127 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 } // if134 } // for135 } // if136 } // print_FuncSpec137 138 120 void DeclarationNode::print( std::ostream &os, int indent ) const { 139 121 os << string( indent, ' ' ); … … 148 130 } // if 149 131 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] << ' '; 153 135 if ( type ) { 154 136 type->print( os, indent ); … … 201 183 } // DeclarationNode::newFunction 202 184 185 DeclarationNode * 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 192 DeclarationNode * 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 203 198 204 199 DeclarationNode * DeclarationNode::newStorageClass( DeclarationNode::StorageClass sc ) { 205 200 DeclarationNode * newnode = new DeclarationNode; 206 newnode->storageClass es[ sc ] = true;201 newnode->storageClass = sc; 207 202 return newnode; 208 203 } // 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::newFuncSpecifier215 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::newQualifier222 204 223 205 DeclarationNode * DeclarationNode::newBasicType( BasicType bt ) { … … 248 230 return newnode; 249 231 } // 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::newForall257 232 258 233 DeclarationNode * DeclarationNode::newFromTypedef( string * name ) { … … 453 428 454 429 void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) { 455 const TypeData::TypeQualifiers qsrc = src->typeQualifiers, qdst = dst->typeQualifiers; // optimization430 TypeData::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization 456 431 457 432 if ( (qsrc & qdst).any() ) { // common qualifier ? 458 for ( unsigned int i = 0; i < NoTypeQualifier; i += 1 ) {// find common qualifiers433 for ( int i = 0; i < NoQualifier; i += 1 ) { // find common qualifiers 459 434 if ( qsrc[i] && qdst[i] ) { 460 appendError( error, string( "duplicate " ) + DeclarationNode:: typeQualifierNames[i] );435 appendError( error, string( "duplicate " ) + DeclarationNode::qualifierName[i] ); 461 436 } // if 462 437 } // for 463 } // for438 } // if 464 439 } // DeclarationNode::checkQualifiers 465 440 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; 441 void 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 453 DeclarationNode * 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 496 461 497 462 for ( Attribute *attr: reverseIterate( q->attributes ) ) { … … 499 464 } // for 500 465 return this; 501 } // DeclarationNode::copyS pecifiers466 } // DeclarationNode::copyStorageClasses 502 467 503 468 static void addQualifiersToType( TypeData *&src, TypeData * dst ) { … … 516 481 src = nullptr; 517 482 } else { 518 dst-> typeQualifiers |= src->typeQualifiers;483 dst->qualifiers |= src->qualifiers; 519 484 } // if 520 485 } // addQualifiersToType … … 523 488 if ( ! q ) { delete q; return this; } 524 489 525 checkS pecifiers( q );526 copyS pecifiers( q );490 checkStorageClasses( q ); 491 copyStorageClasses( q ); 527 492 528 493 if ( ! q->type ) { … … 553 518 } // if 554 519 555 checkQualifiers( type, q->type );520 checkQualifiers( q->type, type ); 556 521 addQualifiersToType( q->type, type ); 557 522 … … 574 539 switch ( dst->kind ) { 575 540 case TypeData::Unknown: 576 src-> typeQualifiers |= dst->typeQualifiers;541 src->qualifiers |= dst->qualifiers; 577 542 dst = src; 578 543 src = nullptr; 579 544 break; 580 545 case TypeData::Basic: 581 dst-> typeQualifiers |= src->typeQualifiers;546 dst->qualifiers |= src->qualifiers; 582 547 if ( src->kind != TypeData::Unknown ) { 583 548 assert( src->kind == TypeData::Basic ); … … 586 551 dst->basictype = src->basictype; 587 552 } else if ( src->basictype != DeclarationNode::NoBasicType ) 588 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::basicTypeName s[ src->basictype ] + " in type: ", src );553 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::basicTypeName[ src->basictype ] + " in type: ", src ); 589 554 590 555 if ( dst->complextype == DeclarationNode::NoComplexType ) { 591 556 dst->complextype = src->complextype; 592 557 } else if ( src->complextype != DeclarationNode::NoComplexType ) 593 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::complexTypeName s[ src->complextype ] + " in type: ", src );558 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::complexTypeName[ src->complextype ] + " in type: ", src ); 594 559 595 560 if ( dst->signedness == DeclarationNode::NoSignedness ) { 596 561 dst->signedness = src->signedness; 597 562 } else if ( src->signedness != DeclarationNode::NoSignedness ) 598 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::signednessName s[ src->signedness ] + " in type: ", src );563 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::signednessName[ src->signedness ] + " in type: ", src ); 599 564 600 565 if ( dst->length == DeclarationNode::NoLength ) { … … 603 568 dst->length = DeclarationNode::LongLong; 604 569 } else if ( src->length != DeclarationNode::NoLength ) 605 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::lengthName s[ src->length ] + " in type: ", src );570 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::lengthName[ src->length ] + " in type: ", src ); 606 571 } // if 607 572 break; … … 615 580 dst->base->aggInst.params = maybeClone( src->aggregate.actuals ); 616 581 } // if 617 dst->base-> typeQualifiers |= src->typeQualifiers;582 dst->base->qualifiers |= src->qualifiers; 618 583 src = nullptr; 619 584 break; … … 634 599 DeclarationNode * DeclarationNode::addType( DeclarationNode * o ) { 635 600 if ( o ) { 636 checkS pecifiers( o );637 copyS pecifiers( o );601 checkStorageClasses( o ); 602 copyStorageClasses( o ); 638 603 if ( o->type ) { 639 604 if ( ! type ) { … … 647 612 type->aggInst.hoistType = o->type->enumeration.body; 648 613 } // if 649 type-> typeQualifiers |= o->type->typeQualifiers;614 type->qualifiers |= o->type->qualifiers; 650 615 } else { 651 616 type = o->type; … … 803 768 p->type->base->aggInst.params = maybeClone( type->aggregate.actuals ); 804 769 } // if 805 p->type->base-> typeQualifiers |= type->typeQualifiers;770 p->type->base->qualifiers |= type->qualifiers; 806 771 break; 807 772 … … 840 805 lastArray->base->aggInst.params = maybeClone( type->aggregate.actuals ); 841 806 } // if 842 lastArray->base-> typeQualifiers |= type->typeQualifiers;807 lastArray->base->qualifiers |= type->qualifiers; 843 808 break; 844 809 default: … … 889 854 DeclarationNode * newnode = new DeclarationNode; 890 855 newnode->type = maybeClone( type ); 891 newnode->copySpecifiers( this ); 856 assert( storageClass == NoStorageClass ); 857 newnode->copyStorageClasses( this ); 892 858 assert( newName ); 893 859 newnode->name = newName; … … 898 864 if ( ! o ) return nullptr; 899 865 900 o->copyS pecifiers( this );866 o->copyStorageClasses( this ); 901 867 if ( type ) { 902 868 TypeData * srcType = type; … … 990 956 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) { 991 957 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 ); 993 959 obj->location = cur->location; 994 960 * out++ = obj; … … 996 962 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) { 997 963 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 ); 999 965 obj->location = cur->location; 1000 966 * out++ = obj; … … 1039 1005 } // if 1040 1006 1007 // if ( variable.name ) { 1041 1008 if ( variable.tyClass != NoTypeClass ) { 1042 1009 static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype }; 1043 1010 assertf( sizeof(kindMap)/sizeof(kindMap[0] == NoTypeClass-1), "DeclarationNode::build: kindMap is out of sync." ); 1044 1011 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 ] ); 1046 1014 buildList( variable.assertions, ret->get_assertions() ); 1047 1015 return ret; … … 1049 1017 1050 1018 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 ); 1071 1028 } 1072 1029 … … 1075 1032 1076 1033 if ( attr.expr ) { 1034 // return new AttrType( buildQualifiers( type ), *attr.name, attr.expr->build() ); 1077 1035 return new AttrType( buildQualifiers( type ), *name, attr.expr->build(), attributes ); 1078 1036 } else if ( attr.type ) { 1037 // return new AttrType( buildQualifiers( type ), *attr.name, attr.type->buildType() ); 1079 1038 return new AttrType( buildQualifiers( type ), *name, attr.type->buildType(), attributes ); 1080 1039 } // if
Note:
See TracChangeset
for help on using the changeset viewer.