Changes in src/Parser/DeclarationNode.cc [f2f512ba:5fcba14]
- File:
-
- 1 edited
-
src/Parser/DeclarationNode.cc (modified) (38 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
rf2f512ba r5fcba14 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 20 14:56:54 201813 // Update Count : 1 10712 // Last Modified On : Mon Nov 20 09:21:52 2017 13 // Update Count : 1031 14 14 // 15 15 … … 32 32 #include "SynTree/Type.h" // for Type, Type::StorageClasses, Type::... 33 33 #include "TypeData.h" // for TypeData, TypeData::Aggregate_t 34 #include "TypedefTable.h" // for TypedefTable 34 #include "TypedefTable.h" // for TypedefTable, TypedefTable::kind_t... 35 35 36 36 class Initializer; … … 47 47 const char * DeclarationNode::aggregateNames[] = { "struct", "union", "trait", "coroutine", "monitor", "thread", "NoAggregateNames" }; 48 48 const char * DeclarationNode::typeClassNames[] = { "otype", "dtype", "ftype", "NoTypeClassNames" }; 49 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", " zero_t", "one_t", "NoBuiltinTypeNames" };49 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "NoBuiltinTypeNames" }; 50 50 51 51 UniqueName DeclarationNode::anonymous( "__anonymous" ); … … 54 54 55 55 DeclarationNode::DeclarationNode() : 56 linkage( ::linkage ) { 56 type( nullptr ), 57 bitfieldWidth( nullptr ), 58 hasEllipsis( false ), 59 linkage( ::linkage ), 60 asmName( nullptr ), 61 initializer( nullptr ), 62 extension( false ), 63 asmStmt( nullptr ) { 57 64 58 65 // variable.name = nullptr; … … 64 71 attr.expr = nullptr; 65 72 attr.type = nullptr; 66 67 assert.condition = nullptr;68 assert.message = nullptr;69 73 } 70 74 … … 84 88 // asmName, no delete, passed to next stage 85 89 delete initializer; 86 87 delete assert.condition;88 delete assert.message;89 90 } 90 91 … … 94 95 newnode->name = name ? new string( *name ) : nullptr; 95 96 96 newnode->builtin = NoBuiltinType;97 97 newnode->type = maybeClone( type ); 98 newnode->inLine = inLine;99 98 newnode->storageClasses = storageClasses; 100 99 newnode->funcSpecs = funcSpecs; … … 118 117 newnode->attr.expr = maybeClone( attr.expr ); 119 118 newnode->attr.type = maybeClone( attr.type ); 120 121 newnode->assert.condition = maybeClone( assert.condition );122 newnode->assert.message = maybeClone( assert.message );123 119 return newnode; 124 120 } // DeclarationNode::clone 125 121 126 void DeclarationNode::print( std::ostream & os, int indent ) const { 122 bool DeclarationNode::get_hasEllipsis() const { 123 return hasEllipsis; 124 } 125 126 void DeclarationNode::print( std::ostream &os, int indent ) const { 127 127 os << string( indent, ' ' ); 128 128 if ( name ) { … … 160 160 } 161 161 162 void DeclarationNode::printList( std::ostream & os, int indent ) const {162 void DeclarationNode::printList( std::ostream &os, int indent ) const { 163 163 ParseNode::printList( os, indent ); 164 164 if ( hasEllipsis ) { … … 167 167 } 168 168 169 DeclarationNode * DeclarationNode::newFunction( const string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body) {169 DeclarationNode * DeclarationNode::newFunction( string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body, bool newStyle ) { 170 170 DeclarationNode * newnode = new DeclarationNode; 171 171 newnode->name = name; 172 172 newnode->type = new TypeData( TypeData::Function ); 173 173 newnode->type->function.params = param; 174 newnode->type->function.newStyle = newStyle; 174 175 newnode->type->function.body = body; 176 177 // ignore unnamed routine declarations: void p( int (*)(int) ); 178 if ( newnode->name ) { 179 typedefTable.addToEnclosingScope( *newnode->name, TypedefTable::ID ); 180 } // if 175 181 176 182 if ( ret ) { … … 238 244 } // DeclarationNode::newForall 239 245 240 DeclarationNode * DeclarationNode::newFromTypedef( conststring * name ) {246 DeclarationNode * DeclarationNode::newFromTypedef( string * name ) { 241 247 DeclarationNode * newnode = new DeclarationNode; 242 248 newnode->type = new TypeData( TypeData::SymbolicInst ); … … 247 253 } // DeclarationNode::newFromTypedef 248 254 249 DeclarationNode * DeclarationNode::newFromGlobalScope() {250 DeclarationNode * newnode = new DeclarationNode;251 newnode->type = new TypeData( TypeData::GlobalScope );252 return newnode;253 }254 255 DeclarationNode * DeclarationNode::newQualifiedType( DeclarationNode * parent, DeclarationNode * child) {256 DeclarationNode * newnode = new DeclarationNode;257 newnode->type = new TypeData( TypeData::Qualified );258 newnode->type->qualified.parent = parent->type;259 newnode->type->qualified.child = child->type;260 parent->type = nullptr;261 child->type = nullptr;262 delete parent;263 delete child;264 return newnode;265 }266 267 255 DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) { 256 assert( name ); 268 257 DeclarationNode * newnode = new DeclarationNode; 269 258 newnode->type = new TypeData( TypeData::Aggregate ); 270 259 newnode->type->aggregate.kind = kind; 271 newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) :name;260 newnode->type->aggregate.name = name; 272 261 newnode->type->aggregate.actuals = actuals; 273 262 newnode->type->aggregate.fields = fields; … … 275 264 newnode->type->aggregate.tagged = false; 276 265 newnode->type->aggregate.parent = nullptr; 277 newnode->type->aggregate.anon = name == nullptr;278 266 return newnode; 279 267 } // DeclarationNode::newAggregate 280 268 281 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body ) { 269 DeclarationNode * DeclarationNode::newEnum( string * name, DeclarationNode * constants, bool body ) { 270 assert( name ); 282 271 DeclarationNode * newnode = new DeclarationNode; 283 272 newnode->type = new TypeData( TypeData::Enum ); 284 newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;273 newnode->type->enumeration.name = name; 285 274 newnode->type->enumeration.constants = constants; 286 275 newnode->type->enumeration.body = body; 287 newnode->type->enumeration.anon = name == nullptr;288 276 return newnode; 289 277 } // DeclarationNode::newEnum 290 278 291 DeclarationNode * DeclarationNode::newEnumConstant( conststring * name, ExpressionNode * constant ) {279 DeclarationNode * DeclarationNode::newEnumConstant( string * name, ExpressionNode * constant ) { 292 280 DeclarationNode * newnode = new DeclarationNode; 293 281 newnode->name = name; 294 282 newnode->enumeratorValue.reset( constant ); 283 typedefTable.addToEnclosingScope( *newnode->name, TypedefTable::ID ); 295 284 return newnode; 296 285 } // DeclarationNode::newEnumConstant 297 286 298 DeclarationNode * DeclarationNode::newName( conststring * name ) {287 DeclarationNode * DeclarationNode::newName( string * name ) { 299 288 DeclarationNode * newnode = new DeclarationNode; 300 289 newnode->name = name; … … 302 291 } // DeclarationNode::newName 303 292 304 DeclarationNode * DeclarationNode::newFromTypeGen( conststring * name, ExpressionNode * params ) {293 DeclarationNode * DeclarationNode::newFromTypeGen( string * name, ExpressionNode * params ) { 305 294 DeclarationNode * newnode = new DeclarationNode; 306 295 newnode->type = new TypeData( TypeData::SymbolicInst ); … … 311 300 } // DeclarationNode::newFromTypeGen 312 301 313 DeclarationNode * DeclarationNode::newTypeParam( TypeClass tc, conststring * name ) {302 DeclarationNode * DeclarationNode::newTypeParam( TypeClass tc, string * name ) { 314 303 DeclarationNode * newnode = new DeclarationNode; 315 304 newnode->type = nullptr; … … 342 331 } // DeclarationNode::newTraitUse 343 332 344 DeclarationNode * DeclarationNode::newTypeDecl( conststring * name, DeclarationNode * typeParams ) {333 DeclarationNode * DeclarationNode::newTypeDecl( string * name, DeclarationNode * typeParams ) { 345 334 DeclarationNode * newnode = new DeclarationNode; 346 335 newnode->name = name; … … 354 343 DeclarationNode * newnode = new DeclarationNode; 355 344 newnode->type = new TypeData( kind == OperKinds::PointTo ? TypeData::Pointer : TypeData::Reference ); 356 if ( kind == OperKinds::And ) {357 // T && is parsed as 'And' operator rather than two references => add a second reference type358 TypeData * td = new TypeData( TypeData::Reference );359 td->base = newnode->type;360 newnode->type = td;361 }362 345 if ( qualifiers ) { 363 346 return newnode->addQualifiers( qualifiers ); … … 417 400 } // DeclarationNode::newBuiltinType 418 401 419 DeclarationNode * DeclarationNode::newAttr( conststring * name, ExpressionNode * expr ) {402 DeclarationNode * DeclarationNode::newAttr( string * name, ExpressionNode * expr ) { 420 403 DeclarationNode * newnode = new DeclarationNode; 421 404 newnode->type = nullptr; … … 426 409 } 427 410 428 DeclarationNode * DeclarationNode::newAttr( conststring * name, DeclarationNode * type ) {411 DeclarationNode * DeclarationNode::newAttr( string * name, DeclarationNode * type ) { 429 412 DeclarationNode * newnode = new DeclarationNode; 430 413 newnode->type = nullptr; … … 435 418 } 436 419 437 DeclarationNode * DeclarationNode::newAttribute( conststring * name, ExpressionNode * expr ) {420 DeclarationNode * DeclarationNode::newAttribute( string * name, ExpressionNode * expr ) { 438 421 DeclarationNode * newnode = new DeclarationNode; 439 422 newnode->type = nullptr; … … 450 433 return newnode; 451 434 } 452 453 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) {454 DeclarationNode * newnode = new DeclarationNode;455 newnode->assert.condition = condition;456 newnode->assert.message = message;457 return newnode;458 }459 460 435 461 436 void appendError( string & dst, const string & src ) { … … 514 489 } // DeclarationNode::copySpecifiers 515 490 516 static void addQualifiersToType( TypeData *& src, TypeData * dst ) { 491 static void addQualifiersToType( TypeData *&src, TypeData * dst ) { 492 if ( src->forall && dst->kind == TypeData::Function ) { 493 if ( dst->forall ) { 494 dst->forall->appendList( src->forall ); 495 } else { 496 dst->forall = src->forall; 497 } // if 498 src->forall = nullptr; 499 } // if 517 500 if ( dst->base ) { 518 501 addQualifiersToType( src, dst->base ); … … 526 509 527 510 DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode * q ) { 528 if ( ! q ) { return this; }// empty qualifier511 if ( ! q ) { delete q; return this; } // empty qualifier 529 512 530 513 checkSpecifiers( q ); … … 548 531 type->aggregate.params->appendList( q->type->forall ); // augment forall qualifier 549 532 } else { // not polymorphic 550 type->aggregate.params = q->type->forall; // set forall qualifier 533 type->aggregate.params = q->type->forall; // make polymorphic type 534 // change implicit typedef from TYPEDEFname to TYPEGENname 535 typedefTable.changeKind( *type->aggregate.name, TypedefTable::TG ); 551 536 } // if 552 537 } else { // not polymorphic … … 558 543 559 544 checkQualifiers( type, q->type ); 560 if ( (builtin == Zero || builtin == One) && q->type->qualifiers.val != 0 && error.length() == 0 ) {561 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, Type::QualifiersNames[ilog2( q->type->qualifiers.val )], builtinTypeNames[builtin] );562 } // if563 545 addQualifiersToType( q->type, type ); 564 546 … … 567 549 } // addQualifiers 568 550 569 static void addTypeToType( TypeData *& src, TypeData *&dst ) {551 static void addTypeToType( TypeData *&src, TypeData *&dst ) { 570 552 if ( src->forall && dst->kind == TypeData::Function ) { 571 553 if ( dst->forall ) { … … 593 575 dst->basictype = src->basictype; 594 576 } else if ( src->basictype != DeclarationNode::NoBasicType ) 595 SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::basicTypeNames[ src->basictype ] + " in type: ");577 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::basicTypeNames[ src->basictype ] + " in type: ", src ); 596 578 597 579 if ( dst->complextype == DeclarationNode::NoComplexType ) { 598 580 dst->complextype = src->complextype; 599 581 } else if ( src->complextype != DeclarationNode::NoComplexType ) 600 SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::complexTypeNames[ src->complextype ] + " in type: ");582 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::complexTypeNames[ src->complextype ] + " in type: ", src ); 601 583 602 584 if ( dst->signedness == DeclarationNode::NoSignedness ) { 603 585 dst->signedness = src->signedness; 604 586 } else if ( src->signedness != DeclarationNode::NoSignedness ) 605 SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::signednessNames[ src->signedness ] + " in type: ");587 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::signednessNames[ src->signedness ] + " in type: ", src ); 606 588 607 589 if ( dst->length == DeclarationNode::NoLength ) { … … 610 592 dst->length = DeclarationNode::LongLong; 611 593 } else if ( src->length != DeclarationNode::NoLength ) 612 SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::lengthNames[ src->length ] + " in type: ");594 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::lengthNames[ src->length ] + " in type: ", src ); 613 595 } // if 614 596 break; … … 735 717 } 736 718 737 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, ExpressionNode * withExprs) {719 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, StatementNode * with ) { 738 720 assert( type ); 739 721 assert( type->kind == TypeData::Function ); 740 722 assert( ! type->function.body ); 723 if ( with ) { 724 // convert 725 // void f(S s) with (s) { x = 0; } 726 // to 727 // void f(S s) { with(s) { x = 0; } } 728 WithStmt * withStmt = strict_dynamic_cast< WithStmt * >( with->build() ); 729 withStmt->stmt = body->build(); 730 delete body; 731 delete with; 732 body = new StatementNode( new CompoundStmt( { withStmt } ) ); 733 } 741 734 type->function.body = body; 742 type->function.withExprs = withExprs;743 735 return this; 744 736 } … … 779 771 DeclarationNode * DeclarationNode::addPointer( DeclarationNode * p ) { 780 772 if ( p ) { 781 assert( p->type->kind == TypeData::Pointer || p->type->kind ==TypeData::Reference );773 assert( p->type->kind == TypeData::Pointer || TypeData::Reference ); 782 774 setBase( p->type ); 783 775 p->type = nullptr; … … 924 916 delete newType->aggInst.aggregate->enumeration.constants; 925 917 newType->aggInst.aggregate->enumeration.constants = nullptr; 926 newType->aggInst.aggregate->enumeration.body = false;927 918 } else { 928 919 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate ); 929 920 delete newType->aggInst.aggregate->aggregate.fields; 930 921 newType->aggInst.aggregate->aggregate.fields = nullptr; 931 newType->aggInst.aggregate->aggregate.body = false;932 922 } // if 933 923 // don't hoist twice … … 958 948 } 959 949 960 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) {961 SemanticError Exceptionerrors;950 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList ) { 951 SemanticError errors; 962 952 std::back_insert_iterator< std::list< Declaration * > > out( outputList ); 963 953 964 954 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 965 955 try { 966 bool extracted = false;967 bool anon = false;968 956 if ( DeclarationNode * extr = cur->extractAggregate() ) { 969 957 // handle the case where a structure declaration is contained within an object or type declaration 970 958 Declaration * decl = extr->build(); 971 959 if ( decl ) { 972 // hoist the structure declaration973 960 decl->location = cur->location; 974 961 * out++ = decl; 975 976 // need to remember the cases where a declaration contains an anonymous aggregate definition977 extracted = true;978 assert( extr->type );979 if ( extr->type->kind == TypeData::Aggregate ) {980 anon = extr->type->aggregate.anon;981 } else if ( extr->type->kind == TypeData::Enum ) {982 // xxx - is it useful to have an implicit anonymous enum member?983 anon = extr->type->enumeration.anon;984 }985 962 } // if 986 963 delete extr; … … 989 966 Declaration * decl = cur->build(); 990 967 if ( decl ) { 991 // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.: 992 // struct S { 993 // struct T { int x; }; // no anonymous member 994 // struct { int y; }; // anonymous member 995 // struct T; // anonymous member 996 // }; 997 if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) { 998 if ( decl->name == "" ) { 999 if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) { 1000 if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType *>( dwt->get_type() ) ) { 1001 if ( aggr->name.find("anonymous") == std::string::npos ) { 1002 if ( ! cur->get_inLine() ) { 1003 // temporary: warn about anonymous member declarations of named types, since 1004 // this conflicts with the syntax for the forward declaration of an anonymous type 1005 SemanticWarning( cur->location, Warning::AggrForwardDecl, aggr->name.c_str() ); 1006 } // if 1007 } // if 1008 } // if 1009 } // if 1010 } // if 1011 decl->location = cur->location; 1012 *out++ = decl; 968 decl->location = cur->location; 969 * out++ = decl; 970 } // if 971 } catch( SemanticError &e ) { 972 e.set_location( cur->location ); 973 errors.append( e ); 974 } // try 975 } // while 976 977 if ( ! errors.isEmpty() ) { 978 throw errors; 979 } // if 980 } // buildList 981 982 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList ) { 983 SemanticError errors; 984 std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList ); 985 986 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 987 try { 988 Declaration * decl = cur->build(); 989 if ( decl ) { 990 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 991 dwt->location = cur->location; 992 * out++ = dwt; 993 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) { 994 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->get_name() ); 995 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 996 obj->location = cur->location; 997 * out++ = obj; 998 delete agg; 999 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) { 1000 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->get_name() ); 1001 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1002 obj->location = cur->location; 1003 * out++ = obj; 1013 1004 } // if 1014 1005 } // if 1015 } catch( SemanticErrorException & e ) { 1006 } catch( SemanticError &e ) { 1007 e.set_location( cur->location ); 1016 1008 errors.append( e ); 1017 1009 } // try … … 1023 1015 } // buildList 1024 1016 1025 // currently only builds assertions, function parameters, and return values 1026 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) { 1027 SemanticErrorException errors; 1028 std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList ); 1029 1030 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 1031 try { 1032 Declaration * decl = cur->build(); 1033 assert( decl ); 1034 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 1035 dwt->location = cur->location; 1036 * out++ = dwt; 1037 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) { 1038 // e.g., int foo(struct S) {} 1039 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name ); 1040 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1041 obj->location = cur->location; 1042 * out++ = obj; 1043 delete agg; 1044 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) { 1045 // e.g., int foo(union U) {} 1046 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name ); 1047 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1048 obj->location = cur->location; 1049 * out++ = obj; 1050 } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) { 1051 // e.g., int foo(enum E) {} 1052 EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name ); 1053 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1054 obj->location = cur->location; 1055 * out++ = obj; 1056 } // if 1057 } catch( SemanticErrorException & e ) { 1058 errors.append( e ); 1059 } // try 1060 } // for 1061 1062 if ( ! errors.isEmpty() ) { 1063 throw errors; 1064 } // if 1065 } // buildList 1066 1067 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) { 1068 SemanticErrorException errors; 1017 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList ) { 1018 SemanticError errors; 1069 1019 std::back_insert_iterator< std::list< Type * > > out( outputList ); 1070 1020 const DeclarationNode * cur = firstNode; … … 1073 1023 try { 1074 1024 * out++ = cur->buildType(); 1075 } catch( SemanticErrorException & e ) { 1025 } catch( SemanticError &e ) { 1026 e.set_location( cur->location ); 1076 1027 errors.append( e ); 1077 1028 } // try … … 1085 1036 1086 1037 Declaration * DeclarationNode::build() const { 1087 if ( ! error.empty() ) SemanticError( this, error + " in declaration of ");1038 if ( ! error.empty() ) throw SemanticError( error + " in declaration of ", this ); 1088 1039 1089 1040 if ( asmStmt ) { … … 1108 1059 // inline _Noreturn int i; // disallowed 1109 1060 if ( type->kind != TypeData::Function && funcSpecs.any() ) { 1110 SemanticError( this, "invalid function specifier for " ); 1111 } // if 1112 // Forall qualifier can only appear on a function/aggregate definition/declaration. 1113 // 1114 // forall int f(); // allowed 1115 // forall int g( int i ); // allowed 1116 // forall int i; // disallowed 1117 if ( type->kind != TypeData::Function && type->forall ) { 1118 SemanticError( this, "invalid type qualifier for " ); 1119 } // if 1120 bool isDelete = initializer && initializer->get_isDelete(); 1121 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension ); 1122 if ( isDelete ) { 1123 DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl ); 1124 dwt->isDeleted = true; 1125 } 1126 return decl; 1127 } // if 1128 1129 if ( assert.condition ) { 1130 return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) ); 1131 } 1061 throw SemanticError( "invalid function specifier for ", this ); 1062 } // if 1063 return buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, maybeBuild< Initializer >(initializer), attributes )->set_extension( extension ); 1064 } // if 1132 1065 1133 1066 // SUE's cannot have function specifiers, either … … 1136 1069 // inlne _Noreturn enum E { ... }; // disallowed 1137 1070 if ( funcSpecs.any() ) { 1138 SemanticError( this, "invalid function specifier for ");1071 throw SemanticError( "invalid function specifier for ", this ); 1139 1072 } // if 1140 1073 assertf( name, "ObjectDecl must a have name\n" );
Note:
See TracChangeset
for help on using the changeset viewer.