Changes in src/SymTab/Indexer.cc [ef5b828:114bde6]
- File:
-
- 1 edited
-
src/SymTab/Indexer.cc (modified) (31 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Indexer.cc
ref5b828 r114bde6 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 const NamedTypeDecl * Indexer::lookupType( const std::string & id ) const { return lookupMutableType(id); } 125 NamedTypeDecl * Indexer::lookupMutableType( const std::string & id ) const { 126 ++* stats().lookup_calls; 124 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const { 125 ++*stats().lookup_calls; 127 126 if ( ! typeTable ) return nullptr; 128 ++* stats().map_lookups;127 ++*stats().map_lookups; 129 128 auto it = typeTable->find( id ); 130 129 return it == typeTable->end() ? nullptr : it->second.decl; 131 130 } 132 131 133 const StructDecl * Indexer::lookupStruct( const std::string & id ) const { return lookupMutableStruct(id); } 134 StructDecl * Indexer::lookupMutableStruct( const std::string & id ) const { 135 ++* stats().lookup_calls; 132 StructDecl *Indexer::lookupStruct( const std::string &id ) const { 133 ++*stats().lookup_calls; 136 134 if ( ! structTable ) return nullptr; 137 ++* stats().map_lookups;135 ++*stats().map_lookups; 138 136 auto it = structTable->find( id ); 139 137 return it == structTable->end() ? nullptr : it->second.decl; 140 138 } 141 139 142 const EnumDecl * Indexer::lookupEnum( const std::string & id ) const { return lookupMutableEnum(id); } 143 EnumDecl * Indexer::lookupMutableEnum( const std::string & id ) const { 144 ++* stats().lookup_calls; 140 EnumDecl *Indexer::lookupEnum( const std::string &id ) const { 141 ++*stats().lookup_calls; 145 142 if ( ! enumTable ) return nullptr; 146 ++* stats().map_lookups;143 ++*stats().map_lookups; 147 144 auto it = enumTable->find( id ); 148 145 return it == enumTable->end() ? nullptr : it->second.decl; 149 146 } 150 147 151 const UnionDecl * Indexer::lookupUnion( const std::string & id ) const { return lookupMutableUnion(id); } 152 UnionDecl * Indexer::lookupMutableUnion( const std::string & id ) const { 153 ++* stats().lookup_calls; 148 UnionDecl *Indexer::lookupUnion( const std::string &id ) const { 149 ++*stats().lookup_calls; 154 150 if ( ! unionTable ) return nullptr; 155 ++* stats().map_lookups;151 ++*stats().map_lookups; 156 152 auto it = unionTable->find( id ); 157 153 return it == unionTable->end() ? nullptr : it->second.decl; 158 154 } 159 155 160 const TraitDecl * Indexer::lookupTrait( const std::string & id ) const { return lookupMutableTrait(id); } 161 TraitDecl * Indexer::lookupMutableTrait( const std::string & id ) const { 162 ++* stats().lookup_calls; 156 TraitDecl *Indexer::lookupTrait( const std::string &id ) const { 157 ++*stats().lookup_calls; 163 158 if ( ! traitTable ) return nullptr; 164 ++* stats().map_lookups;159 ++*stats().map_lookups; 165 160 auto it = traitTable->find( id ); 166 161 return it == traitTable->end() ? nullptr : it->second.decl; 167 162 } 168 163 169 const Indexer * Indexer::atScope( unsigned long target ) const {164 const Indexer* Indexer::atScope( unsigned long target ) const { 170 165 // by lazy construction, final indexer in list has repScope 0, cannot be > target 171 166 // otherwise, will find first scope representing the target 172 const Indexer * indexer = this;167 const Indexer* indexer = this; 173 168 while ( indexer->repScope > target ) { 174 169 indexer = indexer->prevScope.get(); … … 177 172 } 178 173 179 const NamedTypeDecl * Indexer::globalLookupType( const std::string &id ) const {174 NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const { 180 175 return atScope( 0 )->lookupType( id ); 181 176 } 182 177 183 const StructDecl * Indexer::globalLookupStruct( const std::string &id ) const {178 StructDecl *Indexer::globalLookupStruct( const std::string &id ) const { 184 179 return atScope( 0 )->lookupStruct( id ); 185 180 } 186 181 187 const UnionDecl * Indexer::globalLookupUnion( const std::string &id ) const {182 UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const { 188 183 return atScope( 0 )->lookupUnion( id ); 189 184 } 190 185 191 const EnumDecl * Indexer::globalLookupEnum( const std::string &id ) const {186 EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const { 192 187 return atScope( 0 )->lookupEnum( id ); 193 188 } … … 212 207 } 213 208 214 215 bool Indexer::addedIdConflicts( 216 const Indexer::IdData & existing, DeclarationWithType * added,209 210 bool Indexer::addedIdConflicts( 211 const Indexer::IdData & existing, DeclarationWithType *added, 217 212 Indexer::OnConflict handleConflicts, BaseSyntaxNode * deleteStmt ) { 218 // if we're giving the same name mangling to things of different types then there is 213 // if we're giving the same name mangling to things of different types then there is 219 214 // something wrong 220 215 assert( (isObject( added ) && isObject( existing.id ) ) … … 224 219 // new definition shadows the autogenerated one, even at the same scope 225 220 return false; 226 } else if ( LinkageSpec::isMangled( added->linkage ) 227 || ResolvExpr::typesCompatible( 221 } else if ( LinkageSpec::isMangled( added->linkage ) 222 || ResolvExpr::typesCompatible( 228 223 added->get_type(), existing.id->get_type(), Indexer() ) ) { 229 224 … … 243 238 if ( isDefinition( added ) && isDefinition( existing.id ) ) { 244 239 if ( handleConflicts.mode == OnConflict::Error ) { 245 SemanticError( added, 246 isFunction( added ) ? 247 "duplicate function definition for " : 240 SemanticError( added, 241 isFunction( added ) ? 242 "duplicate function definition for " : 248 243 "duplicate object definition for " ); 249 244 } … … 260 255 } 261 256 262 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 { 263 258 if ( ! idTable ) return false; 264 259 265 ++* stats().map_lookups;260 ++*stats().map_lookups; 266 261 auto decls = idTable->find( id ); 267 262 if ( decls == idTable->end() ) return false; … … 275 270 } 276 271 } 277 272 278 273 return false; 279 274 } 280 275 281 bool Indexer::hasIncompatibleCDecl( 282 const std::string & id, const std::string &mangleName ) const {276 bool Indexer::hasIncompatibleCDecl( 277 const std::string &id, const std::string &mangleName ) const { 283 278 if ( ! idTable ) return false; 284 279 285 ++* stats().map_lookups;280 ++*stats().map_lookups; 286 281 auto decls = idTable->find( id ); 287 282 if ( decls == idTable->end() ) return false; … … 300 295 301 296 /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function 302 std::string getOtypeKey( FunctionDecl * function ) {297 std::string getOtypeKey( FunctionDecl* function ) { 303 298 auto& params = function->type->parameters; 304 299 assert( ! params.empty() ); 305 300 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 306 Type * base = InitTweak::getPointerBase( params.front()->get_type() );301 Type* base = InitTweak::getPointerBase( params.front()->get_type() ); 307 302 assert( base ); 308 303 return Mangler::mangle( base ); 309 304 } 310 305 311 /// gets the declaration for the function acting on a type specified by otype key, 306 /// gets the declaration for the function acting on a type specified by otype key, 312 307 /// nullptr if none such 313 308 FunctionDecl * getFunctionForOtype( DeclarationWithType * decl, const std::string& otypeKey ) { … … 317 312 } 318 313 319 bool Indexer::removeSpecialOverrides( 314 bool Indexer::removeSpecialOverrides( 320 315 Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) { 321 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 322 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular, 323 // if the user defines a default ctor, then the generated default ctor is unavailable, 324 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 325 // field ctors are available. If the user defines any ctor then the generated default ctor 326 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 327 // anything that looks like a copy constructor, then the generated copy constructor is 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 328 323 // unavailable, and likewise for the assignment operator. 329 324 … … 345 340 std::vector< MangleTable::value_type > deleted; 346 341 bool alreadyUserDefinedFunc = false; 347 348 for ( const auto& entry : * mangleTable ) {342 343 for ( const auto& entry : *mangleTable ) { 349 344 // skip decls that aren't functions or are for the wrong type 350 345 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); … … 373 368 // perform removals from mangle table, and deletions if necessary 374 369 for ( const auto& key : removed ) { 375 ++* stats().map_mutations;370 ++*stats().map_mutations; 376 371 mangleTable = mangleTable->erase( key ); 377 372 } 378 373 if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) { 379 ++* stats().map_mutations;374 ++*stats().map_mutations; 380 375 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 381 376 } … … 384 379 // if this is the first user-defined function, delete non-user-defined overloads 385 380 std::vector< MangleTable::value_type > deleted; 386 387 for ( const auto& entry : * mangleTable ) {381 382 for ( const auto& entry : *mangleTable ) { 388 383 // skip decls that aren't functions or are for the wrong type 389 384 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); … … 407 402 // this needs to be a separate loop because of iterator invalidation 408 403 for ( const auto& entry : deleted ) { 409 ++* stats().map_mutations;404 ++*stats().map_mutations; 410 405 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 411 406 } … … 413 408 // this is an overridable generated function 414 409 // if there already exists a matching user-defined function, delete this appropriately 415 for ( const auto& entry : * mangleTable ) {410 for ( const auto& entry : *mangleTable ) { 416 411 // skip decls that aren't functions or are for the wrong type 417 412 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); … … 423 418 if ( dataIsCopyFunc ) { 424 419 // remove current function if exists a user-defined copy function 425 // since the signatures for copy functions don't need to match exactly, using 420 // since the signatures for copy functions don't need to match exactly, using 426 421 // a delete statement is the wrong approach 427 422 if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false; … … 433 428 } 434 429 } 435 430 436 431 // nothing (more) to fix, return true 437 432 return true; 438 433 } 439 434 440 void Indexer::addId( 441 DeclarationWithType * decl, OnConflict handleConflicts, Expression * baseExpr,435 void Indexer::addId( 436 DeclarationWithType *decl, OnConflict handleConflicts, Expression * baseExpr, 442 437 BaseSyntaxNode * deleteStmt ) { 443 ++* stats().add_calls;438 ++*stats().add_calls; 444 439 const std::string &name = decl->name; 445 440 if ( name == "" ) return; 446 441 447 442 std::string mangleName; 448 443 if ( LinkageSpec::isOverridable( decl->linkage ) ) { 449 // mangle the name without including the appropriate suffix, so overridable routines 444 // mangle the name without including the appropriate suffix, so overridable routines 450 445 // are placed into the same "bucket" as their user defined versions. 451 446 mangleName = Mangler::mangle( decl, false ); … … 454 449 } // if 455 450 456 // this ensures that no two declarations with the same unmangled name at the same scope 451 // this ensures that no two declarations with the same unmangled name at the same scope 457 452 // both have C linkage 458 453 if ( LinkageSpec::isMangled( decl->linkage ) ) { … … 462 457 } 463 458 } else { 464 // NOTE: only correct if name mangling is completely isomorphic to C 459 // NOTE: only correct if name mangling is completely isomorphic to C 465 460 // type-compatibility, which it may not be. 466 461 if ( hasIncompatibleCDecl( name, mangleName ) ) { … … 475 470 mangleTable = MangleTable::new_ptr(); 476 471 } else { 477 ++* stats().map_lookups;472 ++*stats().map_lookups; 478 473 auto decls = idTable->find( name ); 479 474 if ( decls == idTable->end() ) { … … 482 477 mangleTable = decls->second; 483 478 // skip in-scope repeat declarations of same identifier 484 ++* stats().map_lookups;479 ++*stats().map_lookups; 485 480 auto existing = mangleTable->find( mangleName ); 486 481 if ( existing != mangleTable->end() … … 491 486 // set delete expression for conflicting identifier 492 487 lazyInitScope(); 493 * stats().map_mutations += 2;488 *stats().map_mutations += 2; 494 489 idTable = idTable->set( 495 490 name, 496 mangleTable->set( 497 mangleName, 491 mangleTable->set( 492 mangleName, 498 493 IdData{ existing->second, handleConflicts.deleteStmt } ) ); 499 494 } … … 509 504 // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary 510 505 if ( ! removeSpecialOverrides( data, mangleTable ) ) return; 511 * stats().map_mutations += 2;506 *stats().map_mutations += 2; 512 507 idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) ); 513 508 } … … 523 518 } 524 519 525 bool addedTypeConflicts( NamedTypeDecl * existing, NamedTypeDecl *added ) {520 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) { 526 521 if ( existing->base == nullptr ) { 527 522 return false; … … 535 530 } 536 531 } 537 // does not need to be added to the table if both existing and added have a base that are 532 // does not need to be added to the table if both existing and added have a base that are 538 533 // the same 539 534 return true; 540 535 } 541 536 542 void Indexer::addType( NamedTypeDecl * decl ) {543 ++* stats().add_calls;544 const std::string & id = decl->name;545 546 if ( ! typeTable ) { 537 void Indexer::addType( NamedTypeDecl *decl ) { 538 ++*stats().add_calls; 539 const std::string &id = decl->name; 540 541 if ( ! typeTable ) { 547 542 typeTable = TypeTable::new_ptr(); 548 543 } else { 549 ++* stats().map_lookups;544 ++*stats().map_lookups; 550 545 auto existing = typeTable->find( id ); 551 if ( existing != typeTable->end() 552 && existing->second.scope == scope 546 if ( existing != typeTable->end() 547 && existing->second.scope == scope 553 548 && addedTypeConflicts( existing->second.decl, decl ) ) return; 554 549 } 555 550 556 551 lazyInitScope(); 557 ++* stats().map_mutations;552 ++*stats().map_mutations; 558 553 typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } ); 559 554 } 560 555 561 bool addedDeclConflicts( AggregateDecl * existing, AggregateDecl *added ) {556 bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) { 562 557 if ( ! existing->body ) { 563 558 return false; … … 568 563 } 569 564 570 void Indexer::addStruct( const std::string & id ) {565 void Indexer::addStruct( const std::string &id ) { 571 566 addStruct( new StructDecl( id ) ); 572 567 } 573 568 574 void Indexer::addStruct( StructDecl * decl ) {575 ++* stats().add_calls;576 const std::string & id = decl->name;569 void Indexer::addStruct( StructDecl *decl ) { 570 ++*stats().add_calls; 571 const std::string &id = decl->name; 577 572 578 573 if ( ! structTable ) { 579 574 structTable = StructTable::new_ptr(); 580 575 } else { 581 ++* stats().map_lookups;576 ++*stats().map_lookups; 582 577 auto existing = structTable->find( id ); 583 if ( existing != structTable->end() 584 && existing->second.scope == scope 578 if ( existing != structTable->end() 579 && existing->second.scope == scope 585 580 && addedDeclConflicts( existing->second.decl, decl ) ) return; 586 581 } 587 582 588 583 lazyInitScope(); 589 ++* stats().map_mutations;584 ++*stats().map_mutations; 590 585 structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } ); 591 586 } 592 587 593 void Indexer::addEnum( EnumDecl * decl ) {594 ++* stats().add_calls;595 const std::string & id = decl->name;588 void Indexer::addEnum( EnumDecl *decl ) { 589 ++*stats().add_calls; 590 const std::string &id = decl->name; 596 591 597 592 if ( ! enumTable ) { 598 593 enumTable = EnumTable::new_ptr(); 599 594 } else { 600 ++* stats().map_lookups;595 ++*stats().map_lookups; 601 596 auto existing = enumTable->find( id ); 602 if ( existing != enumTable->end() 603 && existing->second.scope == scope 597 if ( existing != enumTable->end() 598 && existing->second.scope == scope 604 599 && addedDeclConflicts( existing->second.decl, decl ) ) return; 605 600 } 606 601 607 602 lazyInitScope(); 608 ++* stats().map_mutations;603 ++*stats().map_mutations; 609 604 enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } ); 610 605 } 611 606 612 void Indexer::addUnion( const std::string & id ) {607 void Indexer::addUnion( const std::string &id ) { 613 608 addUnion( new UnionDecl( id ) ); 614 609 } 615 610 616 void Indexer::addUnion( UnionDecl * decl ) {617 ++* stats().add_calls;618 const std::string & id = decl->name;611 void Indexer::addUnion( UnionDecl *decl ) { 612 ++*stats().add_calls; 613 const std::string &id = decl->name; 619 614 620 615 if ( ! unionTable ) { 621 616 unionTable = UnionTable::new_ptr(); 622 617 } else { 623 ++* stats().map_lookups;618 ++*stats().map_lookups; 624 619 auto existing = unionTable->find( id ); 625 if ( existing != unionTable->end() 626 && existing->second.scope == scope 620 if ( existing != unionTable->end() 621 && existing->second.scope == scope 627 622 && addedDeclConflicts( existing->second.decl, decl ) ) return; 628 623 } 629 624 630 625 lazyInitScope(); 631 ++* stats().map_mutations;626 ++*stats().map_mutations; 632 627 unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } ); 633 628 } 634 629 635 void Indexer::addTrait( TraitDecl * decl ) {636 ++* stats().add_calls;637 const std::string & id = decl->name;630 void Indexer::addTrait( TraitDecl *decl ) { 631 ++*stats().add_calls; 632 const std::string &id = decl->name; 638 633 639 634 if ( ! traitTable ) { 640 635 traitTable = TraitTable::new_ptr(); 641 636 } else { 642 ++* stats().map_lookups;637 ++*stats().map_lookups; 643 638 auto existing = traitTable->find( id ); 644 if ( existing != traitTable->end() 645 && existing->second.scope == scope 639 if ( existing != traitTable->end() 640 && existing->second.scope == scope 646 641 && addedDeclConflicts( existing->second.decl, decl ) ) return; 647 642 } 648 643 649 644 lazyInitScope(); 650 ++* stats().map_mutations;645 ++*stats().map_mutations; 651 646 traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } ); 652 647 } 653 648 654 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, 649 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, 655 650 OnConflict handleConflicts ) { 656 651 for ( Declaration * decl : aggr->members ) { … … 659 654 if ( dwt->name == "" ) { 660 655 Type * t = dwt->get_type()->stripReferences(); 661 if ( dynamic_cast<StructInstType *>( t ) || dynamic_cast<UnionInstType*>( t ) ) {656 if ( dynamic_cast<StructInstType*>( t ) || dynamic_cast<UnionInstType*>( t ) ) { 662 657 Expression * base = expr->clone(); 663 658 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost?
Note:
See TracChangeset
for help on using the changeset viewer.