Changeset f53acdf8 for src/SymTab
- Timestamp:
- Jul 19, 2019, 2:16:01 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 4eb43fa
- Parents:
- 1f1c102 (diff), 8ac3b0e (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. - Location:
- src/SymTab
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Indexer.cc
r1f1c102 rf53acdf8 74 74 } 75 75 76 Indexer::Indexer() 77 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 78 prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; }76 Indexer::Indexer() 77 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 78 prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; } 79 79 80 80 Indexer::~Indexer() { … … 84 84 void Indexer::lazyInitScope() { 85 85 if ( repScope < scope ) { 86 ++* stats().lazy_scopes;86 ++* stats().lazy_scopes; 87 87 // create rollback 88 prevScope = std::make_shared<Indexer>( * this );88 prevScope = std::make_shared<Indexer>( * this ); 89 89 // update repScope 90 90 repScope = scope; … … 95 95 ++scope; 96 96 97 ++* stats().new_scopes;97 ++* stats().new_scopes; 98 98 stats().avg_scope_depth->push( scope ); 99 99 stats().max_scope_depth->push( scope ); … … 103 103 if ( repScope == scope ) { 104 104 Ptr prev = prevScope; // make sure prevScope stays live 105 * this = std::move(*prevScope); // replace with previous scope105 * this = std::move(* prevScope); // replace with previous scope 106 106 } 107 107 … … 109 109 } 110 110 111 void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const {112 ++* stats().lookup_calls;111 void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const { 112 ++* stats().lookup_calls; 113 113 if ( ! idTable ) return; 114 114 115 ++* stats().map_lookups;115 ++* stats().map_lookups; 116 116 auto decls = idTable->find( id ); 117 117 if ( decls == idTable->end() ) return; … … 122 122 } 123 123 124 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {125 ++* stats().lookup_calls;124 const NamedTypeDecl * Indexer::lookupType( const std::string & id ) const { 125 ++* stats().lookup_calls; 126 126 if ( ! typeTable ) return nullptr; 127 ++* stats().map_lookups;127 ++* stats().map_lookups; 128 128 auto it = typeTable->find( id ); 129 129 return it == typeTable->end() ? nullptr : it->second.decl; 130 130 } 131 131 132 StructDecl *Indexer::lookupStruct( const std::string &id ) const {133 ++* stats().lookup_calls;132 const StructDecl * Indexer::lookupStruct( const std::string & id ) const { 133 ++* stats().lookup_calls; 134 134 if ( ! structTable ) return nullptr; 135 ++* stats().map_lookups;135 ++* stats().map_lookups; 136 136 auto it = structTable->find( id ); 137 137 return it == structTable->end() ? nullptr : it->second.decl; 138 138 } 139 139 140 EnumDecl *Indexer::lookupEnum( const std::string &id ) const {141 ++* stats().lookup_calls;140 const EnumDecl * Indexer::lookupEnum( const std::string & id ) const { 141 ++* stats().lookup_calls; 142 142 if ( ! enumTable ) return nullptr; 143 ++* stats().map_lookups;143 ++* stats().map_lookups; 144 144 auto it = enumTable->find( id ); 145 145 return it == enumTable->end() ? nullptr : it->second.decl; 146 146 } 147 147 148 UnionDecl *Indexer::lookupUnion( const std::string &id ) const {149 ++* stats().lookup_calls;148 const UnionDecl * Indexer::lookupUnion( const std::string & id ) const { 149 ++* stats().lookup_calls; 150 150 if ( ! unionTable ) return nullptr; 151 ++* stats().map_lookups;151 ++* stats().map_lookups; 152 152 auto it = unionTable->find( id ); 153 153 return it == unionTable->end() ? nullptr : it->second.decl; 154 154 } 155 155 156 TraitDecl *Indexer::lookupTrait( const std::string &id ) const {157 ++* stats().lookup_calls;156 const TraitDecl * Indexer::lookupTrait( const std::string & id ) const { 157 ++* stats().lookup_calls; 158 158 if ( ! traitTable ) return nullptr; 159 ++* stats().map_lookups;159 ++* stats().map_lookups; 160 160 auto it = traitTable->find( id ); 161 161 return it == traitTable->end() ? nullptr : it->second.decl; 162 162 } 163 163 164 const Indexer * Indexer::atScope( unsigned long target ) const {164 const Indexer * Indexer::atScope( unsigned long target ) const { 165 165 // by lazy construction, final indexer in list has repScope 0, cannot be > target 166 166 // otherwise, will find first scope representing the target 167 const Indexer * indexer = this;167 const Indexer * indexer = this; 168 168 while ( indexer->repScope > target ) { 169 169 indexer = indexer->prevScope.get(); … … 172 172 } 173 173 174 NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {174 const NamedTypeDecl * Indexer::globalLookupType( const std::string & id ) const { 175 175 return atScope( 0 )->lookupType( id ); 176 176 } 177 177 178 StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {178 const StructDecl * Indexer::globalLookupStruct( const std::string & id ) const { 179 179 return atScope( 0 )->lookupStruct( id ); 180 180 } 181 181 182 UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const {182 const UnionDecl * Indexer::globalLookupUnion( const std::string & id ) const { 183 183 return atScope( 0 )->lookupUnion( id ); 184 184 } 185 185 186 EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const {186 const EnumDecl * Indexer::globalLookupEnum( const std::string & id ) const { 187 187 return atScope( 0 )->lookupEnum( id ); 188 188 } 189 189 190 bool isFunction( DeclarationWithType * decl ) {190 bool isFunction( const DeclarationWithType * decl ) { 191 191 return GenPoly::getFunctionType( decl->get_type() ); 192 192 } 193 193 194 bool isObject( DeclarationWithType * decl ) {194 bool isObject( const DeclarationWithType * decl ) { 195 195 return ! isFunction( decl ); 196 196 } 197 197 198 bool isDefinition( DeclarationWithType * decl ) {199 if ( FunctionDecl * func = dynamic_cast<FunctionDecl * >( decl ) ) {198 bool isDefinition( const DeclarationWithType * decl ) { 199 if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) { 200 200 // a function is a definition if it has a body 201 201 return func->statements; … … 207 207 } 208 208 209 210 bool Indexer::addedIdConflicts( 211 const Indexer::IdData & existing, DeclarationWithType *added,212 Indexer::OnConflict handleConflicts, BaseSyntaxNode* deleteStmt ) {213 // if we're giving the same name mangling to things of different types then there is 209 210 bool Indexer::addedIdConflicts( 211 const Indexer::IdData & existing, const DeclarationWithType * added, 212 Indexer::OnConflict handleConflicts, const Declaration * deleteStmt ) { 213 // if we're giving the same name mangling to things of different types then there is 214 214 // something wrong 215 215 assert( (isObject( added ) && isObject( existing.id ) ) … … 219 219 // new definition shadows the autogenerated one, even at the same scope 220 220 return false; 221 } else if ( LinkageSpec::isMangled( added->linkage ) 222 || ResolvExpr::typesCompatible( 221 } else if ( LinkageSpec::isMangled( added->linkage ) 222 || ResolvExpr::typesCompatible( 223 223 added->get_type(), existing.id->get_type(), Indexer() ) ) { 224 224 … … 238 238 if ( isDefinition( added ) && isDefinition( existing.id ) ) { 239 239 if ( handleConflicts.mode == OnConflict::Error ) { 240 SemanticError( added, 241 isFunction( added ) ? 242 "duplicate function definition for " : 240 SemanticError( added, 241 isFunction( added ) ? 242 "duplicate function definition for " : 243 243 "duplicate object definition for " ); 244 244 } … … 255 255 } 256 256 257 bool Indexer::hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const {257 bool Indexer::hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const { 258 258 if ( ! idTable ) return false; 259 259 260 ++* stats().map_lookups;260 ++* stats().map_lookups; 261 261 auto decls = idTable->find( id ); 262 262 if ( decls == idTable->end() ) return false; … … 270 270 } 271 271 } 272 272 273 273 return false; 274 274 } 275 275 276 bool Indexer::hasIncompatibleCDecl( 277 const std::string &id, const std::string &mangleName ) const { 276 bool Indexer::hasIncompatibleCDecl(const std::string & id, const std::string &mangleName ) const { 278 277 if ( ! idTable ) return false; 279 278 280 ++* stats().map_lookups;279 ++* stats().map_lookups; 281 280 auto decls = idTable->find( id ); 282 281 if ( decls == idTable->end() ) return false; … … 295 294 296 295 /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function 297 std::string getOtypeKey( FunctionDecl* function ) {296 std::string getOtypeKey( const FunctionDecl * function ) { 298 297 auto& params = function->type->parameters; 299 298 assert( ! params.empty() ); 300 299 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 301 Type * base = InitTweak::getPointerBase( params.front()->get_type() );300 Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 302 301 assert( base ); 303 302 return Mangler::mangle( base ); 304 303 } 305 304 306 /// gets the declaration for the function acting on a type specified by otype key, 305 /// gets the declaration for the function acting on a type specified by otype key, 307 306 /// nullptr if none such 308 FunctionDecl * getFunctionForOtype(DeclarationWithType * decl, const std::string& otypeKey ) {309 FunctionDecl * func = dynamic_cast<FunctionDecl * >( decl );307 const FunctionDecl * getFunctionForOtype( const DeclarationWithType * decl, const std::string& otypeKey ) { 308 const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ); 310 309 if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr; 311 310 return func; 312 311 } 313 312 314 bool Indexer::removeSpecialOverrides( 315 Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) { 316 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 317 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular, 318 // if the user defines a default ctor, then the generated default ctor is unavailable, 319 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 320 // field ctors are available. If the user defines any ctor then the generated default ctor 321 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 322 // anything that looks like a copy constructor, then the generated copy constructor is 313 bool Indexer::removeSpecialOverrides(Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) { 314 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 315 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular, 316 // if the user defines a default ctor, then the generated default ctor is unavailable, 317 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 318 // field ctors are available. If the user defines any ctor then the generated default ctor 319 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 320 // anything that looks like a copy constructor, then the generated copy constructor is 323 321 // unavailable, and likewise for the assignment operator. 324 322 325 323 // only relevant on function declarations 326 FunctionDecl * function = dynamic_cast<FunctionDecl * >( data.id );324 const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( data.id ); 327 325 if ( ! function ) return true; 328 326 // only need to perform this check for constructors, destructors, and assignment functions … … 340 338 std::vector< MangleTable::value_type > deleted; 341 339 bool alreadyUserDefinedFunc = false; 342 343 for ( const auto& entry : * mangleTable ) {340 341 for ( const auto& entry : * mangleTable ) { 344 342 // skip decls that aren't functions or are for the wrong type 345 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );343 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 346 344 if ( ! decl ) continue; 347 345 … … 368 366 // perform removals from mangle table, and deletions if necessary 369 367 for ( const auto& key : removed ) { 370 ++* stats().map_mutations;368 ++* stats().map_mutations; 371 369 mangleTable = mangleTable->erase( key ); 372 370 } 373 371 if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) { 374 ++* stats().map_mutations;372 ++* stats().map_mutations; 375 373 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 376 374 } … … 379 377 // if this is the first user-defined function, delete non-user-defined overloads 380 378 std::vector< MangleTable::value_type > deleted; 381 382 for ( const auto& entry : * mangleTable ) {379 380 for ( const auto& entry : * mangleTable ) { 383 381 // skip decls that aren't functions or are for the wrong type 384 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );382 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 385 383 if ( ! decl ) continue; 386 384 … … 402 400 // this needs to be a separate loop because of iterator invalidation 403 401 for ( const auto& entry : deleted ) { 404 ++* stats().map_mutations;402 ++* stats().map_mutations; 405 403 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 406 404 } … … 408 406 // this is an overridable generated function 409 407 // if there already exists a matching user-defined function, delete this appropriately 410 for ( const auto& entry : * mangleTable ) {408 for ( const auto& entry : * mangleTable ) { 411 409 // skip decls that aren't functions or are for the wrong type 412 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );410 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 413 411 if ( ! decl ) continue; 414 412 … … 418 416 if ( dataIsCopyFunc ) { 419 417 // remove current function if exists a user-defined copy function 420 // since the signatures for copy functions don't need to match exactly, using 418 // since the signatures for copy functions don't need to match exactly, using 421 419 // a delete statement is the wrong approach 422 420 if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false; … … 428 426 } 429 427 } 430 428 431 429 // nothing (more) to fix, return true 432 430 return true; 433 431 } 434 432 435 void Indexer::addId( 436 DeclarationWithType *decl, OnConflict handleConflicts, Expression * baseExpr, 437 BaseSyntaxNode * deleteStmt ) { 438 ++*stats().add_calls; 433 void Indexer::addId(const DeclarationWithType * decl, OnConflict handleConflicts, const Expression * baseExpr, 434 const Declaration * deleteStmt ) { 435 ++* stats().add_calls; 439 436 const std::string &name = decl->name; 440 437 if ( name == "" ) return; 441 438 442 439 std::string mangleName; 443 440 if ( LinkageSpec::isOverridable( decl->linkage ) ) { 444 // mangle the name without including the appropriate suffix, so overridable routines 441 // mangle the name without including the appropriate suffix, so overridable routines 445 442 // are placed into the same "bucket" as their user defined versions. 446 443 mangleName = Mangler::mangle( decl, false ); … … 449 446 } // if 450 447 451 // this ensures that no two declarations with the same unmangled name at the same scope 448 // this ensures that no two declarations with the same unmangled name at the same scope 452 449 // both have C linkage 453 450 if ( LinkageSpec::isMangled( decl->linkage ) ) { … … 457 454 } 458 455 } else { 459 // NOTE: only correct if name mangling is completely isomorphic to C 456 // NOTE: only correct if name mangling is completely isomorphic to C 460 457 // type-compatibility, which it may not be. 461 458 if ( hasIncompatibleCDecl( name, mangleName ) ) { … … 470 467 mangleTable = MangleTable::new_ptr(); 471 468 } else { 472 ++* stats().map_lookups;469 ++* stats().map_lookups; 473 470 auto decls = idTable->find( name ); 474 471 if ( decls == idTable->end() ) { … … 477 474 mangleTable = decls->second; 478 475 // skip in-scope repeat declarations of same identifier 479 ++* stats().map_lookups;476 ++* stats().map_lookups; 480 477 auto existing = mangleTable->find( mangleName ); 481 478 if ( existing != mangleTable->end() … … 486 483 // set delete expression for conflicting identifier 487 484 lazyInitScope(); 488 * stats().map_mutations += 2;485 * stats().map_mutations += 2; 489 486 idTable = idTable->set( 490 487 name, 491 mangleTable->set( 492 mangleName, 488 mangleTable->set( 489 mangleName, 493 490 IdData{ existing->second, handleConflicts.deleteStmt } ) ); 494 491 } … … 504 501 // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary 505 502 if ( ! removeSpecialOverrides( data, mangleTable ) ) return; 506 * stats().map_mutations += 2;503 * stats().map_mutations += 2; 507 504 idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) ); 508 505 } 509 506 510 void Indexer::addId( DeclarationWithType * decl,Expression * baseExpr ) {507 void Indexer::addId( const DeclarationWithType * decl, const Expression * baseExpr ) { 511 508 // default handling of conflicts is to raise an error 512 509 addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr ); 513 510 } 514 511 515 void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode* deleteStmt ) {512 void Indexer::addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt ) { 516 513 // default handling of conflicts is to raise an error 517 514 addId( decl, OnConflict::error(), nullptr, deleteStmt ); 518 515 } 519 516 520 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {517 bool addedTypeConflicts( const NamedTypeDecl * existing, const NamedTypeDecl * added ) { 521 518 if ( existing->base == nullptr ) { 522 519 return false; … … 530 527 } 531 528 } 532 // does not need to be added to the table if both existing and added have a base that are 529 // does not need to be added to the table if both existing and added have a base that are 533 530 // the same 534 531 return true; 535 532 } 536 533 537 void Indexer::addType( NamedTypeDecl *decl ) {538 ++* stats().add_calls;539 const std::string & id = decl->name;540 541 if ( ! typeTable ) { 534 void Indexer::addType( const NamedTypeDecl * decl ) { 535 ++* stats().add_calls; 536 const std::string & id = decl->name; 537 538 if ( ! typeTable ) { 542 539 typeTable = TypeTable::new_ptr(); 543 540 } else { 544 ++* stats().map_lookups;541 ++* stats().map_lookups; 545 542 auto existing = typeTable->find( id ); 546 if ( existing != typeTable->end() 547 && existing->second.scope == scope 543 if ( existing != typeTable->end() 544 && existing->second.scope == scope 548 545 && addedTypeConflicts( existing->second.decl, decl ) ) return; 549 546 } 550 547 551 548 lazyInitScope(); 552 ++* stats().map_mutations;549 ++* stats().map_mutations; 553 550 typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } ); 554 551 } 555 552 556 bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) {553 bool addedDeclConflicts( const AggregateDecl * existing, const AggregateDecl * added ) { 557 554 if ( ! existing->body ) { 558 555 return false; … … 563 560 } 564 561 565 void Indexer::addStruct( const std::string & id ) {562 void Indexer::addStruct( const std::string & id ) { 566 563 addStruct( new StructDecl( id ) ); 567 564 } 568 565 569 void Indexer::addStruct( StructDecl *decl ) {570 ++* stats().add_calls;571 const std::string & id = decl->name;566 void Indexer::addStruct( const StructDecl * decl ) { 567 ++* stats().add_calls; 568 const std::string & id = decl->name; 572 569 573 570 if ( ! structTable ) { 574 571 structTable = StructTable::new_ptr(); 575 572 } else { 576 ++* stats().map_lookups;573 ++* stats().map_lookups; 577 574 auto existing = structTable->find( id ); 578 if ( existing != structTable->end() 579 && existing->second.scope == scope 575 if ( existing != structTable->end() 576 && existing->second.scope == scope 580 577 && addedDeclConflicts( existing->second.decl, decl ) ) return; 581 578 } 582 579 583 580 lazyInitScope(); 584 ++* stats().map_mutations;581 ++* stats().map_mutations; 585 582 structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } ); 586 583 } 587 584 588 void Indexer::addEnum( EnumDecl *decl ) {589 ++* stats().add_calls;590 const std::string & id = decl->name;585 void Indexer::addEnum( const EnumDecl * decl ) { 586 ++* stats().add_calls; 587 const std::string & id = decl->name; 591 588 592 589 if ( ! enumTable ) { 593 590 enumTable = EnumTable::new_ptr(); 594 591 } else { 595 ++* stats().map_lookups;592 ++* stats().map_lookups; 596 593 auto existing = enumTable->find( id ); 597 if ( existing != enumTable->end() 598 && existing->second.scope == scope 594 if ( existing != enumTable->end() 595 && existing->second.scope == scope 599 596 && addedDeclConflicts( existing->second.decl, decl ) ) return; 600 597 } 601 598 602 599 lazyInitScope(); 603 ++* stats().map_mutations;600 ++* stats().map_mutations; 604 601 enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } ); 605 602 } 606 603 607 void Indexer::addUnion( const std::string & id ) {604 void Indexer::addUnion( const std::string & id ) { 608 605 addUnion( new UnionDecl( id ) ); 609 606 } 610 607 611 void Indexer::addUnion( UnionDecl *decl ) {612 ++* stats().add_calls;613 const std::string & id = decl->name;608 void Indexer::addUnion( const UnionDecl * decl ) { 609 ++* stats().add_calls; 610 const std::string & id = decl->name; 614 611 615 612 if ( ! unionTable ) { 616 613 unionTable = UnionTable::new_ptr(); 617 614 } else { 618 ++* stats().map_lookups;615 ++* stats().map_lookups; 619 616 auto existing = unionTable->find( id ); 620 if ( existing != unionTable->end() 621 && existing->second.scope == scope 617 if ( existing != unionTable->end() 618 && existing->second.scope == scope 622 619 && addedDeclConflicts( existing->second.decl, decl ) ) return; 623 620 } 624 621 625 622 lazyInitScope(); 626 ++* stats().map_mutations;623 ++* stats().map_mutations; 627 624 unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } ); 628 625 } 629 626 630 void Indexer::addTrait( TraitDecl *decl ) {631 ++* stats().add_calls;632 const std::string & id = decl->name;627 void Indexer::addTrait( const TraitDecl * decl ) { 628 ++* stats().add_calls; 629 const std::string & id = decl->name; 633 630 634 631 if ( ! traitTable ) { 635 632 traitTable = TraitTable::new_ptr(); 636 633 } else { 637 ++* stats().map_lookups;634 ++* stats().map_lookups; 638 635 auto existing = traitTable->find( id ); 639 if ( existing != traitTable->end() 640 && existing->second.scope == scope 636 if ( existing != traitTable->end() 637 && existing->second.scope == scope 641 638 && addedDeclConflicts( existing->second.decl, decl ) ) return; 642 639 } 643 640 644 641 lazyInitScope(); 645 ++* stats().map_mutations;642 ++* stats().map_mutations; 646 643 traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } ); 647 644 } 648 645 649 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, 650 OnConflict handleConflicts ) { 646 void Indexer::addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ) { 651 647 for ( Declaration * decl : aggr->members ) { 652 648 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 653 649 addId( dwt, handleConflicts, expr ); 654 650 if ( dwt->name == "" ) { 655 Type * t = dwt->get_type()->stripReferences();656 if ( dynamic_cast< StructInstType*>( t ) || dynamic_cast<UnionInstType*>( t ) ) {651 const Type * t = dwt->get_type()->stripReferences(); 652 if ( dynamic_cast<const StructInstType *>( t ) || dynamic_cast<const UnionInstType *>( t ) ) { 657 653 Expression * base = expr->clone(); 658 654 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost? … … 665 661 } 666 662 667 void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode* withStmt ) {668 for ( Expression * expr : withExprs ) {663 void Indexer::addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt ) { 664 for ( const Expression * expr : withExprs ) { 669 665 if ( expr->result ) { 670 666 AggregateDecl * aggr = expr->result->stripReferences()->getAggr(); … … 689 685 } 690 686 691 void Indexer::addFunctionType( FunctionType * ftype ) {687 void Indexer::addFunctionType( const FunctionType * ftype ) { 692 688 addTypes( ftype->forall ); 693 689 addIds( ftype->returnVals ); … … 700 696 Expression * base = baseExpr->clone(); 701 697 ResolvExpr::referenceToRvalueConversion( base, cost ); 702 ret = new MemberExpr( id, base );698 ret = new MemberExpr( const_cast<DeclarationWithType *>(id), base ); 703 699 // xxx - this introduces hidden environments, for now remove them. 704 700 // std::swap( base->env, ret->env ); … … 706 702 base->env = nullptr; 707 703 } else { 708 ret = new VariableExpr( id);709 } 710 if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt);704 ret = new VariableExpr( const_cast<DeclarationWithType *>(id) ); 705 } 706 if ( deleteStmt ) ret = new DeletedExpr( ret, const_cast<Declaration *>(deleteStmt) ); 711 707 return ret; 712 708 } -
src/SymTab/Indexer.h
r1f1c102 rf53acdf8 34 34 virtual ~Indexer(); 35 35 36 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 36 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 37 37 // tell the indexer explicitly when scopes begin and end 38 38 void enterScope(); … … 40 40 41 41 struct IdData { 42 DeclarationWithType * id = nullptr;43 Expression * baseExpr = nullptr; // WithExpr42 const DeclarationWithType * id = nullptr; 43 const Expression * baseExpr = nullptr; // WithExpr 44 44 45 45 /// non-null if this declaration is deleted 46 BaseSyntaxNode* deleteStmt = nullptr;46 const Declaration * deleteStmt = nullptr; 47 47 /// scope of identifier 48 48 unsigned long scope = 0; … … 50 50 // NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members. 51 51 IdData() = default; 52 IdData( 53 DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode* deleteStmt,54 unsigned long scope ) 52 IdData( 53 const DeclarationWithType * id, const Expression * baseExpr, const Declaration * deleteStmt, 54 unsigned long scope ) 55 55 : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {} 56 IdData( const IdData& o, BaseSyntaxNode* deleteStmt )56 IdData( const IdData& o, const Declaration * deleteStmt ) 57 57 : id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {} 58 58 … … 61 61 62 62 /// Gets all declarations with the given ID 63 void lookupId( const std::string & id, std::list< IdData > &out ) const;63 void lookupId( const std::string & id, std::list< IdData > &out ) const; 64 64 /// Gets the top-most type declaration with the given ID 65 NamedTypeDecl *lookupType( const std::string &id ) const;65 const NamedTypeDecl * lookupType( const std::string & id ) const; 66 66 /// Gets the top-most struct declaration with the given ID 67 StructDecl *lookupStruct( const std::string &id ) const;67 const StructDecl * lookupStruct( const std::string & id ) const; 68 68 /// Gets the top-most enum declaration with the given ID 69 EnumDecl *lookupEnum( const std::string &id ) const;69 const EnumDecl * lookupEnum( const std::string & id ) const; 70 70 /// Gets the top-most union declaration with the given ID 71 UnionDecl *lookupUnion( const std::string &id ) const;71 const UnionDecl * lookupUnion( const std::string & id ) const; 72 72 /// Gets the top-most trait declaration with the given ID 73 TraitDecl *lookupTrait( const std::string &id ) const;73 const TraitDecl * lookupTrait( const std::string & id ) const; 74 74 75 75 /// Gets the type declaration with the given ID at global scope 76 NamedTypeDecl *globalLookupType( const std::string &id ) const;76 const NamedTypeDecl * globalLookupType( const std::string & id ) const; 77 77 /// Gets the struct declaration with the given ID at global scope 78 StructDecl *globalLookupStruct( const std::string &id ) const;78 const StructDecl * globalLookupStruct( const std::string & id ) const; 79 79 /// Gets the union declaration with the given ID at global scope 80 UnionDecl *globalLookupUnion( const std::string &id ) const;80 const UnionDecl * globalLookupUnion( const std::string & id ) const; 81 81 /// Gets the enum declaration with the given ID at global scope 82 EnumDecl *globalLookupEnum( const std::string &id ) const;82 const EnumDecl * globalLookupEnum( const std::string & id ) const; 83 83 84 void addId( DeclarationWithType * decl,Expression * baseExpr = nullptr );85 void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode* deleteStmt );84 void addId( const DeclarationWithType * decl, const Expression * baseExpr = nullptr ); 85 void addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt ); 86 86 87 void addType( NamedTypeDecl *decl );88 void addStruct( const std::string & id );89 void addStruct( StructDecl *decl );90 void addEnum( EnumDecl *decl );91 void addUnion( const std::string & id );92 void addUnion( UnionDecl *decl );93 void addTrait( TraitDecl *decl );87 void addType( const NamedTypeDecl * decl ); 88 void addStruct( const std::string & id ); 89 void addStruct( const StructDecl * decl ); 90 void addEnum( const EnumDecl * decl ); 91 void addUnion( const std::string & id ); 92 void addUnion( const UnionDecl * decl ); 93 void addTrait( const TraitDecl * decl ); 94 94 95 95 /// adds all of the IDs from WithStmt exprs 96 void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode* withStmt );96 void addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt ); 97 97 98 98 /// convenience function for adding a list of Ids to the indexer … … 103 103 104 104 /// convenience function for adding all of the declarations in a function type to the indexer 105 void addFunctionType( FunctionType * ftype );105 void addFunctionType( const FunctionType * ftype ); 106 106 107 107 private: 108 /// Wraps a Decl * with a scope108 /// Wraps a Decl * with a scope 109 109 template<typename Decl> 110 110 struct Scoped { 111 Decl* decl; ///< declaration111 const Decl * decl; ///< declaration 112 112 unsigned long scope; ///< scope of this declaration 113 113 114 Scoped( Decl* d, unsigned long s) : decl(d), scope(s) {}114 Scoped(const Decl * d, unsigned long s) : decl(d), scope(s) {} 115 115 }; 116 116 … … 140 140 141 141 /// Gets the indexer at the given scope 142 const Indexer * atScope( unsigned long scope ) const;142 const Indexer * atScope( unsigned long scope ) const; 143 143 144 /// Removes matching autogenerated constructors and destructors so that they will not be 144 /// Removes matching autogenerated constructors and destructors so that they will not be 145 145 /// selected. If returns false, passed decl should not be added. 146 bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr& mangleTable );146 bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable ); 147 147 148 148 /// Options for handling identifier conflicts … … 152 152 Delete ///< Delete the earlier version with the delete statement 153 153 } mode; 154 BaseSyntaxNode* deleteStmt; ///< Statement that deletes this expression154 const Declaration * deleteStmt; ///< Statement that deletes this expression 155 155 156 156 private: 157 157 OnConflict() : mode(Error), deleteStmt(nullptr) {} 158 OnConflict( BaseSyntaxNode* d ) : mode(Delete), deleteStmt(d) {}158 OnConflict( const Declaration * d ) : mode(Delete), deleteStmt(d) {} 159 159 public: 160 160 OnConflict( const OnConflict& ) = default; 161 161 162 162 static OnConflict error() { return {}; } 163 static OnConflict deleteWith( BaseSyntaxNode* d ) { return { d }; }163 static OnConflict deleteWith( const Declaration * d ) { return { d }; } 164 164 }; 165 165 166 166 /// true if the existing identifier conflicts with the added identifier 167 167 bool addedIdConflicts( 168 const IdData & existing, DeclarationWithType * added, OnConflict handleConflicts,169 BaseSyntaxNode* deleteStmt );168 const IdData & existing, const DeclarationWithType * added, OnConflict handleConflicts, 169 const Declaration * deleteStmt ); 170 170 171 171 /// common code for addId, addDeletedId, etc. 172 void addId( 173 DeclarationWithType * decl, OnConflict handleConflicts, 174 Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr ); 172 void addId(const DeclarationWithType * decl, OnConflict handleConflicts, 173 const Expression * baseExpr = nullptr, const Declaration * deleteStmt = nullptr ); 175 174 176 175 /// adds all of the members of the Aggregate (addWith helper) 177 void addMembers( AggregateDecl * aggr,Expression * expr, OnConflict handleConflicts );176 void addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ); 178 177 179 178 /// returns true if there exists a declaration with C linkage and the given name with the same mangled name 180 bool hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const;179 bool hasCompatibleCDecl( const std::string & id, const std::string & mangleName ) const; 181 180 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name 182 bool hasIncompatibleCDecl( const std::string & id, const std::string &mangleName ) const;181 bool hasIncompatibleCDecl( const std::string & id, const std::string & mangleName ) const; 183 182 }; 184 183 } // namespace SymTab -
src/SymTab/Mangler.cc
r1f1c102 rf53acdf8 42 42 Mangler_old( const Mangler_old & ) = delete; 43 43 44 void previsit( BaseSyntaxNode * ) { visit_children = false; }45 46 void postvisit( ObjectDecl * declaration );47 void postvisit( FunctionDecl * declaration );48 void postvisit( TypeDecl * declaration );49 50 void postvisit( VoidType * voidType );51 void postvisit( BasicType * basicType );52 void postvisit( PointerType * pointerType );53 void postvisit( ArrayType * arrayType );54 void postvisit( ReferenceType * refType );55 void postvisit( FunctionType * functionType );56 void postvisit( StructInstType * aggregateUseType );57 void postvisit( UnionInstType * aggregateUseType );58 void postvisit( EnumInstType * aggregateUseType );59 void postvisit( TypeInstType * aggregateUseType );60 void postvisit( TraitInstType * inst );61 void postvisit( TupleType * tupleType );62 void postvisit( VarArgsType * varArgsType );63 void postvisit( ZeroType * zeroType );64 void postvisit( OneType * oneType );65 void postvisit( QualifiedType * qualType );44 void previsit( const BaseSyntaxNode * ) { visit_children = false; } 45 46 void postvisit( const ObjectDecl * declaration ); 47 void postvisit( const FunctionDecl * declaration ); 48 void postvisit( const TypeDecl * declaration ); 49 50 void postvisit( const VoidType * voidType ); 51 void postvisit( const BasicType * basicType ); 52 void postvisit( const PointerType * pointerType ); 53 void postvisit( const ArrayType * arrayType ); 54 void postvisit( const ReferenceType * refType ); 55 void postvisit( const FunctionType * functionType ); 56 void postvisit( const StructInstType * aggregateUseType ); 57 void postvisit( const UnionInstType * aggregateUseType ); 58 void postvisit( const EnumInstType * aggregateUseType ); 59 void postvisit( const TypeInstType * aggregateUseType ); 60 void postvisit( const TraitInstType * inst ); 61 void postvisit( const TupleType * tupleType ); 62 void postvisit( const VarArgsType * varArgsType ); 63 void postvisit( const ZeroType * zeroType ); 64 void postvisit( const OneType * oneType ); 65 void postvisit( const QualifiedType * qualType ); 66 66 67 67 std::string get_mangleName() { return mangleName.str(); } … … 79 79 80 80 public: 81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 82 82 int nextVarNum, const VarMapType& varNums ); 83 83 84 84 private: 85 void mangleDecl( DeclarationWithType *declaration );86 void mangleRef( ReferenceToType *refType, std::string prefix );87 88 void printQualifiers( Type *type );85 void mangleDecl( const DeclarationWithType * declaration ); 86 void mangleRef( const ReferenceToType * refType, std::string prefix ); 87 88 void printQualifiers( const Type *type ); 89 89 }; // Mangler_old 90 90 } // namespace 91 91 92 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {92 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) { 93 93 PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams ); 94 94 maybeAccept( decl, mangler ); … … 96 96 } 97 97 98 std::string mangleType( Type * ty ) {98 std::string mangleType( const Type * ty ) { 99 99 PassVisitor<Mangler_old> mangler( false, true, true ); 100 100 maybeAccept( ty, mangler ); … … 102 102 } 103 103 104 std::string mangleConcrete( Type * ty ) {104 std::string mangleConcrete( const Type * ty ) { 105 105 PassVisitor<Mangler_old> mangler( false, false, false ); 106 106 maybeAccept( ty, mangler ); … … 110 110 namespace { 111 111 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) 112 : nextVarNum( 0 ), isTopLevel( true ), 113 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 112 : nextVarNum( 0 ), isTopLevel( true ), 113 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 114 114 mangleGenericParams( mangleGenericParams ) {} 115 116 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 115 116 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 117 117 int nextVarNum, const VarMapType& varNums ) 118 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 119 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 118 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 119 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 120 120 mangleGenericParams( mangleGenericParams ) {} 121 121 122 void Mangler_old::mangleDecl( DeclarationWithType * declaration ) {122 void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) { 123 123 bool wasTopLevel = isTopLevel; 124 124 if ( isTopLevel ) { … … 150 150 } 151 151 152 void Mangler_old::postvisit( ObjectDecl * declaration ) {152 void Mangler_old::postvisit( const ObjectDecl * declaration ) { 153 153 mangleDecl( declaration ); 154 154 } 155 155 156 void Mangler_old::postvisit( FunctionDecl * declaration ) {156 void Mangler_old::postvisit( const FunctionDecl * declaration ) { 157 157 mangleDecl( declaration ); 158 158 } 159 159 160 void Mangler_old::postvisit( VoidType * voidType ) {160 void Mangler_old::postvisit( const VoidType * voidType ) { 161 161 printQualifiers( voidType ); 162 162 mangleName << Encoding::void_t; 163 163 } 164 164 165 void Mangler_old::postvisit( BasicType * basicType ) {165 void Mangler_old::postvisit( const BasicType * basicType ) { 166 166 printQualifiers( basicType ); 167 assertf( basicType-> get_kind() < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->get_kind());168 mangleName << Encoding::basicTypes[ basicType-> get_kind()];169 } 170 171 void Mangler_old::postvisit( PointerType * pointerType ) {167 assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind ); 168 mangleName << Encoding::basicTypes[ basicType->kind ]; 169 } 170 171 void Mangler_old::postvisit( const PointerType * pointerType ) { 172 172 printQualifiers( pointerType ); 173 173 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers … … 176 176 } 177 177 178 void Mangler_old::postvisit( ArrayType * arrayType ) {178 void Mangler_old::postvisit( const ArrayType * arrayType ) { 179 179 // TODO: encode dimension 180 180 printQualifiers( arrayType ); … … 183 183 } 184 184 185 void Mangler_old::postvisit( ReferenceType * refType ) {185 void Mangler_old::postvisit( const ReferenceType * refType ) { 186 186 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload. 187 187 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.), … … 202 202 } 203 203 204 void Mangler_old::postvisit( FunctionType * functionType ) {204 void Mangler_old::postvisit( const FunctionType * functionType ) { 205 205 printQualifiers( functionType ); 206 206 mangleName << Encoding::function; … … 219 219 } 220 220 221 void Mangler_old::mangleRef( ReferenceToType * refType, std::string prefix ) {221 void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) { 222 222 printQualifiers( refType ); 223 223 … … 225 225 226 226 if ( mangleGenericParams ) { 227 std::list< Expression* >& params = refType->parameters;227 const std::list< Expression* > & params = refType->parameters; 228 228 if ( ! params.empty() ) { 229 229 mangleName << "_"; 230 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param) {231 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );232 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString( *param));230 for ( const Expression * param : params ) { 231 const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param ); 232 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 233 233 maybeAccept( paramType->type, *visitor ); 234 234 } … … 238 238 } 239 239 240 void Mangler_old::postvisit( StructInstType * aggregateUseType ) {240 void Mangler_old::postvisit( const StructInstType * aggregateUseType ) { 241 241 mangleRef( aggregateUseType, Encoding::struct_t ); 242 242 } 243 243 244 void Mangler_old::postvisit( UnionInstType * aggregateUseType ) {244 void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) { 245 245 mangleRef( aggregateUseType, Encoding::union_t ); 246 246 } 247 247 248 void Mangler_old::postvisit( EnumInstType * aggregateUseType ) {248 void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) { 249 249 mangleRef( aggregateUseType, Encoding::enum_t ); 250 250 } 251 251 252 void Mangler_old::postvisit( TypeInstType * typeInst ) {252 void Mangler_old::postvisit( const TypeInstType * typeInst ) { 253 253 VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); 254 254 if ( varNum == varNums.end() ) { … … 266 266 } 267 267 268 void Mangler_old::postvisit( TraitInstType * inst ) {268 void Mangler_old::postvisit( const TraitInstType * inst ) { 269 269 printQualifiers( inst ); 270 270 mangleName << inst->name.size() << inst->name; 271 271 } 272 272 273 void Mangler_old::postvisit( TupleType * tupleType ) {273 void Mangler_old::postvisit( const TupleType * tupleType ) { 274 274 printQualifiers( tupleType ); 275 275 mangleName << Encoding::tuple << tupleType->types.size(); … … 277 277 } 278 278 279 void Mangler_old::postvisit( VarArgsType * varArgsType ) {279 void Mangler_old::postvisit( const VarArgsType * varArgsType ) { 280 280 printQualifiers( varArgsType ); 281 281 static const std::string vargs = "__builtin_va_list"; … … 283 283 } 284 284 285 void Mangler_old::postvisit( ZeroType * ) {285 void Mangler_old::postvisit( const ZeroType * ) { 286 286 mangleName << Encoding::zero; 287 287 } 288 288 289 void Mangler_old::postvisit( OneType * ) {289 void Mangler_old::postvisit( const OneType * ) { 290 290 mangleName << Encoding::one; 291 291 } 292 292 293 void Mangler_old::postvisit( QualifiedType * qualType ) {293 void Mangler_old::postvisit( const QualifiedType * qualType ) { 294 294 bool inqual = inQualifiedType; 295 295 if (! inqual ) { … … 307 307 } 308 308 309 void Mangler_old::postvisit( TypeDecl * decl ) {309 void Mangler_old::postvisit( const TypeDecl * decl ) { 310 310 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be 311 311 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa. … … 314 314 // aside from the assert false. 315 315 assertf(false, "Mangler_old should not visit typedecl: %s", toCString(decl)); 316 assertf( decl-> get_kind() < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->get_kind());317 mangleName << Encoding::typeVariables[ decl-> get_kind()] << ( decl->name.length() ) << decl->name;316 assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind ); 317 mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name; 318 318 } 319 319 … … 324 324 } 325 325 326 void Mangler_old::printQualifiers( Type * type ) {326 void Mangler_old::printQualifiers( const Type * type ) { 327 327 // skip if not including qualifiers 328 328 if ( typeMode ) return; 329 if ( ! type-> get_forall().empty() ) {329 if ( ! type->forall.empty() ) { 330 330 std::list< std::string > assertionNames; 331 331 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 332 332 mangleName << Encoding::forall; 333 for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i) {334 switch ( (*i)->get_kind()) {333 for ( const TypeDecl * i : type->forall ) { 334 switch ( i->kind ) { 335 335 case TypeDecl::Dtype: 336 336 dcount++; … … 345 345 assert( false ); 346 346 } // switch 347 varNums[ (*i)->name ] = std::make_pair( nextVarNum, (int)(*i)->get_kind());348 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert) {349 PassVisitor<Mangler_old> sub_mangler( 347 varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind ); 348 for ( const DeclarationWithType * assert : i->assertions ) { 349 PassVisitor<Mangler_old> sub_mangler( 350 350 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 351 (*assert)->accept( sub_mangler );351 assert->accept( sub_mangler ); 352 352 assertionNames.push_back( sub_mangler.pass.get_mangleName() ); 353 353 acount++; … … 436 436 437 437 private: 438 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 438 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 439 439 int nextVarNum, const VarMapType& varNums ); 440 440 friend class ast::Pass<Mangler_new>; … … 457 457 namespace { 458 458 Mangler_new::Mangler_new( Mangle::Mode mode ) 459 : nextVarNum( 0 ), isTopLevel( true ), 459 : nextVarNum( 0 ), isTopLevel( true ), 460 460 mangleOverridable ( ! mode.no_overrideable ), 461 typeMode ( mode.type ), 461 typeMode ( mode.type ), 462 462 mangleGenericParams( ! mode.no_generic_params ) {} 463 464 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 463 464 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 465 465 int nextVarNum, const VarMapType& varNums ) 466 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 467 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 466 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 467 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 468 468 mangleGenericParams( mangleGenericParams ) {} 469 469 … … 693 693 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind ); 694 694 for ( const ast::DeclWithType * assert : decl->assertions ) { 695 ast::Pass<Mangler_new> sub_mangler( 695 ast::Pass<Mangler_new> sub_mangler( 696 696 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 697 697 assert->accept( sub_mangler ); -
src/SymTab/Mangler.h
r1f1c102 rf53acdf8 40 40 namespace Mangler { 41 41 /// Mangle syntax tree object; primary interface to clients 42 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );42 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true ); 43 43 44 44 /// Mangle a type name; secondary interface 45 std::string mangleType( Type* ty );45 std::string mangleType( const Type * ty ); 46 46 /// Mangle ignoring generic type parameters 47 std::string mangleConcrete( Type* ty );47 std::string mangleConcrete( const Type * ty ); 48 48 49 49 namespace Encoding { -
src/SymTab/Validate.cc
r1f1c102 rf53acdf8 119 119 120 120 private: 121 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl );121 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl ); 122 122 123 123 AggregateDecl * parentAggr = nullptr; … … 134 134 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 135 135 struct EnumAndPointerDecay_old { 136 void previsit( EnumDecl * aggregateDecl );137 void previsit( FunctionType * func );136 void previsit( EnumDecl * aggregateDecl ); 137 void previsit( FunctionType * func ); 138 138 }; 139 139 140 140 /// Associates forward declarations of aggregates with their definitions 141 141 struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting { 142 LinkReferenceToTypes_old( const Indexer * indexer );143 void postvisit( TypeInstType * typeInst );144 145 void postvisit( EnumInstType * enumInst );146 void postvisit( StructInstType * structInst );147 void postvisit( UnionInstType * unionInst );148 void postvisit( TraitInstType * traitInst );142 LinkReferenceToTypes_old( const Indexer * indexer ); 143 void postvisit( TypeInstType * typeInst ); 144 145 void postvisit( EnumInstType * enumInst ); 146 void postvisit( StructInstType * structInst ); 147 void postvisit( UnionInstType * unionInst ); 148 void postvisit( TraitInstType * traitInst ); 149 149 void previsit( QualifiedType * qualType ); 150 150 void postvisit( QualifiedType * qualType ); 151 151 152 void postvisit( EnumDecl * enumDecl );153 void postvisit( StructDecl * structDecl );154 void postvisit( UnionDecl * unionDecl );152 void postvisit( EnumDecl * enumDecl ); 153 void postvisit( StructDecl * structDecl ); 154 void postvisit( UnionDecl * unionDecl ); 155 155 void postvisit( TraitDecl * traitDecl ); 156 156 157 void previsit( StructDecl * structDecl );158 void previsit( UnionDecl * unionDecl );157 void previsit( StructDecl * structDecl ); 158 void previsit( UnionDecl * unionDecl ); 159 159 160 160 void renameGenericParams( std::list< TypeDecl * > & params ); 161 161 162 162 private: 163 const Indexer * local_indexer;163 const Indexer * local_indexer; 164 164 165 165 typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType; … … 239 239 240 240 template<typename AggDecl> 241 void handleAggregate( AggDecl * aggregateDecl );241 void handleAggregate( AggDecl * aggregateDecl ); 242 242 243 243 void previsit( StructDecl * aggregateDecl ); … … 252 252 static void verify( std::list< Declaration * > &translationUnit ); 253 253 254 void previsit( FunctionDecl * funcDecl );254 void previsit( FunctionDecl * funcDecl ); 255 255 }; 256 256 … … 287 287 Type::StorageClasses storageClasses; 288 288 289 void premutate( ObjectDecl * objectDecl );290 Expression * postmutate( CompoundLiteralExpr * compLitExpr );289 void premutate( ObjectDecl * objectDecl ); 290 Expression * postmutate( CompoundLiteralExpr * compLitExpr ); 291 291 }; 292 292 … … 393 393 } 394 394 395 void validateType( Type * type, const Indexer *indexer ) {395 void validateType( Type * type, const Indexer * indexer ) { 396 396 PassVisitor<EnumAndPointerDecay_old> epc; 397 397 PassVisitor<LinkReferenceToTypes_old> lrt( indexer ); … … 496 496 } 497 497 498 bool shouldHoist( Declaration * decl ) {498 bool shouldHoist( Declaration * decl ) { 499 499 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl ); 500 500 } … … 515 515 516 516 template< typename AggDecl > 517 void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) {517 void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) { 518 518 if ( parentAggr ) { 519 519 aggregateDecl->parent = parentAggr; … … 560 560 561 561 562 bool isTypedef( Declaration * decl ) {562 bool isTypedef( Declaration * decl ) { 563 563 return dynamic_cast< TypedefDecl * >( decl ); 564 564 } … … 571 571 572 572 template< typename AggDecl > 573 void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) {573 void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) { 574 574 filter( aggregateDecl->members, isTypedef, true ); 575 575 } … … 586 586 // remove and delete decl stmts 587 587 filter( compoundStmt->kids, [](Statement * stmt) { 588 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {588 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { 589 589 if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) { 590 590 return true; … … 595 595 } 596 596 597 void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) {597 void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) { 598 598 // Set the type of each member of the enumeration to be EnumConstant 599 599 for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) { 600 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i );600 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i ); 601 601 assert( obj ); 602 602 obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) ); … … 627 627 } 628 628 629 void EnumAndPointerDecay_old::previsit( FunctionType * func ) {629 void EnumAndPointerDecay_old::previsit( FunctionType * func ) { 630 630 // Fix up parameters and return types 631 631 fixFunctionList( func->parameters, func->isVarArgs, func ); … … 633 633 } 634 634 635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) {635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) { 636 636 if ( other_indexer ) { 637 637 local_indexer = other_indexer; … … 641 641 } 642 642 643 void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) {644 EnumDecl *st = local_indexer->lookupEnum( enumInst->name );643 void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) { 644 const EnumDecl * st = local_indexer->lookupEnum( enumInst->name ); 645 645 // it's not a semantic error if the enum is not found, just an implicit forward declaration 646 646 if ( st ) { 647 enumInst->baseEnum = st;647 enumInst->baseEnum = const_cast<EnumDecl *>(st); // Just linking in the node 648 648 } // if 649 649 if ( ! st || ! st->body ) { … … 661 661 } 662 662 663 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) {664 StructDecl *st = local_indexer->lookupStruct( structInst->name );663 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) { 664 const StructDecl * st = local_indexer->lookupStruct( structInst->name ); 665 665 // it's not a semantic error if the struct is not found, just an implicit forward declaration 666 666 if ( st ) { 667 structInst->baseStruct = st;667 structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node 668 668 } // if 669 669 if ( ! st || ! st->body ) { … … 674 674 } 675 675 676 void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) {677 UnionDecl *un = local_indexer->lookupUnion( unionInst->name );676 void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) { 677 const UnionDecl * un = local_indexer->lookupUnion( unionInst->name ); 678 678 // it's not a semantic error if the union is not found, just an implicit forward declaration 679 679 if ( un ) { 680 unionInst->baseUnion = un;680 unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node 681 681 } // if 682 682 if ( ! un || ! un->body ) { … … 693 693 void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) { 694 694 // linking only makes sense for the 'oldest ancestor' of the qualified type 695 qualType->parent->accept( * visitor );695 qualType->parent->accept( * visitor ); 696 696 } 697 697 … … 762 762 void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) { 763 763 // handle other traits 764 TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );764 const TraitDecl * traitDecl = local_indexer->lookupTrait( traitInst->name ); 765 765 if ( ! traitDecl ) { 766 766 SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name ); … … 769 769 SemanticError( traitInst, "incorrect number of trait parameters: " ); 770 770 } // if 771 traitInst->baseTrait = traitDecl;771 traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node 772 772 773 773 // need to carry over the 'sized' status of each decl in the instance … … 786 786 } 787 787 788 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) {788 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) { 789 789 // visit enum members first so that the types of self-referencing members are updated properly 790 790 if ( enumDecl->body ) { … … 792 792 if ( fwds != forwardEnums.end() ) { 793 793 for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 794 (* inst)->baseEnum = enumDecl;794 (* inst)->baseEnum = enumDecl; 795 795 } // for 796 796 forwardEnums.erase( fwds ); … … 834 834 } 835 835 836 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) {836 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) { 837 837 // visit struct members first so that the types of self-referencing members are updated properly 838 838 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) … … 841 841 if ( fwds != forwardStructs.end() ) { 842 842 for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 843 (* inst)->baseStruct = structDecl;843 (* inst)->baseStruct = structDecl; 844 844 } // for 845 845 forwardStructs.erase( fwds ); … … 848 848 } 849 849 850 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) {850 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) { 851 851 if ( unionDecl->body ) { 852 852 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); 853 853 if ( fwds != forwardUnions.end() ) { 854 854 for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 855 (* inst)->baseUnion = unionDecl;855 (* inst)->baseUnion = unionDecl; 856 856 } // for 857 857 forwardUnions.erase( fwds ); … … 860 860 } 861 861 862 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) {862 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) { 863 863 // ensure generic parameter instances are renamed like the base type 864 864 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; 865 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {866 if ( TypeDecl *typeDecl = dynamic_cast<TypeDecl * >( namedTypeDecl ) ) {867 typeInst->set_isFtype( typeDecl-> get_kind()== TypeDecl::Ftype );865 if ( const NamedTypeDecl * namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) { 866 if ( const TypeDecl * typeDecl = dynamic_cast< const TypeDecl * >( namedTypeDecl ) ) { 867 typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype ); 868 868 } // if 869 869 } // if … … 877 877 // expand trait instances into their members 878 878 for ( DeclarationWithType * assertion : asserts ) { 879 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {879 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 880 880 // expand trait instance into all of its members 881 881 expandAssertions( traitInst, back_inserter( type->assertions ) ); … … 897 897 } 898 898 899 void ForallPointerDecay_old::previsit( ObjectDecl * object ) {899 void ForallPointerDecay_old::previsit( ObjectDecl * object ) { 900 900 // ensure that operator names only apply to functions or function pointers 901 901 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { … … 905 905 } 906 906 907 void ForallPointerDecay_old::previsit( FunctionDecl * func ) {907 void ForallPointerDecay_old::previsit( FunctionDecl * func ) { 908 908 func->fixUniqueId(); 909 909 } … … 961 961 Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) { 962 962 // replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type 963 qualType->parent = qualType->parent->acceptMutator( * visitor );963 qualType->parent = qualType->parent->acceptMutator( * visitor ); 964 964 return qualType; 965 965 } … … 970 970 TypedefMap::const_iterator def = typedefNames.find( typeInst->name ); 971 971 if ( def != typedefNames.end() ) { 972 Type * ret = def->second.first->base->clone();972 Type * ret = def->second.first->base->clone(); 973 973 ret->location = typeInst->location; 974 974 ret->get_qualifiers() |= typeInst->get_qualifiers(); … … 982 982 // place instance parameters on the typedef'd type 983 983 if ( ! typeInst->parameters.empty() ) { 984 ReferenceToType * rtt = dynamic_cast<ReferenceToType*>(ret);984 ReferenceToType * rtt = dynamic_cast<ReferenceToType *>(ret); 985 985 if ( ! rtt ) { 986 986 SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name ); … … 988 988 rtt->parameters.clear(); 989 989 cloneAll( typeInst->parameters, rtt->parameters ); 990 mutateAll( rtt->parameters, * visitor ); // recursively fix typedefs on parameters990 mutateAll( rtt->parameters, * visitor ); // recursively fix typedefs on parameters 991 991 } // if 992 992 delete typeInst; … … 1043 1043 // struct screen; 1044 1044 // because the expansion of the typedef is: 1045 // void rtn( SCREEN * p ) => void rtn( struct screen *p )1045 // void rtn( SCREEN * p ) => void rtn( struct screen * p ) 1046 1046 // hence the type-name "screen" must be defined. 1047 1047 // Note, qualifiers on the typedef are superfluous for the forward declaration. 1048 1048 1049 Type * designatorType = tyDecl->base->stripDeclarator();1050 if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {1049 Type * designatorType = tyDecl->base->stripDeclarator(); 1050 if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) { 1051 1051 declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) ); 1052 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {1052 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) { 1053 1053 declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) ); 1054 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {1054 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) { 1055 1055 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) ); 1056 1056 } // if … … 1078 1078 1079 1079 DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) { 1080 if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?1080 if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type? 1081 1081 // replace the current object declaration with a function declaration 1082 1082 FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() ); … … 1104 1104 void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) { 1105 1105 if ( typedefNames.count( aggDecl->get_name() ) == 0 ) { 1106 Type * type = nullptr;1106 Type * type = nullptr; 1107 1107 if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) { 1108 1108 type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ); … … 1130 1130 GuardScope( typedefNames ); 1131 1131 GuardScope( typedeclNames ); 1132 mutateAll( aggr->parameters, * visitor );1132 mutateAll( aggr->parameters, * visitor ); 1133 1133 1134 1134 // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body. … … 1137 1137 1138 1138 try { 1139 * i = maybeMutate( *i, *visitor );1139 * i = maybeMutate( * i, * visitor ); 1140 1140 } catch ( SemanticErrorException &e ) { 1141 1141 errors.append( e ); … … 1217 1217 for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) { 1218 1218 if ( i < args.size() ) { 1219 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) );1220 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() );1219 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) ); 1220 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() ); 1221 1221 } else if ( i == args.size() ) { 1222 Type * defaultType = (* paramIter)->get_init();1222 Type * defaultType = (* paramIter)->get_init(); 1223 1223 if ( defaultType ) { 1224 1224 args.push_back( new TypeExpr( defaultType->clone() ) ); 1225 sub.add( (* paramIter)->get_name(), defaultType->clone() );1225 sub.add( (* paramIter)->get_name(), defaultType->clone() ); 1226 1226 } 1227 1227 } … … 1242 1242 } 1243 1243 1244 void CompoundLiteral::premutate( ObjectDecl * objectDecl ) {1244 void CompoundLiteral::premutate( ObjectDecl * objectDecl ) { 1245 1245 storageClasses = objectDecl->get_storageClasses(); 1246 1246 } 1247 1247 1248 Expression * CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {1248 Expression * CompoundLiteral::postmutate( CompoundLiteralExpr * compLitExpr ) { 1249 1249 // transform [storage_class] ... (struct S){ 3, ... }; 1250 1250 // into [storage_class] struct S temp = { 3, ... }; 1251 1251 static UniqueName indexName( "_compLit" ); 1252 1252 1253 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );1253 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() ); 1254 1254 compLitExpr->set_result( nullptr ); 1255 1255 compLitExpr->set_initializer( nullptr ); … … 1289 1289 TupleType * tupleType = strict_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) ); 1290 1290 // ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false. 1291 ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) );1291 ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) ); 1292 1292 deleteAll( retVals ); 1293 1293 retVals.clear(); … … 1302 1302 1303 1303 void FixObjectType::previsit( ObjectDecl * objDecl ) { 1304 Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );1304 Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer ); 1305 1305 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1306 1306 objDecl->set_type( new_type ); … … 1308 1308 1309 1309 void FixObjectType::previsit( FunctionDecl * funcDecl ) { 1310 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );1310 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer ); 1311 1311 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1312 1312 funcDecl->set_type( new_type ); 1313 1313 } 1314 1314 1315 void FixObjectType::previsit( TypeDecl * typeDecl ) {1315 void FixObjectType::previsit( TypeDecl * typeDecl ) { 1316 1316 if ( typeDecl->get_base() ) { 1317 Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );1317 Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer ); 1318 1318 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1319 1319 typeDecl->set_base( new_type ); … … 1378 1378 1379 1379 namespace { 1380 /// Replaces enum types by int, and function/array types in function parameter and return 1380 /// Replaces enum types by int, and function/array types in function parameter and return 1381 1381 /// lists by appropriate pointers 1382 1382 struct EnumAndPointerDecay_new { … … 1385 1385 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1386 1386 // build new version of object with EnumConstant 1387 ast::ptr< ast::ObjectDecl > obj = 1387 ast::ptr< ast::ObjectDecl > obj = 1388 1388 enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1389 obj.get_and_mutate()->type = 1389 obj.get_and_mutate()->type = 1390 1390 new ast::EnumInstType{ enumDecl->name, ast::CV::Const }; 1391 1391 1392 1392 // set into decl 1393 1393 ast::EnumDecl * mut = mutate( enumDecl ); … … 1399 1399 1400 1400 static const ast::FunctionType * fixFunctionList( 1401 const ast::FunctionType * func, 1401 const ast::FunctionType * func, 1402 1402 std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field, 1403 1403 ast::ArgumentFlag isVarArgs = ast::FixedArgs 1404 1404 ) { 1405 const auto & dwts = func->* field;1405 const auto & dwts = func->* field; 1406 1406 unsigned nvals = dwts.size(); 1407 1407 bool hasVoid = false; … … 1409 1409 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) ); 1410 1410 } 1411 1411 1412 1412 // the only case in which "void" is valid is where it is the only one in the list 1413 1413 if ( hasVoid && ( nvals > 1 || isVarArgs ) ) { 1414 SemanticError( 1414 SemanticError( 1415 1415 dwts.front()->location, func, "invalid type void in function type" ); 1416 1416 } … … 1418 1418 // one void is the only thing in the list, remove it 1419 1419 if ( hasVoid ) { 1420 func = ast::mutate_field( 1420 func = ast::mutate_field( 1421 1421 func, field, std::vector< ast::ptr< ast::DeclWithType > >{} ); 1422 1422 } … … 1432 1432 1433 1433 /// expand assertions from a trait instance, performing appropriate type variable substitutions 1434 void expandAssertions( 1435 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 1434 void expandAssertions( 1435 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 1436 1436 ) { 1437 1437 assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) ); 1438 1438 1439 1439 // build list of trait members, substituting trait decl parameters for instance parameters 1440 ast::TypeSubstitution sub{ 1440 ast::TypeSubstitution sub{ 1441 1441 inst->base->params.begin(), inst->base->params.end(), inst->params.begin() }; 1442 1442 // deliberately take ast::ptr by-value to ensure this does not mutate inst->base … … 1449 1449 1450 1450 /// Associates forward declarations of aggregates with their definitions 1451 class LinkReferenceToTypes_new final 1452 : public ast::WithSymbolTable, public ast::WithGuards, public 1451 class LinkReferenceToTypes_new final 1452 : public ast::WithSymbolTable, public ast::WithGuards, public 1453 1453 ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting { 1454 1455 // these maps of uses of forward declarations of types need to have the actual type 1456 // declaration switched in * after* they have been traversed. To enable this in the1457 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 1458 // before it is placed in the map, properly updating its parents in the usual traversal, 1454 1455 // these maps of uses of forward declarations of types need to have the actual type 1456 // declaration switched in * after * they have been traversed. To enable this in the 1457 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 1458 // before it is placed in the map, properly updating its parents in the usual traversal, 1459 1459 // then can have the actual mutation applied later 1460 1460 using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >; 1461 1461 using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >; 1462 1462 using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >; 1463 1463 1464 1464 const CodeLocation & location; 1465 1465 const ast::SymbolTable * localSymtab; 1466 1466 1467 1467 ForwardEnumsType forwardEnums; 1468 1468 ForwardStructsType forwardStructs; 1469 1469 ForwardUnionsType forwardUnions; 1470 1470 1471 /// true if currently in a generic type body, so that type parameter instances can be 1471 /// true if currently in a generic type body, so that type parameter instances can be 1472 1472 /// renamed appropriately 1473 1473 bool inGeneric = false; … … 1475 1475 public: 1476 1476 /// contstruct using running symbol table 1477 LinkReferenceToTypes_new( const CodeLocation & loc ) 1477 LinkReferenceToTypes_new( const CodeLocation & loc ) 1478 1478 : location( loc ), localSymtab( &symtab ) {} 1479 1479 1480 1480 /// construct using provided symbol table 1481 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 1481 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 1482 1482 : location( loc ), localSymtab( &syms ) {} 1483 1483 … … 1485 1485 // ensure generic parameter instances are renamed like the base type 1486 1486 if ( inGeneric && typeInst->base ) { 1487 typeInst = ast::mutate_field( 1487 typeInst = ast::mutate_field( 1488 1488 typeInst, &ast::TypeInstType::name, typeInst->base->name ); 1489 1489 } 1490 1490 1491 if ( 1492 auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 1493 localSymtab->lookupType( typeInst->name ) ) 1491 if ( 1492 auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 1493 localSymtab->lookupType( typeInst->name ) ) 1494 1494 ) { 1495 1495 typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind ); … … 1517 1517 for ( const ast::Expr * param : inst->params ) { 1518 1518 if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) { 1519 SemanticError( 1519 SemanticError( 1520 1520 location, inst, "Expression parameters for generic types are currently " 1521 1521 "unsupported: " ); … … 1571 1571 auto expr = traitInst->params[i].as< ast::TypeExpr >(); 1572 1572 if ( ! expr ) { 1573 SemanticError( 1573 SemanticError( 1574 1574 traitInst->params[i].get(), "Expression parameters for trait instances " 1575 1575 "are currently unsupported: " ); … … 1593 1593 return traitInst; 1594 1594 } 1595 1595 1596 1596 void previsit( const ast::QualifiedType * ) { visit_children = false; } 1597 1597 1598 1598 const ast::Type * postvisit( const ast::QualifiedType * qualType ) { 1599 1599 // linking only makes sense for the "oldest ancestor" of the qualified type 1600 return ast::mutate_field( 1601 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) );1600 return ast::mutate_field( 1601 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) ); 1602 1602 } 1603 1603 1604 1604 const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) { 1605 // visit enum members first so that the types of self-referencing members are updated 1605 // visit enum members first so that the types of self-referencing members are updated 1606 1606 // properly 1607 1607 if ( ! enumDecl->body ) return enumDecl; … … 1612 1612 auto inst = fwds.first; 1613 1613 do { 1614 // forward decl is stored * mutably* in map, can thus be updated1614 // forward decl is stored * mutably * in map, can thus be updated 1615 1615 inst->second->base = enumDecl; 1616 1616 } while ( ++inst != fwds.second ); 1617 1617 forwardEnums.erase( fwds.first, fwds.second ); 1618 1618 } 1619 1619 1620 1620 // ensure that enumerator initializers are properly set 1621 1621 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1622 1622 auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1623 1623 if ( field->init ) { 1624 // need to resolve enumerator initializers early so that other passes that 1624 // need to resolve enumerator initializers early so that other passes that 1625 1625 // determine if an expression is constexpr have appropriate information 1626 1626 auto init = field->init.strict_as< ast::SingleInit >(); 1627 1628 enumDecl = ast::mutate_field_index( 1629 enumDecl, &ast::EnumDecl::members, i, 1630 ast::mutate_field( field, &ast::ObjectDecl::init, 1627 1628 enumDecl = ast::mutate_field_index( 1629 enumDecl, &ast::EnumDecl::members, i, 1630 ast::mutate_field( field, &ast::ObjectDecl::init, 1631 1631 ast::mutate_field( init, &ast::SingleInit::value, 1632 ResolvExpr::findSingleExpression( 1632 ResolvExpr::findSingleExpression( 1633 1633 init->value, new ast::BasicType{ ast::BasicType::SignedInt }, 1634 1634 symtab ) ) ) ); … … 1639 1639 } 1640 1640 1641 /// rename generic type parameters uniquely so that they do not conflict with user defined 1641 /// rename generic type parameters uniquely so that they do not conflict with user defined 1642 1642 /// function forall parameters, e.g. the T in Box and the T in f, below 1643 1643 /// forall(otype T) … … 1657 1657 const ast::TypeDecl * td = aggr->params[i]; 1658 1658 1659 aggr = ast::mutate_field_index( 1660 aggr, &AggrDecl::params, i, 1659 aggr = ast::mutate_field_index( 1660 aggr, &AggrDecl::params, i, 1661 1661 ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) ); 1662 1662 } … … 1669 1669 1670 1670 void postvisit( const ast::StructDecl * structDecl ) { 1671 // visit struct members first so that the types of self-referencing members are 1671 // visit struct members first so that the types of self-referencing members are 1672 1672 // updated properly 1673 1673 if ( ! structDecl->body ) return; … … 1678 1678 auto inst = fwds.first; 1679 1679 do { 1680 // forward decl is stored * mutably* in map, can thus be updated1680 // forward decl is stored * mutably * in map, can thus be updated 1681 1681 inst->second->base = structDecl; 1682 1682 } while ( ++inst != fwds.second ); … … 1690 1690 1691 1691 void postvisit( const ast::UnionDecl * unionDecl ) { 1692 // visit union members first so that the types of self-referencing members are updated 1692 // visit union members first so that the types of self-referencing members are updated 1693 1693 // properly 1694 1694 if ( ! unionDecl->body ) return; … … 1699 1699 auto inst = fwds.first; 1700 1700 do { 1701 // forward decl is stored * mutably* in map, can thus be updated1701 // forward decl is stored * mutably * in map, can thus be updated 1702 1702 inst->second->base = unionDecl; 1703 1703 } while ( ++inst != fwds.second ); … … 1712 1712 "number of parameters: %zd", traitDecl->params.size() ); 1713 1713 1714 traitDecl = ast::mutate_field_index( 1715 traitDecl, &ast::TraitDecl::params, 0, 1716 ast::mutate_field( 1714 traitDecl = ast::mutate_field_index( 1715 traitDecl, &ast::TraitDecl::params, 0, 1716 ast::mutate_field( 1717 1717 traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) ); 1718 1718 } … … 1737 1737 traitDecl = mut; 1738 1738 } 1739 1739 1740 1740 return traitDecl; 1741 1741 } 1742 1742 }; 1743 1743 1744 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1744 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1745 1745 /// each object and function declaration a unique ID 1746 1746 class ForallPointerDecay_new { … … 1751 1751 const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) { 1752 1752 // ensure that operator names only apply to functions or function pointers 1753 if ( 1754 CodeGen::isOperator( obj->name ) 1753 if ( 1754 CodeGen::isOperator( obj->name ) 1755 1755 && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() ) 1756 1756 ) { … … 1776 1776 /// Fix up assertions -- flattens assertion lists, removing all trait instances 1777 1777 template< typename node_t, typename parent_t > 1778 static const node_t * forallFixer( 1779 const CodeLocation & loc, const node_t * node, 1778 static const node_t * forallFixer( 1779 const CodeLocation & loc, const node_t * node, 1780 1780 ast::ParameterizedType::ForallList parent_t::* forallField 1781 1781 ) { 1782 for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) {1783 const ast::TypeDecl * type = (node->* forallField)[i];1782 for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) { 1783 const ast::TypeDecl * type = (node->* forallField)[i]; 1784 1784 if ( type->assertions.empty() ) continue; 1785 1785 … … 1789 1789 // expand trait instances into their members 1790 1790 for ( const ast::DeclWithType * assn : type->assertions ) { 1791 auto traitInst = 1792 dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 1791 auto traitInst = 1792 dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 1793 1793 if ( traitInst ) { 1794 1794 // expand trait instance to all its members … … 1831 1831 } // anonymous namespace 1832 1832 1833 const ast::Type * validateType( 1833 const ast::Type * validateType( 1834 1834 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { 1835 1835 ast::Pass< EnumAndPointerDecay_new > epc; -
src/SymTab/Validate.h
r1f1c102 rf53acdf8 19 19 #include <list> // for list 20 20 21 classCodeLocation;22 class Declaration;23 class Type;21 struct CodeLocation; 22 class Declaration; 23 class Type; 24 24 25 25 namespace ast { … … 35 35 void validateType( Type *type, const Indexer *indexer ); 36 36 37 const ast::Type * validateType( 37 const ast::Type * validateType( 38 38 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ); 39 39 } // namespace SymTab
Note:
See TracChangeset
for help on using the changeset viewer.