Changeset 90152a4 for src/Parser/DeclarationNode.cc
- Timestamp:
- Aug 27, 2018, 4:40:34 PM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- b7c89aa
- Parents:
- f9feab8 (diff), 305581d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
rf9feab8 r90152a4 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Nov 20 09:21:52 201713 // Update Count : 1 03112 // Last Modified On : Fri Jul 20 14:56:54 2018 13 // Update Count : 1107 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 , TypedefTable::kind_t...34 #include "TypedefTable.h" // for TypedefTable 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", " NoBuiltinTypeNames" };49 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "zero_t", "one_t", "NoBuiltinTypeNames" }; 50 50 51 51 UniqueName DeclarationNode::anonymous( "__anonymous" ); … … 54 54 55 55 DeclarationNode::DeclarationNode() : 56 type( nullptr ), 57 bitfieldWidth( nullptr ), 58 hasEllipsis( false ), 59 linkage( ::linkage ), 60 asmName( nullptr ), 61 initializer( nullptr ), 62 extension( false ), 63 asmStmt( nullptr ) { 56 linkage( ::linkage ) { 64 57 65 58 // variable.name = nullptr; … … 71 64 attr.expr = nullptr; 72 65 attr.type = nullptr; 66 67 assert.condition = nullptr; 68 assert.message = nullptr; 73 69 } 74 70 … … 88 84 // asmName, no delete, passed to next stage 89 85 delete initializer; 86 87 delete assert.condition; 88 delete assert.message; 90 89 } 91 90 … … 95 94 newnode->name = name ? new string( *name ) : nullptr; 96 95 96 newnode->builtin = NoBuiltinType; 97 97 newnode->type = maybeClone( type ); 98 newnode->inLine = inLine; 98 99 newnode->storageClasses = storageClasses; 99 100 newnode->funcSpecs = funcSpecs; … … 117 118 newnode->attr.expr = maybeClone( attr.expr ); 118 119 newnode->attr.type = maybeClone( attr.type ); 120 121 newnode->assert.condition = maybeClone( assert.condition ); 122 newnode->assert.message = maybeClone( assert.message ); 119 123 return newnode; 120 124 } // DeclarationNode::clone 121 125 122 bool DeclarationNode::get_hasEllipsis() const { 123 return hasEllipsis; 124 } 125 126 void DeclarationNode::print( std::ostream &os, int indent ) const { 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( string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body, bool newStyle) {169 DeclarationNode * DeclarationNode::newFunction( const string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ) { 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;175 174 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 } // if181 175 182 176 if ( ret ) { … … 244 238 } // DeclarationNode::newForall 245 239 246 DeclarationNode * DeclarationNode::newFromTypedef( string * name ) {240 DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) { 247 241 DeclarationNode * newnode = new DeclarationNode; 248 242 newnode->type = new TypeData( TypeData::SymbolicInst ); … … 253 247 } // DeclarationNode::newFromTypedef 254 248 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 255 267 DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) { 256 assert( name );257 268 DeclarationNode * newnode = new DeclarationNode; 258 269 newnode->type = new TypeData( TypeData::Aggregate ); 259 270 newnode->type->aggregate.kind = kind; 260 newnode->type->aggregate.name = name;271 newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 261 272 newnode->type->aggregate.actuals = actuals; 262 273 newnode->type->aggregate.fields = fields; … … 264 275 newnode->type->aggregate.tagged = false; 265 276 newnode->type->aggregate.parent = nullptr; 277 newnode->type->aggregate.anon = name == nullptr; 266 278 return newnode; 267 279 } // DeclarationNode::newAggregate 268 280 269 DeclarationNode * DeclarationNode::newEnum( string * name, DeclarationNode * constants, bool body ) { 270 assert( name ); 281 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body ) { 271 282 DeclarationNode * newnode = new DeclarationNode; 272 283 newnode->type = new TypeData( TypeData::Enum ); 273 newnode->type->enumeration.name = name ;284 newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 274 285 newnode->type->enumeration.constants = constants; 275 286 newnode->type->enumeration.body = body; 287 newnode->type->enumeration.anon = name == nullptr; 276 288 return newnode; 277 289 } // DeclarationNode::newEnum 278 290 279 DeclarationNode * DeclarationNode::newEnumConstant( string * name, ExpressionNode * constant ) {291 DeclarationNode * DeclarationNode::newEnumConstant( const string * name, ExpressionNode * constant ) { 280 292 DeclarationNode * newnode = new DeclarationNode; 281 293 newnode->name = name; 282 294 newnode->enumeratorValue.reset( constant ); 283 typedefTable.addToEnclosingScope( *newnode->name, TypedefTable::ID );284 295 return newnode; 285 296 } // DeclarationNode::newEnumConstant 286 297 287 DeclarationNode * DeclarationNode::newName( string * name ) {298 DeclarationNode * DeclarationNode::newName( const string * name ) { 288 299 DeclarationNode * newnode = new DeclarationNode; 289 300 newnode->name = name; … … 291 302 } // DeclarationNode::newName 292 303 293 DeclarationNode * DeclarationNode::newFromTypeGen( string * name, ExpressionNode * params ) {304 DeclarationNode * DeclarationNode::newFromTypeGen( const string * name, ExpressionNode * params ) { 294 305 DeclarationNode * newnode = new DeclarationNode; 295 306 newnode->type = new TypeData( TypeData::SymbolicInst ); … … 300 311 } // DeclarationNode::newFromTypeGen 301 312 302 DeclarationNode * DeclarationNode::newTypeParam( TypeClass tc, string * name ) {313 DeclarationNode * DeclarationNode::newTypeParam( TypeClass tc, const string * name ) { 303 314 DeclarationNode * newnode = new DeclarationNode; 304 315 newnode->type = nullptr; … … 331 342 } // DeclarationNode::newTraitUse 332 343 333 DeclarationNode * DeclarationNode::newTypeDecl( string * name, DeclarationNode * typeParams ) {344 DeclarationNode * DeclarationNode::newTypeDecl( const string * name, DeclarationNode * typeParams ) { 334 345 DeclarationNode * newnode = new DeclarationNode; 335 346 newnode->name = name; … … 343 354 DeclarationNode * newnode = new DeclarationNode; 344 355 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 type 358 TypeData * td = new TypeData( TypeData::Reference ); 359 td->base = newnode->type; 360 newnode->type = td; 361 } 345 362 if ( qualifiers ) { 346 363 return newnode->addQualifiers( qualifiers ); … … 400 417 } // DeclarationNode::newBuiltinType 401 418 402 DeclarationNode * DeclarationNode::newAttr( string * name, ExpressionNode * expr ) {419 DeclarationNode * DeclarationNode::newAttr( const string * name, ExpressionNode * expr ) { 403 420 DeclarationNode * newnode = new DeclarationNode; 404 421 newnode->type = nullptr; … … 409 426 } 410 427 411 DeclarationNode * DeclarationNode::newAttr( string * name, DeclarationNode * type ) {428 DeclarationNode * DeclarationNode::newAttr( const string * name, DeclarationNode * type ) { 412 429 DeclarationNode * newnode = new DeclarationNode; 413 430 newnode->type = nullptr; … … 418 435 } 419 436 420 DeclarationNode * DeclarationNode::newAttribute( string * name, ExpressionNode * expr ) {437 DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) { 421 438 DeclarationNode * newnode = new DeclarationNode; 422 439 newnode->type = nullptr; … … 433 450 return newnode; 434 451 } 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 435 460 436 461 void appendError( string & dst, const string & src ) { … … 489 514 } // DeclarationNode::copySpecifiers 490 515 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 516 static void addQualifiersToType( TypeData *& src, TypeData * dst ) { 500 517 if ( dst->base ) { 501 518 addQualifiersToType( src, dst->base ); … … 509 526 510 527 DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode * q ) { 511 if ( ! q ) { delete q; return this; }// empty qualifier528 if ( ! q ) { return this; } // empty qualifier 512 529 513 530 checkSpecifiers( q ); … … 531 548 type->aggregate.params->appendList( q->type->forall ); // augment forall qualifier 532 549 } else { // not polymorphic 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 ); 550 type->aggregate.params = q->type->forall; // set forall qualifier 536 551 } // if 537 552 } else { // not polymorphic … … 543 558 544 559 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 } // if 545 563 addQualifiersToType( q->type, type ); 546 564 … … 549 567 } // addQualifiers 550 568 551 static void addTypeToType( TypeData *& src, TypeData *&dst ) {569 static void addTypeToType( TypeData *& src, TypeData *& dst ) { 552 570 if ( src->forall && dst->kind == TypeData::Function ) { 553 571 if ( dst->forall ) { … … 575 593 dst->basictype = src->basictype; 576 594 } else if ( src->basictype != DeclarationNode::NoBasicType ) 577 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::basicTypeNames[ src->basictype ] + " in type: ", src);595 SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::basicTypeNames[ src->basictype ] + " in type: " ); 578 596 579 597 if ( dst->complextype == DeclarationNode::NoComplexType ) { 580 598 dst->complextype = src->complextype; 581 599 } else if ( src->complextype != DeclarationNode::NoComplexType ) 582 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::complexTypeNames[ src->complextype ] + " in type: ", src);600 SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::complexTypeNames[ src->complextype ] + " in type: " ); 583 601 584 602 if ( dst->signedness == DeclarationNode::NoSignedness ) { 585 603 dst->signedness = src->signedness; 586 604 } else if ( src->signedness != DeclarationNode::NoSignedness ) 587 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::signednessNames[ src->signedness ] + " in type: ", src);605 SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::signednessNames[ src->signedness ] + " in type: " ); 588 606 589 607 if ( dst->length == DeclarationNode::NoLength ) { … … 592 610 dst->length = DeclarationNode::LongLong; 593 611 } else if ( src->length != DeclarationNode::NoLength ) 594 throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::lengthNames[ src->length ] + " in type: ", src);612 SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::lengthNames[ src->length ] + " in type: " ); 595 613 } // if 596 614 break; … … 717 735 } 718 736 719 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, StatementNode * with) {737 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, ExpressionNode * withExprs ) { 720 738 assert( type ); 721 739 assert( type->kind == TypeData::Function ); 722 740 assert( ! type->function.body ); 723 if ( with ) {724 // convert725 // void f(S s) with (s) { x = 0; }726 // to727 // 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 }734 741 type->function.body = body; 742 type->function.withExprs = withExprs; 735 743 return this; 736 744 } … … 771 779 DeclarationNode * DeclarationNode::addPointer( DeclarationNode * p ) { 772 780 if ( p ) { 773 assert( p->type->kind == TypeData::Pointer || TypeData::Reference );781 assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference ); 774 782 setBase( p->type ); 775 783 p->type = nullptr; … … 916 924 delete newType->aggInst.aggregate->enumeration.constants; 917 925 newType->aggInst.aggregate->enumeration.constants = nullptr; 926 newType->aggInst.aggregate->enumeration.body = false; 918 927 } else { 919 928 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate ); 920 929 delete newType->aggInst.aggregate->aggregate.fields; 921 930 newType->aggInst.aggregate->aggregate.fields = nullptr; 931 newType->aggInst.aggregate->aggregate.body = false; 922 932 } // if 923 933 // don't hoist twice … … 948 958 } 949 959 950 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) {951 SemanticError errors;960 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) { 961 SemanticErrorException errors; 952 962 std::back_insert_iterator< std::list< Declaration * > > out( outputList ); 953 963 954 964 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 955 965 try { 966 bool extracted = false; 967 bool anon = false; 956 968 if ( DeclarationNode * extr = cur->extractAggregate() ) { 957 969 // handle the case where a structure declaration is contained within an object or type declaration 958 970 Declaration * decl = extr->build(); 959 971 if ( decl ) { 972 // hoist the structure declaration 960 973 decl->location = cur->location; 961 974 * out++ = decl; 975 976 // need to remember the cases where a declaration contains an anonymous aggregate definition 977 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 } 962 985 } // if 963 986 delete extr; … … 966 989 Declaration * decl = cur->build(); 967 990 if ( decl ) { 968 decl->location = cur->location; 969 * out++ = 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; 1013 } // if 970 1014 } // if 971 } catch( SemanticError &e ) { 972 e.set_location( cur->location ); 1015 } catch( SemanticErrorException & e ) { 973 1016 errors.append( e ); 974 1017 } // try 975 } // while1018 } // for 976 1019 977 1020 if ( ! errors.isEmpty() ) { … … 980 1023 } // buildList 981 1024 982 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList ) { 983 SemanticError errors; 1025 // currently only builds assertions, function parameters, and return values 1026 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) { 1027 SemanticErrorException errors; 984 1028 std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList ); 985 1029 … … 987 1031 try { 988 1032 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; 1004 } // if 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; 1005 1056 } // if 1006 } catch( SemanticError &e ) { 1007 e.set_location( cur->location ); 1057 } catch( SemanticErrorException & e ) { 1008 1058 errors.append( e ); 1009 1059 } // try … … 1015 1065 } // buildList 1016 1066 1017 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) {1018 SemanticError errors;1067 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) { 1068 SemanticErrorException errors; 1019 1069 std::back_insert_iterator< std::list< Type * > > out( outputList ); 1020 1070 const DeclarationNode * cur = firstNode; … … 1023 1073 try { 1024 1074 * out++ = cur->buildType(); 1025 } catch( SemanticError &e ) { 1026 e.set_location( cur->location ); 1075 } catch( SemanticErrorException & e ) { 1027 1076 errors.append( e ); 1028 1077 } // try … … 1036 1085 1037 1086 Declaration * DeclarationNode::build() const { 1038 if ( ! error.empty() ) throw SemanticError( error + " in declaration of ", this);1087 if ( ! error.empty() ) SemanticError( this, error + " in declaration of " ); 1039 1088 1040 1089 if ( asmStmt ) { … … 1059 1108 // inline _Noreturn int i; // disallowed 1060 1109 if ( type->kind != TypeData::Function && funcSpecs.any() ) { 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 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 } 1065 1132 1066 1133 // SUE's cannot have function specifiers, either … … 1069 1136 // inlne _Noreturn enum E { ... }; // disallowed 1070 1137 if ( funcSpecs.any() ) { 1071 throw SemanticError( "invalid function specifier for ", this);1138 SemanticError( this, "invalid function specifier for " ); 1072 1139 } // if 1073 1140 assertf( name, "ObjectDecl must a have name\n" );
Note:
See TracChangeset
for help on using the changeset viewer.