Changes in / [aeec6b7:97be800]
- Location:
- src
- Files:
-
- 4 deleted
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
raeec6b7 r97be800 164 164 previsit( (BaseSyntaxNode *)node ); 165 165 GuardAction( [this, node](){ 166 if ( printExprTypes && node->result) {166 if ( printExprTypes ) { 167 167 output << " /* " << genType( node->result, "", pretty, genC ) << " */ "; 168 168 } … … 224 224 225 225 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) { 226 if( ! aggDecl-> parameters.empty() && ! genC ) {226 if( ! aggDecl->get_parameters().empty() && ! genC ) { 227 227 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 228 228 output << "forall("; 229 genCommaList( aggDecl-> parameters.begin(), aggDecl->parameters.end() );229 genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() ); 230 230 output << ")" << endl; 231 231 output << indent; … … 233 233 234 234 output << kind; 235 genAttributes( aggDecl-> attributes);236 output << aggDecl-> name;235 genAttributes( aggDecl->get_attributes() ); 236 output << aggDecl->get_name(); 237 237 238 238 if ( aggDecl->has_body() ) { 239 std::list< Declaration * > & memb = aggDecl-> members;239 std::list< Declaration * > & memb = aggDecl->get_members(); 240 240 output << " {" << endl; 241 241 -
src/CodeGen/GenType.cc
raeec6b7 r97be800 48 48 void postvisit( ZeroType * zeroType ); 49 49 void postvisit( OneType * oneType ); 50 void postvisit( GlobalScopeType * globalType );51 50 void postvisit( TraitInstType * inst ); 52 51 void postvisit( TypeofType * typeof ); 53 void postvisit( QualifiedType * qualType );54 52 55 53 private: … … 293 291 } 294 292 295 void GenType::postvisit( GlobalScopeType * globalType ) {296 assertf( ! genC, "Global scope type should not reach code generation." );297 handleQualifiers( globalType );298 }299 300 293 void GenType::postvisit( TraitInstType * inst ) { 301 294 assertf( ! genC, "Trait types should not reach code generation." ); … … 314 307 } 315 308 316 void GenType::postvisit( QualifiedType * qualType ) {317 assertf( ! genC, "Qualified types should not reach code generation." );318 std::ostringstream os;319 os << genType( qualType->parent, "", pretty, genC, lineMarks ) << "." << genType( qualType->child, "", pretty, genC, lineMarks ) << typeString;320 typeString = os.str();321 handleQualifiers( qualType );322 }323 324 309 void GenType::handleQualifiers( Type * type ) { 325 310 if ( type->get_const() ) { -
src/Common/PassVisitor.h
raeec6b7 r97be800 133 133 virtual void visit( ArrayType * arrayType ) override final; 134 134 virtual void visit( ReferenceType * referenceType ) override final; 135 virtual void visit( QualifiedType * qualType ) override final;136 135 virtual void visit( FunctionType * functionType ) override final; 137 136 virtual void visit( StructInstType * aggregateUseType ) override final; … … 146 145 virtual void visit( ZeroType * zeroType ) override final; 147 146 virtual void visit( OneType * oneType ) override final; 148 virtual void visit( GlobalScopeType * globalType ) override final;149 147 150 148 virtual void visit( Designation * designation ) override final; … … 235 233 virtual Type * mutate( ArrayType * arrayType ) override final; 236 234 virtual Type * mutate( ReferenceType * referenceType ) override final; 237 virtual Type * mutate( QualifiedType * qualType ) override final;238 235 virtual Type * mutate( FunctionType * functionType ) override final; 239 236 virtual Type * mutate( StructInstType * aggregateUseType ) override final; … … 248 245 virtual Type * mutate( ZeroType * zeroType ) override final; 249 246 virtual Type * mutate( OneType * oneType ) override final; 250 virtual Type * mutate( GlobalScopeType * globalType ) override final;251 247 252 248 virtual Designation * mutate( Designation * designation ) override final; -
src/Common/PassVisitor.impl.h
raeec6b7 r97be800 2262 2262 2263 2263 //-------------------------------------------------------------------------- 2264 // QualifiedType2265 template< typename pass_type >2266 void PassVisitor< pass_type >::visit( QualifiedType * node ) {2267 VISIT_START( node );2268 2269 maybeAccept_impl( node->forall, *this );2270 maybeAccept_impl( node->parent, *this );2271 maybeAccept_impl( node->child, *this );2272 2273 VISIT_END( node );2274 }2275 2276 template< typename pass_type >2277 Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) {2278 MUTATE_START( node );2279 2280 maybeMutate_impl( node->forall, *this );2281 maybeMutate_impl( node->parent, *this );2282 maybeMutate_impl( node->child, *this );2283 2284 MUTATE_END( Type, node );2285 }2286 2287 //--------------------------------------------------------------------------2288 2264 // FunctionType 2289 2265 template< typename pass_type > … … 2578 2554 2579 2555 //-------------------------------------------------------------------------- 2580 // GlobalScopeType2581 template< typename pass_type >2582 void PassVisitor< pass_type >::visit( GlobalScopeType * node ) {2583 VISIT_START( node );2584 2585 maybeAccept_impl( node->forall, *this );2586 2587 VISIT_END( node );2588 }2589 2590 template< typename pass_type >2591 Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) {2592 MUTATE_START( node );2593 2594 maybeMutate_impl( node->forall, *this );2595 2596 MUTATE_END( Type, node );2597 }2598 2599 //--------------------------------------------------------------------------2600 2556 // Designation 2601 2557 template< typename pass_type > -
src/Concurrency/Keywords.cc
raeec6b7 r97be800 501 501 void MutexKeyword::postvisit(StructDecl* decl) { 502 502 503 if( decl->name == "monitor_desc" && decl->body) {503 if( decl->name == "monitor_desc" ) { 504 504 assert( !monitor_decl ); 505 505 monitor_decl = decl; 506 506 } 507 else if( decl->name == "monitor_guard_t" && decl->body) {507 else if( decl->name == "monitor_guard_t" ) { 508 508 assert( !guard_decl ); 509 509 guard_decl = decl; 510 510 } 511 else if( decl->name == "monitor_dtor_guard_t" && decl->body) {511 else if( decl->name == "monitor_dtor_guard_t" ) { 512 512 assert( !dtor_guard_decl ); 513 513 dtor_guard_decl = decl; -
src/InitTweak/FixInit.cc
raeec6b7 r97be800 1163 1163 1164 1164 std::string fname = getFunctionName( appExpr ); 1165 if ( fname == function-> name) {1165 if ( fname == function->get_name() ) { 1166 1166 // call to same kind of function 1167 Expression * firstParam = appExpr-> args.front();1167 Expression * firstParam = appExpr->get_args().front(); 1168 1168 1169 1169 if ( isThisExpression( firstParam, thisParam ) ) { … … 1174 1174 // if first parameter is a member expression on the this parameter, 1175 1175 // then remove the member from unhandled set. 1176 if ( isThisExpression( memberExpr-> aggregate, thisParam ) ) {1177 unhandled.erase( memberExpr-> member);1176 if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) { 1177 unhandled.erase( memberExpr->get_member() ); 1178 1178 } 1179 1179 } -
src/Parser/DeclarationNode.cc
raeec6b7 r97be800 253 253 return newnode; 254 254 } // DeclarationNode::newFromTypedef 255 256 DeclarationNode * DeclarationNode::newFromGlobalScope() {257 DeclarationNode * newnode = new DeclarationNode;258 newnode->type = new TypeData( TypeData::GlobalScope );259 return newnode;260 }261 262 DeclarationNode * DeclarationNode::newQualifiedType( DeclarationNode * parent, DeclarationNode * child) {263 DeclarationNode * newnode = new DeclarationNode;264 newnode->type = new TypeData( TypeData::Qualified );265 newnode->type->qualified.parent = parent->type;266 newnode->type->qualified.child = child->type;267 parent->type = nullptr;268 child->type = nullptr;269 delete parent;270 delete child;271 return newnode;272 }273 255 274 256 DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) { … … 1003 985 try { 1004 986 Declaration * decl = cur->build(); 1005 assert( decl );1006 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {1007 dwt->location = cur->location;1008 * out++ = dwt;1009 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {1010 // xxx - this might be where anonymous struct members are added - should be conditional on struct name1011 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name);1012 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );1013 obj->location = cur->location;1014 * out++ = obj;1015 delete agg;1016 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {1017 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name);1018 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );1019 obj->location = cur->location;1020 * out++ = obj;987 if ( decl ) { 988 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 989 dwt->location = cur->location; 990 * out++ = dwt; 991 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) { 992 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->get_name() ); 993 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 994 obj->location = cur->location; 995 * out++ = obj; 996 delete agg; 997 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) { 998 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->get_name() ); 999 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1000 obj->location = cur->location; 1001 * out++ = obj; 1002 } // if 1021 1003 } // if 1022 1004 } catch( SemanticErrorException &e ) { -
src/Parser/ParseNode.h
raeec6b7 r97be800 231 231 static DeclarationNode * newForall( DeclarationNode * ); 232 232 static DeclarationNode * newFromTypedef( const std::string * ); 233 static DeclarationNode * newFromGlobalScope();234 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );235 233 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ); 236 234 static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ); -
src/Parser/TypeData.cc
raeec6b7 r97be800 37 37 case Reference: 38 38 case EnumConstant: 39 case GlobalScope:40 39 // nothing else to initialize 41 40 break; … … 99 98 case Builtin: 100 99 // builtin = new Builtin_t; 101 case Qualified:102 qualified.parent = nullptr;103 qualified.child = nullptr;104 100 break; 105 101 } // switch … … 116 112 case Reference: 117 113 case EnumConstant: 118 case GlobalScope:119 114 // nothing to destroy 120 115 break; … … 170 165 // delete builtin; 171 166 break; 172 case Qualified:173 delete qualified.parent;174 delete qualified.child;175 167 } // switch 176 168 } // TypeData::~TypeData … … 188 180 case Pointer: 189 181 case Reference: 190 case GlobalScope:191 182 // nothing else to copy 192 183 break; … … 246 237 assert( builtintype == DeclarationNode::Zero || builtintype == DeclarationNode::One ); 247 238 newtype->builtintype = builtintype; 248 break;249 case Qualified:250 newtype->qualified.parent = maybeClone( qualified.parent );251 newtype->qualified.child = maybeClone( qualified.child );252 239 break; 253 240 } // switch … … 478 465 return new EnumInstType( buildQualifiers( td ), "" ); 479 466 case TypeData::SymbolicInst: 480 return buildSymbolicInst( td ); 467 return buildSymbolicInst( td );; 481 468 case TypeData::Tuple: 482 469 return buildTuple( td ); … … 493 480 return new VarArgsType( buildQualifiers( td ) ); 494 481 } 495 case TypeData::GlobalScope:496 return new GlobalScopeType();497 case TypeData::Qualified:498 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );499 482 case TypeData::Symbolic: 500 483 case TypeData::Enum: … … 502 485 assert( false ); 503 486 } // switch 504 505 487 return nullptr; 506 488 } // typebuild … … 911 893 assert( td->kind == TypeData::Function ); 912 894 FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis ); 913 buildList( td->function.params, ft-> parameters);914 buildForall( td->forall, ft-> forall);895 buildList( td->function.params, ft->get_parameters() ); 896 buildForall( td->forall, ft->get_forall() ); 915 897 if ( td->base ) { 916 898 switch ( td->base->kind ) { 917 899 case TypeData::Tuple: 918 buildList( td->base->tuple, ft-> returnVals);900 buildList( td->base->tuple, ft->get_returnVals() ); 919 901 break; 920 902 default: -
src/Parser/TypeData.h
raeec6b7 r97be800 27 27 struct TypeData { 28 28 enum Kind { Basic, Pointer, Array, Reference, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic, 29 SymbolicInst, Tuple, Typeof, Builtin, GlobalScope, Qualified,Unknown };29 SymbolicInst, Tuple, Typeof, Builtin, Unknown }; 30 30 31 31 struct Aggregate_t { … … 75 75 }; 76 76 77 struct Qualified_t { // qualified type S.T78 TypeData * parent;79 TypeData * child;80 };81 82 77 CodeLocation location; 83 78 … … 93 88 DeclarationNode * forall; 94 89 90 // Basic_t basic; 95 91 Aggregate_t aggregate; 96 92 AggInst_t aggInst; 97 93 Array_t array; 98 94 Enumeration_t enumeration; 95 // Variable_t variable; 99 96 Function_t function; 100 97 Symbolic_t symbolic; 101 Qualified_t qualified;102 98 DeclarationNode * tuple; 103 99 ExpressionNode * typeexpr; -
src/Parser/parser.yy
raeec6b7 r97be800 1821 1821 { $$ = DeclarationNode::newFromTypedef( $1 ); } 1822 1822 | '.' TYPEDEFname 1823 { $$ = DeclarationNode::newQualifiedType( DeclarationNode::newFromGlobalScope(), DeclarationNode::newFromTypedef( $2 ) ); }1823 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 1824 1824 | type_name '.' TYPEDEFname 1825 { $$ = DeclarationNode::newQualifiedType( $1, DeclarationNode::newFromTypedef( $3 ) ); }1825 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 1826 1826 | typegen_name 1827 1827 | '.' typegen_name 1828 { $$ = DeclarationNode::newQualifiedType( DeclarationNode::newFromGlobalScope(), $2 ); }1828 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 1829 1829 | type_name '.' typegen_name 1830 { $$ = DeclarationNode::newQualifiedType( $1, $3 ); }1830 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } 1831 1831 ; 1832 1832 … … 1929 1929 { distExt( $3 ); $$ = distAttr( $2, $3 ); } // mark all fields in list 1930 1930 | typedef_declaration ';' // CFA 1931 { SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; } 1931 1932 | cfa_field_declaring_list ';' // CFA, new style field declaration 1932 1933 | EXTENSION cfa_field_declaring_list ';' // GCC 1933 1934 { distExt( $2 ); $$ = $2; } // mark all fields in list 1934 1935 | cfa_typedef_declaration ';' // CFA 1936 { SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; } 1935 1937 | static_assert // C11 1936 1938 ; -
src/SymTab/Indexer.cc
raeec6b7 r97be800 272 272 } 273 273 274 NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {275 return lookupTypeAtScope( id, 0 );276 }277 278 StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {279 return lookupStructAtScope( id, 0 );280 }281 282 UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const {283 return lookupUnionAtScope( id, 0 );284 }285 286 EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const {287 return lookupEnumAtScope( id, 0 );288 }289 290 274 EnumDecl *Indexer::lookupEnum( const std::string &id ) const { 291 275 if ( ! tables ) return 0; … … 363 347 if ( ! tables ) return 0; 364 348 if ( tables->scope < scope ) return 0; 365 if ( tables->scope > scope ) return tables->base.lookupTypeAtScope( id, scope );366 349 367 350 TypeTable::const_iterator ret = tables->typeTable.find( id ); … … 372 355 if ( ! tables ) return 0; 373 356 if ( tables->scope < scope ) return 0; 374 if ( tables->scope > scope ) return tables->base.lookupStructAtScope( id, scope );375 357 376 358 StructTable::const_iterator ret = tables->structTable.find( id ); … … 381 363 if ( ! tables ) return 0; 382 364 if ( tables->scope < scope ) return 0; 383 if ( tables->scope > scope ) return tables->base.lookupEnumAtScope( id, scope );384 365 385 366 EnumTable::const_iterator ret = tables->enumTable.find( id ); … … 390 371 if ( ! tables ) return 0; 391 372 if ( tables->scope < scope ) return 0; 392 if ( tables->scope > scope ) return tables->base.lookupUnionAtScope( id, scope );393 373 394 374 UnionTable::const_iterator ret = tables->unionTable.find( id ); … … 399 379 if ( ! tables ) return 0; 400 380 if ( tables->scope < scope ) return 0; 401 if ( tables->scope > scope ) return tables->base.lookupTraitAtScope( id, scope );402 381 403 382 TraitTable::const_iterator ret = tables->traitTable.find( id ); … … 507 486 508 487 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) { 509 if ( existing-> base == nullptr) {488 if ( existing->get_base() == 0 ) { 510 489 return false; 511 } else if ( added-> base == nullptr) {490 } else if ( added->get_base() == 0 ) { 512 491 return true; 513 492 } else { 514 assert( existing->base && added->base ); 515 // typedef redeclarations are errors only if types are different 516 if ( ! ResolvExpr::typesCompatible( existing->base, added->base, Indexer() ) ) { 517 SemanticError( added->location, "redeclaration of " + added->name ); 518 } 519 } 520 // does not need to be added to the table if both existing and added have a base that are the same 521 return true; 493 SemanticError( added, "redeclaration of " ); 494 } 522 495 } 523 496 … … 526 499 makeWritable(); 527 500 528 const std::string &id = decl-> name;501 const std::string &id = decl->get_name(); 529 502 TypeTable::iterator existing = tables->typeTable.find( id ); 530 503 if ( existing == tables->typeTable.end() ) { … … 559 532 makeWritable(); 560 533 561 const std::string &id = decl-> name;534 const std::string &id = decl->get_name(); 562 535 StructTable::iterator existing = tables->structTable.find( id ); 563 536 if ( existing == tables->structTable.end() ) { … … 578 551 makeWritable(); 579 552 580 const std::string &id = decl-> name;553 const std::string &id = decl->get_name(); 581 554 EnumTable::iterator existing = tables->enumTable.find( id ); 582 555 if ( existing == tables->enumTable.end() ) { … … 602 575 makeWritable(); 603 576 604 const std::string &id = decl-> name;577 const std::string &id = decl->get_name(); 605 578 UnionTable::iterator existing = tables->unionTable.find( id ); 606 579 if ( existing == tables->unionTable.end() ) { … … 621 594 makeWritable(); 622 595 623 const std::string &id = decl-> name;596 const std::string &id = decl->get_name(); 624 597 TraitTable::iterator existing = tables->traitTable.find( id ); 625 598 if ( existing == tables->traitTable.end() ) { -
src/SymTab/Indexer.h
raeec6b7 r97be800 70 70 /// Gets the top-most trait declaration with the given ID 71 71 TraitDecl *lookupTrait( const std::string &id ) const; 72 73 /// Gets the type declaration with the given ID at global scope74 NamedTypeDecl *globalLookupType( const std::string &id ) const;75 /// Gets the struct declaration with the given ID at global scope76 StructDecl *globalLookupStruct( const std::string &id ) const;77 /// Gets the union declaration with the given ID at global scope78 UnionDecl *globalLookupUnion( const std::string &id ) const;79 /// Gets the enum declaration with the given ID at global scope80 EnumDecl *globalLookupEnum( const std::string &id ) const;81 72 82 73 void print( std::ostream &os, int indent = 0 ) const; -
src/SymTab/Mangler.cc
raeec6b7 r97be800 60 60 void postvisit( ZeroType * zeroType ); 61 61 void postvisit( OneType * oneType ); 62 void postvisit( QualifiedType * qualType );63 62 64 63 std::string get_mangleName() { return mangleName.str(); } … … 172 171 "w", // SignedInt128 173 172 "Uw", // UnsignedInt128 174 "x", 175 "y", 173 "x", // Float80 174 "y", // Float128 176 175 }; 177 176 static_assert( … … 313 312 void Mangler::postvisit( OneType * ) { 314 313 mangleName << "O"; 315 }316 317 void Mangler::postvisit( QualifiedType * qualType ) {318 maybeAccept( qualType->parent, *visitor );319 mangleName << "__";320 maybeAccept( qualType->child, *visitor );321 314 } 322 315 -
src/SymTab/Validate.cc
raeec6b7 r97be800 77 77 class SwitchStmt; 78 78 79 #define debugPrint( x ) if ( doDebug ) x79 #define debugPrint( x ) if ( doDebug ) { std::cout << x; } 80 80 81 81 namespace SymTab { 82 /// hoists declarations that are difficult to hoist while parsing83 struct HoistTypeDecls final : public WithDeclsToAdd {84 void previsit( SizeofExpr * );85 void previsit( AlignofExpr * );86 void previsit( UntypedOffsetofExpr * );87 void handleType( Type * );88 };89 90 struct FixQualifiedTypes final : public WithIndexer {91 Type * postmutate( QualifiedType * );92 };93 94 82 struct HoistStruct final : public WithDeclsToAdd, public WithGuards { 95 83 /// Flattens nested struct types 96 84 static void hoistStruct( std::list< Declaration * > &translationUnit ); 97 85 86 void previsit( EnumInstType * enumInstType ); 87 void previsit( StructInstType * structInstType ); 88 void previsit( UnionInstType * unionInstType ); 98 89 void previsit( StructDecl * aggregateDecl ); 99 90 void previsit( UnionDecl * aggregateDecl ); 100 91 void previsit( StaticAssertDecl * assertDecl ); 101 void previsit( StructInstType * type );102 void previsit( UnionInstType * type );103 void previsit( EnumInstType * type );104 92 105 93 private: … … 124 112 125 113 /// Associates forward declarations of aggregates with their definitions 126 struct LinkReferenceToTypes final : public WithIndexer, public WithGuards , public WithVisitorRef<LinkReferenceToTypes>, public WithShortCircuiting{114 struct LinkReferenceToTypes final : public WithIndexer, public WithGuards { 127 115 LinkReferenceToTypes( const Indexer *indexer ); 128 116 void postvisit( TypeInstType *typeInst ); … … 132 120 void postvisit( UnionInstType *unionInst ); 133 121 void postvisit( TraitInstType *traitInst ); 134 void previsit( QualifiedType * qualType );135 void postvisit( QualifiedType * qualType );136 122 137 123 void postvisit( EnumDecl *enumDecl ); … … 179 165 }; 180 166 181 struct ReplaceTypedef final : public WithVisitorRef<ReplaceTypedef>, public WithGuards, public WithShortCircuiting, public WithDeclsToAdd{182 ReplaceTypedef() : scopeLevel( 0 ) {}167 struct EliminateTypedef final : public WithVisitorRef<EliminateTypedef>, public WithGuards { 168 EliminateTypedef() : scopeLevel( 0 ) {} 183 169 /// Replaces typedefs by forward declarations 184 static void replaceTypedef( std::list< Declaration * > &translationUnit ); 185 186 void premutate( QualifiedType * ); 187 Type * postmutate( QualifiedType * qualType ); 170 static void eliminateTypedef( std::list< Declaration * > &translationUnit ); 171 188 172 Type * postmutate( TypeInstType * aggregateUseType ); 189 173 Declaration * postmutate( TypedefDecl * typeDecl ); … … 196 180 197 181 void premutate( CompoundStmt * compoundStmt ); 182 CompoundStmt * postmutate( CompoundStmt * compoundStmt ); 198 183 199 184 void premutate( StructDecl * structDecl ); 185 Declaration * postmutate( StructDecl * structDecl ); 200 186 void premutate( UnionDecl * unionDecl ); 187 Declaration * postmutate( UnionDecl * unionDecl ); 201 188 void premutate( EnumDecl * enumDecl ); 202 void premutate( TraitDecl * ); 189 Declaration * postmutate( EnumDecl * enumDecl ); 190 Declaration * postmutate( TraitDecl * contextDecl ); 203 191 204 192 void premutate( FunctionType * ftype ); … … 206 194 private: 207 195 template<typename AggDecl> 196 AggDecl *handleAggregate( AggDecl * aggDecl ); 197 198 template<typename AggDecl> 208 199 void addImplicitTypedef( AggDecl * aggDecl ); 209 template< typename AggDecl >210 void handleAggregate( AggDecl * aggr );211 200 212 201 typedef std::unique_ptr<TypedefDecl> TypedefDeclPtr; 213 202 typedef ScopedMap< std::string, std::pair< TypedefDeclPtr, int > > TypedefMap; 214 typedef ScopedMap< std::string, TypeDecl * > TypeDeclMap;203 typedef std::map< std::string, TypeDecl * > TypeDeclMap; 215 204 TypedefMap typedefNames; 216 205 TypeDeclMap typedeclNames; 217 206 int scopeLevel; 218 207 bool inFunctionType = false; 219 };220 221 struct EliminateTypedef {222 /// removes TypedefDecls from the AST223 static void eliminateTypedef( std::list< Declaration * > &translationUnit );224 225 template<typename AggDecl>226 void handleAggregate( AggDecl *aggregateDecl );227 228 void previsit( StructDecl * aggregateDecl );229 void previsit( UnionDecl * aggregateDecl );230 void previsit( CompoundStmt * compoundStmt );231 208 }; 232 209 … … 286 263 PassVisitor<FindSpecialDeclarations> finder; 287 264 PassVisitor<LabelAddressFixer> labelAddrFixer; 288 PassVisitor<HoistTypeDecls> hoistDecls; 289 PassVisitor<FixQualifiedTypes> fixQual; 290 291 acceptAll( translationUnit, hoistDecls ); 292 ReplaceTypedef::replaceTypedef( translationUnit ); 265 266 EliminateTypedef::eliminateTypedef( translationUnit ); 267 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order 293 268 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 294 269 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling 295 270 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 296 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes, because aggregate members are accessed297 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order298 EliminateTypedef::eliminateTypedef( translationUnit ); //299 271 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes 300 272 VerifyCtorDtorAssign::verify( translationUnit ); // must happen before autogen, because autogen examines existing ctor/dtors … … 322 294 } 323 295 324 325 void HoistTypeDecls::handleType( Type * type ) {326 // some type declarations are buried in expressions and not easy to hoist during parsing; hoist them here327 AggregateDecl * aggr = nullptr;328 if ( StructInstType * inst = dynamic_cast< StructInstType * >( type ) ) {329 aggr = inst->baseStruct;330 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( type ) ) {331 aggr = inst->baseUnion;332 } else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( type ) ) {333 aggr = inst->baseEnum;334 }335 if ( aggr && aggr->body ) {336 declsToAddBefore.push_front( aggr );337 }338 }339 340 void HoistTypeDecls::previsit( SizeofExpr * expr ) {341 handleType( expr->type );342 }343 344 void HoistTypeDecls::previsit( AlignofExpr * expr ) {345 handleType( expr->type );346 }347 348 void HoistTypeDecls::previsit( UntypedOffsetofExpr * expr ) {349 handleType( expr->type );350 }351 352 353 Type * FixQualifiedTypes::postmutate( QualifiedType * qualType ) {354 Type * parent = qualType->parent;355 Type * child = qualType->child;356 if ( dynamic_cast< GlobalScopeType * >( qualType->parent ) ) {357 // .T => lookup T at global scope358 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) {359 auto td = indexer.globalLookupType( inst->name );360 if ( ! td ) {361 SemanticError( qualType->location, toString("Use of undefined global type ", inst->name) );362 }363 auto base = td->base;364 assert( base );365 return base->clone();366 } else {367 // .T => T is not a type name368 assertf( false, "unhandled global qualified child type: %s", toCString(child) );369 }370 } else {371 // S.T => S must be an aggregate type, find the declaration for T in S.372 AggregateDecl * aggr = nullptr;373 if ( StructInstType * inst = dynamic_cast< StructInstType * >( parent ) ) {374 aggr = inst->baseStruct;375 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * > ( parent ) ) {376 aggr = inst->baseUnion;377 } else {378 SemanticError( qualType->location, toString("Qualified type requires an aggregate on the left, but has: ", parent) );379 }380 assert( aggr ); // TODO: need to handle forward declarations381 for ( Declaration * member : aggr->members ) {382 if ( StructInstType * inst = dynamic_cast< StructInstType * >( child ) ) {383 if ( StructDecl * aggr = dynamic_cast< StructDecl * >( member ) ) {384 if ( aggr->name == inst->name ) {385 return new StructInstType( qualType->get_qualifiers(), aggr );386 }387 }388 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( child ) ) {389 if ( UnionDecl * aggr = dynamic_cast< UnionDecl * > ( member ) ) {390 if ( aggr->name == inst->name ) {391 return new UnionInstType( qualType->get_qualifiers(), aggr );392 }393 }394 } else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( child ) ) {395 if ( EnumDecl * aggr = dynamic_cast< EnumDecl * > ( member ) ) {396 if ( aggr->name == inst->name ) {397 return new EnumInstType( qualType->get_qualifiers(), aggr );398 }399 }400 } else if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) {401 // struct typedefs are being replaced by forward decls too early; move it to hoist struct402 if ( NamedTypeDecl * aggr = dynamic_cast< NamedTypeDecl * > ( member ) ) {403 if ( aggr->name == inst->name ) {404 assert( aggr->base );405 return aggr->base->clone();406 }407 }408 } else {409 // S.T - S is not an aggregate => error410 assertf( false, "unhandled qualified child type: %s", toCString(qualType) );411 }412 }413 // failed to find a satisfying definition of type414 SemanticError( qualType->location, toString("Undefined type in qualified type: ", qualType) );415 }416 417 // ... may want to link canonical SUE definition to each forward decl so that it becomes easier to lookup?418 }419 420 421 296 void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) { 422 297 PassVisitor<HoistStruct> hoister; … … 428 303 } 429 304 430 namespace {431 void qualifiedName( AggregateDecl * aggr, std::ostringstream & ss ) {432 if ( aggr->parent ) qualifiedName( aggr->parent, ss );433 ss << "__" << aggr->name;434 }435 436 // mangle nested type names using entire parent chain437 std::string qualifiedName( AggregateDecl * aggr ) {438 std::ostringstream ss;439 qualifiedName( aggr, ss );440 return ss.str();441 }442 }443 444 305 template< typename AggDecl > 445 306 void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) { 446 307 if ( parentAggr ) { 447 aggregateDecl->parent = parentAggr;448 aggregateDecl->name = qualifiedName( aggregateDecl );449 308 // Add elements in stack order corresponding to nesting structure. 450 309 declsToAddBefore.push_front( aggregateDecl ); … … 457 316 } 458 317 318 void HoistStruct::previsit( EnumInstType * inst ) { 319 if ( inst->baseEnum && inst->baseEnum->body ) { 320 declsToAddBefore.push_front( inst->baseEnum ); 321 } 322 } 323 324 void HoistStruct::previsit( StructInstType * inst ) { 325 if ( inst->baseStruct && inst->baseStruct->body ) { 326 declsToAddBefore.push_front( inst->baseStruct ); 327 } 328 } 329 330 void HoistStruct::previsit( UnionInstType * inst ) { 331 if ( inst->baseUnion && inst->baseUnion->body ) { 332 declsToAddBefore.push_front( inst->baseUnion ); 333 } 334 } 335 459 336 void HoistStruct::previsit( StaticAssertDecl * assertDecl ) { 460 337 if ( parentAggr ) { … … 471 348 } 472 349 473 void HoistStruct::previsit( StructInstType * type ) {474 // need to reset type name after expanding to qualified name475 assert( type->baseStruct );476 type->name = type->baseStruct->name;477 }478 479 void HoistStruct::previsit( UnionInstType * type ) {480 assert( type->baseUnion );481 type->name = type->baseUnion->name;482 }483 484 void HoistStruct::previsit( EnumInstType * type ) {485 assert( type->baseEnum );486 type->name = type->baseEnum->name;487 }488 489 490 bool isTypedef( Declaration *decl ) {491 return dynamic_cast< TypedefDecl * >( decl );492 }493 494 void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {495 PassVisitor<EliminateTypedef> eliminator;496 acceptAll( translationUnit, eliminator );497 filter( translationUnit, isTypedef, true );498 }499 500 template< typename AggDecl >501 void EliminateTypedef::handleAggregate( AggDecl *aggregateDecl ) {502 filter( aggregateDecl->members, isTypedef, true );503 }504 505 void EliminateTypedef::previsit( StructDecl * aggregateDecl ) {506 handleAggregate( aggregateDecl );507 }508 509 void EliminateTypedef::previsit( UnionDecl * aggregateDecl ) {510 handleAggregate( aggregateDecl );511 }512 513 void EliminateTypedef::previsit( CompoundStmt * compoundStmt ) {514 // remove and delete decl stmts515 filter( compoundStmt->kids, [](Statement * stmt) {516 if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {517 if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) {518 return true;519 } // if520 } // if521 return false;522 }, true);523 }524 525 350 void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) { 526 351 // Set the type of each member of the enumeration to be EnumConstant 527 for ( std::list< Declaration * >::iterator i = enumDecl-> members.begin(); i != enumDecl->members.end(); ++i ) {352 for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) { 528 353 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i ); 529 354 assert( obj ); 530 obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl-> name) );355 obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->get_name() ) ); 531 356 } // for 532 357 } … … 570 395 571 396 void LinkReferenceToTypes::postvisit( EnumInstType *enumInst ) { 572 EnumDecl *st = local_indexer->lookupEnum( enumInst-> name);397 EnumDecl *st = local_indexer->lookupEnum( enumInst->get_name() ); 573 398 // it's not a semantic error if the enum is not found, just an implicit forward declaration 574 399 if ( st ) { 575 enumInst->baseEnum = st; 576 } // if 577 if ( ! st || ! st->body ) { 400 //assert( ! enumInst->get_baseEnum() || enumInst->get_baseEnum()->get_members().empty() || ! st->get_members().empty() ); 401 enumInst->set_baseEnum( st ); 402 } // if 403 if ( ! st || st->get_members().empty() ) { 578 404 // use of forward declaration 579 forwardEnums[ enumInst-> name].push_back( enumInst );405 forwardEnums[ enumInst->get_name() ].push_back( enumInst ); 580 406 } // if 581 407 } … … 590 416 591 417 void LinkReferenceToTypes::postvisit( StructInstType *structInst ) { 592 StructDecl *st = local_indexer->lookupStruct( structInst-> name);418 StructDecl *st = local_indexer->lookupStruct( structInst->get_name() ); 593 419 // it's not a semantic error if the struct is not found, just an implicit forward declaration 594 420 if ( st ) { 595 structInst->baseStruct = st; 596 } // if 597 if ( ! st || ! st->body ) { 421 //assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() ); 422 structInst->set_baseStruct( st ); 423 } // if 424 if ( ! st || st->get_members().empty() ) { 598 425 // use of forward declaration 599 forwardStructs[ structInst-> name].push_back( structInst );426 forwardStructs[ structInst->get_name() ].push_back( structInst ); 600 427 } // if 601 428 checkGenericParameters( structInst ); … … 603 430 604 431 void LinkReferenceToTypes::postvisit( UnionInstType *unionInst ) { 605 UnionDecl *un = local_indexer->lookupUnion( unionInst-> name);432 UnionDecl *un = local_indexer->lookupUnion( unionInst->get_name() ); 606 433 // it's not a semantic error if the union is not found, just an implicit forward declaration 607 434 if ( un ) { 608 unionInst-> baseUnion = un;609 } // if 610 if ( ! un || ! un->body) {435 unionInst->set_baseUnion( un ); 436 } // if 437 if ( ! un || un->get_members().empty() ) { 611 438 // use of forward declaration 612 forwardUnions[ unionInst-> name].push_back( unionInst );439 forwardUnions[ unionInst->get_name() ].push_back( unionInst ); 613 440 } // if 614 441 checkGenericParameters( unionInst ); 615 }616 617 void LinkReferenceToTypes::previsit( QualifiedType * ) {618 visit_children = false;619 }620 621 void LinkReferenceToTypes::postvisit( QualifiedType * qualType ) {622 // linking only makes sense for the 'oldest ancestor' of the qualified type623 qualType->parent->accept( *visitor );624 442 } 625 443 … … 632 450 DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 ); 633 451 if ( dwt1 && dwt2 ) { 634 if ( dwt1-> name == dwt2->name&& ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {452 if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) { 635 453 // std::cerr << "=========== equal:" << std::endl; 636 454 // std::cerr << "d1: " << d1 << std::endl; … … 657 475 template< typename Iterator > 658 476 void expandAssertions( TraitInstType * inst, Iterator out ) { 659 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", to CString( inst) );477 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() ); 660 478 std::list< DeclarationWithType * > asserts; 661 479 for ( Declaration * decl : inst->baseTrait->members ) { … … 694 512 SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name ); 695 513 } // if 696 if ( traitDecl-> parameters.size() != traitInst->parameters.size() ) {514 if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) { 697 515 SemanticError( traitInst, "incorrect number of trait parameters: " ); 698 516 } // if … … 700 518 701 519 // need to carry over the 'sized' status of each decl in the instance 702 for ( auto p : group_iterate( traitDecl-> parameters, traitInst->parameters) ) {520 for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) { 703 521 TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) ); 704 522 if ( ! expr ) { … … 707 525 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) { 708 526 TypeDecl * formalDecl = std::get<0>(p); 709 TypeDecl * instDecl = inst-> baseType;527 TypeDecl * instDecl = inst->get_baseType(); 710 528 if ( formalDecl->get_sized() ) instDecl->set_sized( true ); 711 529 } … … 716 534 void LinkReferenceToTypes::postvisit( EnumDecl *enumDecl ) { 717 535 // visit enum members first so that the types of self-referencing members are updated properly 718 if ( enumDecl->body) {719 ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl-> name);536 if ( ! enumDecl->get_members().empty() ) { 537 ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->get_name() ); 720 538 if ( fwds != forwardEnums.end() ) { 721 539 for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 722 (*inst )->baseEnum = enumDecl;540 (*inst )->set_baseEnum( enumDecl ); 723 541 } // for 724 542 forwardEnums.erase( fwds ); … … 756 574 // visit struct members first so that the types of self-referencing members are updated properly 757 575 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) 758 if ( structDecl->body) {759 ForwardStructsType::iterator fwds = forwardStructs.find( structDecl-> name);576 if ( ! structDecl->get_members().empty() ) { 577 ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() ); 760 578 if ( fwds != forwardStructs.end() ) { 761 579 for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 762 (*inst )->baseStruct = structDecl;580 (*inst )->set_baseStruct( structDecl ); 763 581 } // for 764 582 forwardStructs.erase( fwds ); … … 768 586 769 587 void LinkReferenceToTypes::postvisit( UnionDecl *unionDecl ) { 770 if ( unionDecl->body) {771 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl-> name);588 if ( ! unionDecl->get_members().empty() ) { 589 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() ); 772 590 if ( fwds != forwardUnions.end() ) { 773 591 for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 774 (*inst )->baseUnion = unionDecl;592 (*inst )->set_baseUnion( unionDecl ); 775 593 } // for 776 594 forwardUnions.erase( fwds ); … … 782 600 // ensure generic parameter instances are renamed like the base type 783 601 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; 784 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst-> name) ) {602 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) { 785 603 if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) { 786 604 typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype ); … … 861 679 862 680 863 void ReplaceTypedef::replaceTypedef( std::list< Declaration * > &translationUnit ) { 864 PassVisitor<ReplaceTypedef> eliminator; 681 bool isTypedef( Declaration *decl ) { 682 return dynamic_cast< TypedefDecl * >( decl ); 683 } 684 685 void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) { 686 PassVisitor<EliminateTypedef> eliminator; 865 687 mutateAll( translationUnit, eliminator ); 866 688 if ( eliminator.pass.typedefNames.count( "size_t" ) ) { 867 689 // grab and remember declaration of size_t 868 SizeType = eliminator.pass.typedefNames["size_t"].first-> base->clone();690 SizeType = eliminator.pass.typedefNames["size_t"].first->get_base()->clone(); 869 691 } else { 870 692 // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong … … 872 694 SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 873 695 } 874 } 875 876 void ReplaceTypedef::premutate( QualifiedType * ) { 877 visit_children = false; 878 } 879 880 Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) { 881 // replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type 882 qualType->parent = qualType->parent->acceptMutator( *visitor ); 883 return qualType; 884 } 885 886 Type * ReplaceTypedef::postmutate( TypeInstType * typeInst ) { 696 filter( translationUnit, isTypedef, true ); 697 } 698 699 Type * EliminateTypedef::postmutate( TypeInstType * typeInst ) { 887 700 // instances of typedef types will come here. If it is an instance 888 701 // of a typdef type, link the instance to its actual type. 889 TypedefMap::const_iterator def = typedefNames.find( typeInst-> name);702 TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() ); 890 703 if ( def != typedefNames.end() ) { 891 704 Type *ret = def->second.first->base->clone(); … … 904 717 SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name ); 905 718 } 906 rtt-> parameters.clear();719 rtt->get_parameters().clear(); 907 720 cloneAll( typeInst->parameters, rtt->parameters ); 908 721 mutateAll( rtt->parameters, *visitor ); // recursively fix typedefs on parameters … … 911 724 return ret; 912 725 } else { 913 TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->name ); 914 if ( base == typedeclNames.end() ) { 915 SemanticError( typeInst->location, toString("Use of undefined type ", typeInst->name) ); 916 } 726 TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() ); 727 assertf( base != typedeclNames.end(), "Cannot find typedecl name %s", typeInst->name.c_str() ); 917 728 typeInst->set_baseType( base->second ); 918 return typeInst; 919 } // if 920 assert( false ); 729 } // if 730 return typeInst; 921 731 } 922 732 … … 935 745 } 936 746 937 Declaration * ReplaceTypedef::postmutate( TypedefDecl * tyDecl ) {938 if ( typedefNames.count( tyDecl-> name ) == 1 && typedefNames[ tyDecl->name].second == scopeLevel ) {747 Declaration *EliminateTypedef::postmutate( TypedefDecl * tyDecl ) { 748 if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) { 939 749 // typedef to the same name from the same scope 940 750 // must be from the same type 941 751 942 Type * t1 = tyDecl-> base;943 Type * t2 = typedefNames[ tyDecl-> name ].first->base;752 Type * t1 = tyDecl->get_base(); 753 Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base(); 944 754 if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) { 945 755 SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name ); … … 953 763 } 954 764 } else { 955 typedefNames[ tyDecl-> name] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );765 typedefNames[ tyDecl->get_name() ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel ); 956 766 } // if 957 767 … … 965 775 // Note, qualifiers on the typedef are superfluous for the forward declaration. 966 776 967 Type *designatorType = tyDecl-> base->stripDeclarator();777 Type *designatorType = tyDecl->get_base()->stripDeclarator(); 968 778 if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) { 969 declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage) );779 return new StructDecl( aggDecl->get_name(), DeclarationNode::Struct, noAttributes, tyDecl->get_linkage() ); 970 780 } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) { 971 declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage) );781 return new UnionDecl( aggDecl->get_name(), noAttributes, tyDecl->get_linkage() ); 972 782 } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) { 973 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) ); 974 } // if 975 return tyDecl->clone(); 976 } 977 978 void ReplaceTypedef::premutate( TypeDecl * typeDecl ) { 979 TypedefMap::iterator i = typedefNames.find( typeDecl->name ); 783 return new EnumDecl( enumDecl->get_name(), noAttributes, tyDecl->get_linkage() ); 784 } else { 785 return tyDecl->clone(); 786 } // if 787 } 788 789 void EliminateTypedef::premutate( TypeDecl * typeDecl ) { 790 TypedefMap::iterator i = typedefNames.find( typeDecl->get_name() ); 980 791 if ( i != typedefNames.end() ) { 981 792 typedefNames.erase( i ) ; 982 793 } // if 983 794 984 typedeclNames .insert( typeDecl->name, typeDecl );985 } 986 987 void ReplaceTypedef::premutate( FunctionDecl * ) {795 typedeclNames[ typeDecl->get_name() ] = typeDecl; 796 } 797 798 void EliminateTypedef::premutate( FunctionDecl * ) { 988 799 GuardScope( typedefNames ); 989 GuardScope( typedeclNames ); 990 } 991 992 void ReplaceTypedef::premutate( ObjectDecl * ) { 800 } 801 802 void EliminateTypedef::premutate( ObjectDecl * ) { 993 803 GuardScope( typedefNames ); 994 GuardScope( typedeclNames ); 995 } 996 997 DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) { 998 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type? 804 } 805 806 DeclarationWithType *EliminateTypedef::postmutate( ObjectDecl * objDecl ) { 807 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->get_type() ) ) { // function type? 999 808 // replace the current object declaration with a function declaration 1000 FunctionDecl * newDecl = new FunctionDecl( objDecl-> name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() );1001 objDecl-> attributes.clear();809 FunctionDecl * newDecl = new FunctionDecl( objDecl->get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() ); 810 objDecl->get_attributes().clear(); 1002 811 objDecl->set_type( nullptr ); 1003 812 delete objDecl; … … 1007 816 } 1008 817 1009 void ReplaceTypedef::premutate( CastExpr * ) {818 void EliminateTypedef::premutate( CastExpr * ) { 1010 819 GuardScope( typedefNames ); 1011 GuardScope( typedeclNames ); 1012 } 1013 1014 void ReplaceTypedef::premutate( CompoundStmt * ) { 820 } 821 822 void EliminateTypedef::premutate( CompoundStmt * ) { 1015 823 GuardScope( typedefNames ); 1016 GuardScope( typedeclNames );1017 824 scopeLevel += 1; 1018 825 GuardAction( [this](){ scopeLevel -= 1; } ); 1019 826 } 1020 827 828 CompoundStmt *EliminateTypedef::postmutate( CompoundStmt * compoundStmt ) { 829 // remove and delete decl stmts 830 filter( compoundStmt->kids, [](Statement * stmt) { 831 if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { 832 if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) { 833 return true; 834 } // if 835 } // if 836 return false; 837 }, true); 838 return compoundStmt; 839 } 840 841 // there may be typedefs nested within aggregates. in order for everything to work properly, these should be removed 842 // as well 1021 843 template<typename AggDecl> 1022 void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) { 844 AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) { 845 filter( aggDecl->members, isTypedef, true ); 846 return aggDecl; 847 } 848 849 template<typename AggDecl> 850 void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) { 1023 851 if ( typedefNames.count( aggDecl->get_name() ) == 0 ) { 1024 852 Type *type = nullptr; … … 1032 860 TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() ) ); 1033 861 typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel ); 1034 // add the implicit typedef to the AST 1035 declsToAddBefore.push_back( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type->clone(), aggDecl->get_linkage() ) ); 1036 } // if 1037 } 1038 1039 template< typename AggDecl > 1040 void ReplaceTypedef::handleAggregate( AggDecl * aggr ) { 1041 SemanticErrorException errors; 1042 1043 ValueGuard< std::list<Declaration * > > oldBeforeDecls( declsToAddBefore ); 1044 ValueGuard< std::list<Declaration * > > oldAfterDecls ( declsToAddAfter ); 1045 declsToAddBefore.clear(); 1046 declsToAddAfter.clear(); 1047 1048 GuardScope( typedefNames ); 1049 GuardScope( typedeclNames ); 1050 mutateAll( aggr->parameters, *visitor ); 1051 1052 // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body. 1053 for ( std::list< Declaration * >::iterator i = aggr->members.begin(); i != aggr->members.end(); ++i ) { 1054 if ( !declsToAddAfter.empty() ) { aggr->members.splice( i, declsToAddAfter ); } 1055 1056 try { 1057 *i = maybeMutate( *i, *visitor ); 1058 } catch ( SemanticErrorException &e ) { 1059 errors.append( e ); 1060 } 1061 1062 if ( !declsToAddBefore.empty() ) { aggr->members.splice( i, declsToAddBefore ); } 1063 } 1064 1065 if ( !declsToAddAfter.empty() ) { aggr->members.splice( aggr->members.end(), declsToAddAfter ); } 1066 if ( !errors.isEmpty() ) { throw errors; } 1067 } 1068 1069 void ReplaceTypedef::premutate( StructDecl * structDecl ) { 1070 visit_children = false; 862 } // if 863 } 864 865 void EliminateTypedef::premutate( StructDecl * structDecl ) { 1071 866 addImplicitTypedef( structDecl ); 1072 handleAggregate( structDecl ); 1073 } 1074 1075 void ReplaceTypedef::premutate( UnionDecl * unionDecl ) { 1076 visit_children = false; 867 } 868 869 870 Declaration *EliminateTypedef::postmutate( StructDecl * structDecl ) { 871 return handleAggregate( structDecl ); 872 } 873 874 void EliminateTypedef::premutate( UnionDecl * unionDecl ) { 1077 875 addImplicitTypedef( unionDecl ); 1078 handleAggregate( unionDecl ); 1079 } 1080 1081 void ReplaceTypedef::premutate( EnumDecl * enumDecl ) { 876 } 877 878 Declaration *EliminateTypedef::postmutate( UnionDecl * unionDecl ) { 879 return handleAggregate( unionDecl ); 880 } 881 882 void EliminateTypedef::premutate( EnumDecl * enumDecl ) { 1082 883 addImplicitTypedef( enumDecl ); 1083 884 } 1084 885 1085 void ReplaceTypedef::premutate( FunctionType * ) { 886 Declaration *EliminateTypedef::postmutate( EnumDecl * enumDecl ) { 887 return handleAggregate( enumDecl ); 888 } 889 890 Declaration *EliminateTypedef::postmutate( TraitDecl * traitDecl ) { 891 return handleAggregate( traitDecl ); 892 } 893 894 void EliminateTypedef::premutate( FunctionType * ) { 1086 895 GuardValue( inFunctionType ); 1087 896 inFunctionType = true; 1088 }1089 1090 void ReplaceTypedef::premutate( TraitDecl * ) {1091 GuardScope( typedefNames );1092 GuardScope( typedeclNames);1093 897 } 1094 898 … … 1220 1024 1221 1025 void ArrayLength::previsit( ObjectDecl * objDecl ) { 1222 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl-> type) ) {1026 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) { 1223 1027 if ( at->get_dimension() ) return; 1224 if ( ListInit * init = dynamic_cast< ListInit * >( objDecl-> init) ) {1225 at->set_dimension( new ConstantExpr( Constant::from_ulong( init-> initializers.size() ) ) );1028 if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->get_init() ) ) { 1029 at->set_dimension( new ConstantExpr( Constant::from_ulong( init->get_initializers().size() ) ) ); 1226 1030 } 1227 1031 } -
src/SynTree/Declaration.h
raeec6b7 r97be800 266 266 bool body; 267 267 std::list< Attribute * > attributes; 268 AggregateDecl * parent = nullptr;269 268 270 269 AggregateDecl( const std::string &name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ); -
src/SynTree/Mutator.h
raeec6b7 r97be800 101 101 virtual Type * mutate( ArrayType * arrayType ) = 0; 102 102 virtual Type * mutate( ReferenceType * refType ) = 0; 103 virtual Type * mutate( QualifiedType * qualType ) = 0;104 103 virtual Type * mutate( FunctionType * functionType ) = 0; 105 104 virtual Type * mutate( StructInstType * aggregateUseType ) = 0; … … 114 113 virtual Type * mutate( ZeroType * zeroType ) = 0; 115 114 virtual Type * mutate( OneType * oneType ) = 0; 116 virtual Type * mutate( GlobalScopeType * globalType ) = 0;117 115 118 116 virtual Designation * mutate( Designation * designation ) = 0 ; -
src/SynTree/ReferenceToType.cc
raeec6b7 r97be800 76 76 bool StructInstType::isComplete() const { return baseStruct ? baseStruct->has_body() : false; } 77 77 78 AggregateDecl * StructInstType::getAggr() const{ return baseStruct; }78 AggregateDecl * StructInstType::getAggr() { return baseStruct; } 79 79 80 80 TypeSubstitution StructInstType::genericSubstitution() const { … … 119 119 bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; } 120 120 121 AggregateDecl * UnionInstType::getAggr() const{ return baseUnion; }121 AggregateDecl * UnionInstType::getAggr() { return baseUnion; } 122 122 123 123 TypeSubstitution UnionInstType::genericSubstitution() const { … … 152 152 bool EnumInstType::isComplete() const { return baseEnum ? baseEnum->has_body() : false; } 153 153 154 AggregateDecl * EnumInstType::getAggr() const { return baseEnum; }155 156 154 void EnumInstType::print( std::ostream &os, Indenter indent ) const { 157 155 using std::endl; -
src/SynTree/SynTree.h
raeec6b7 r97be800 110 110 class ArrayType; 111 111 class ReferenceType; 112 class QualifiedType;113 112 class FunctionType; 114 113 class ReferenceToType; … … 124 123 class ZeroType; 125 124 class OneType; 126 class GlobalScopeType;127 125 128 126 class Designation; -
src/SynTree/Type.cc
raeec6b7 r97be800 105 105 } 106 106 107 108 QualifiedType::QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child ) : Type( tq, {} ), parent( parent ), child( child ) {109 }110 111 QualifiedType::QualifiedType( const QualifiedType & other ) : Type( other ), parent( maybeClone( other.parent ) ), child( maybeClone( other.child ) ) {112 }113 114 QualifiedType::~QualifiedType() {115 delete parent;116 delete child;117 }118 119 void QualifiedType::print( std::ostream & os, Indenter indent ) const {120 os << "Qualified Type: " << endl;121 os << indent+1;122 parent->print( os, indent+1 );123 os << endl << indent+1;124 child->print( os, indent+1 );125 os << endl;126 Type::print( os, indent+1 );127 }128 129 GlobalScopeType::GlobalScopeType() : Type( Type::Qualifiers(), {} ) {}130 131 void GlobalScopeType::print( std::ostream & os, Indenter ) const {132 os << "Global Scope Type" << endl;133 }134 135 136 107 // Empty Variable declarations: 137 108 const Type::FuncSpecifiers noFuncSpecifiers; -
src/SynTree/Type.h
raeec6b7 r97be800 178 178 virtual bool isComplete() const { return true; } 179 179 180 virtual AggregateDecl * getAggr() const{ assertf( false, "Non-aggregate type: %s", toCString( this ) ); }180 virtual AggregateDecl * getAggr() { assertf( false, "Non-aggregate type: %s", toCString( this ) ); } 181 181 182 182 virtual TypeSubstitution genericSubstitution() const; … … 315 315 }; 316 316 317 class QualifiedType : public Type {318 public:319 Type * parent;320 Type * child;321 322 QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child );323 QualifiedType( const QualifiedType & tq );324 virtual ~QualifiedType();325 326 virtual QualifiedType *clone() const override { return new QualifiedType( *this ); }327 virtual void accept( Visitor & v ) override { v.visit( this ); }328 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }329 virtual void print( std::ostream & os, Indenter indent = {} ) const override;330 };331 332 317 class ReferenceType : public Type { 333 318 public: … … 431 416 virtual bool isComplete() const override; 432 417 433 virtual AggregateDecl * getAggr() constoverride;418 virtual AggregateDecl * getAggr() override; 434 419 435 420 virtual TypeSubstitution genericSubstitution() const override; … … 468 453 virtual bool isComplete() const override; 469 454 470 virtual AggregateDecl * getAggr() constoverride;455 virtual AggregateDecl * getAggr() override; 471 456 472 457 virtual TypeSubstitution genericSubstitution() const override; … … 500 485 501 486 virtual bool isComplete() const override; 502 503 virtual AggregateDecl * getAggr() const;504 487 505 488 virtual EnumInstType *clone() const override { return new EnumInstType( *this ); } … … 682 665 }; 683 666 684 class GlobalScopeType : public Type {685 public:686 GlobalScopeType();687 688 virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); }689 virtual void accept( Visitor & v ) override { v.visit( this ); }690 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }691 virtual void print( std::ostream & os, Indenter indent = {} ) const override;692 };693 694 667 // Local Variables: // 695 668 // tab-width: 4 // -
src/SynTree/Visitor.h
raeec6b7 r97be800 103 103 virtual void visit( ArrayType * arrayType ) = 0; 104 104 virtual void visit( ReferenceType * refType ) = 0; 105 virtual void visit( QualifiedType * qualType ) = 0;106 105 virtual void visit( FunctionType * functionType ) = 0; 107 106 virtual void visit( StructInstType * aggregateUseType ) = 0; … … 116 115 virtual void visit( ZeroType * zeroType ) = 0; 117 116 virtual void visit( OneType * oneType ) = 0; 118 virtual void visit( GlobalScopeType * globalType ) = 0;119 117 120 118 virtual void visit( Designation * designation ) = 0; -
src/main.cc
raeec6b7 r97be800 247 247 } // if 248 248 249 // Temporary: fill locations after parsing so that every node has a location, for early error messages.250 // Eventually we should pass the locations from the parser to every node, but this quick and dirty solution251 // works okay for now.252 CodeTools::fillLocations( translationUnit );253 254 249 // add the assignment statement after the initialization of a type parameter 255 250 PASS( "validate", SymTab::validate( translationUnit, symtabp ) ); -
src/prelude/prelude.old.cf
raeec6b7 r97be800 728 728 forall( dtype DT ) void ?{}( volatile DT * &, DT * ); 729 729 forall( dtype DT ) void ?{}( volatile DT * &, volatile DT * ); 730 730 731 forall( dtype DT ) void ?{}( const volatile DT * &, DT * ); 731 732 forall( dtype DT ) void ?{}( const volatile DT * &, const DT * ); -
src/tests/Makefile.am
raeec6b7 r97be800 110 110 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 111 111 112 nested-types-ERR1: nested-types.c @CFA_BINDIR@/@CFA_NAME@113 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}114 115 nested-types-ERR2: nested-types.c @CFA_BINDIR@/@CFA_NAME@116 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR2 ${<} -o ${@}117 118 112 # Constructor/destructor tests 119 113 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.c @CFA_BINDIR@/@CFA_NAME@ -
src/tests/Makefile.in
raeec6b7 r97be800 787 787 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 788 788 789 nested-types-ERR1: nested-types.c @CFA_BINDIR@/@CFA_NAME@790 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}791 792 nested-types-ERR2: nested-types.c @CFA_BINDIR@/@CFA_NAME@793 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR2 ${<} -o ${@}794 795 789 # Constructor/destructor tests 796 790 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.c @CFA_BINDIR@/@CFA_NAME@
Note:
See TracChangeset
for help on using the changeset viewer.