Changes in src/SymTab/Indexer.cc [afc1045:2a4b088]
- File:
-
- 1 edited
-
src/SymTab/Indexer.cc (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Indexer.cc
rafc1045 r2a4b088 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:37:33 2015 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:31:29 2016 13 // Update Count : 11 14 // 15 16 #include "Indexer.h" 17 18 #include <string> 19 #include <typeinfo> 20 #include <unordered_map> 21 #include <unordered_set> 22 #include <utility> 23 24 #include "Mangler.h" 25 26 #include "Common/utility.h" 27 28 #include "ResolvExpr/typeops.h" 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Aug 05 13:52:42 2015 13 // Update Count : 10 14 // 29 15 30 16 #include "SynTree/Declaration.h" … … 33 19 #include "SynTree/Initializer.h" 34 20 #include "SynTree/Statement.h" 21 #include "Indexer.h" 22 #include <typeinfo> 23 #include "Common/utility.h" 35 24 36 25 #define debugPrint(x) if ( doDebug ) { std::cout << x; } … … 44 33 } 45 34 46 typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable; 47 typedef std::unordered_map< std::string, MangleTable > IdTable; 48 typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable; 49 typedef std::unordered_map< std::string, StructDecl* > StructTable; 50 typedef std::unordered_map< std::string, EnumDecl* > EnumTable; 51 typedef std::unordered_map< std::string, UnionDecl* > UnionTable; 52 typedef std::unordered_map< std::string, TraitDecl* > TraitTable; 53 54 void dump( const IdTable &table, std::ostream &os ) { 55 for ( IdTable::const_iterator id = table.begin(); id != table.end(); ++id ) { 56 for ( MangleTable::const_iterator mangle = id->second.begin(); mangle != id->second.end(); ++mangle ) { 57 os << mangle->second << std::endl; 58 } 59 } 60 } 61 62 template< typename Decl > 63 void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) { 64 for ( typename std::unordered_map< std::string, Decl* >::const_iterator it = table.begin(); it != table.end(); ++it ) { 65 os << it->second << std::endl; 66 } // for 67 } 68 69 struct Indexer::Impl { 70 Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(), 71 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {} 72 Impl( unsigned long _scope, Indexer &&_base ) : refCount(1), scope( _scope ), size( 0 ), base( _base ), 73 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {} 74 unsigned long refCount; ///< Number of references to these tables 75 unsigned long scope; ///< Scope these tables are associated with 76 unsigned long size; ///< Number of elements stored in this table 77 const Indexer base; ///< Base indexer this extends 78 79 IdTable idTable; ///< Identifier namespace 80 TypeTable typeTable; ///< Type namespace 81 StructTable structTable; ///< Struct namespace 82 EnumTable enumTable; ///< Enum namespace 83 UnionTable unionTable; ///< Union namespace 84 TraitTable traitTable; ///< Trait namespace 85 }; 86 87 Indexer::Impl *Indexer::newRef( Indexer::Impl *toClone ) { 88 if ( ! toClone ) return 0; 89 90 // shorten the search chain by skipping empty links 91 Indexer::Impl *ret = toClone->size == 0 ? toClone->base.tables : toClone; 92 if ( ret ) { ++ret->refCount; } 93 94 return ret; 95 } 96 97 void Indexer::deleteRef( Indexer::Impl *toFree ) { 98 if ( ! toFree ) return; 99 100 if ( --toFree->refCount == 0 ) delete toFree; 101 } 102 103 void Indexer::makeWritable() { 104 if ( ! tables ) { 105 // create indexer if not yet set 106 tables = new Indexer::Impl( scope ); 107 } else if ( tables->refCount > 1 || tables->scope != scope ) { 108 // make this indexer the base of a fresh indexer at the current scope 109 tables = new Indexer::Impl( scope, std::move( *this ) ); 110 } 111 } 112 113 Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {} 114 115 Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {} 116 117 Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) { 118 that.tables = 0; 119 } 120 121 Indexer::~Indexer() { 122 deleteRef( tables ); 123 } 124 125 Indexer& Indexer::operator= ( const Indexer &that ) { 126 deleteRef( tables ); 127 128 tables = newRef( that.tables ); 129 scope = that.scope; 130 doDebug = that.doDebug; 131 132 return *this; 133 } 134 135 Indexer& Indexer::operator= ( Indexer &&that ) { 136 deleteRef( tables ); 137 138 tables = that.tables; 139 scope = that.scope; 140 doDebug = that.doDebug; 141 142 that.tables = 0; 143 144 return *this; 145 } 35 Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {} 36 37 Indexer::~Indexer() {} 146 38 147 39 void Indexer::visit( ObjectDecl *objectDecl ) { … … 153 45 if ( objectDecl->get_name() != "" ) { 154 46 debugPrint( "Adding object " << objectDecl->get_name() << std::endl ); 155 addId( objectDecl );47 idTable.addDecl( objectDecl ); 156 48 } // if 157 49 } … … 160 52 if ( functionDecl->get_name() == "" ) return; 161 53 debugPrint( "Adding function " << functionDecl->get_name() << std::endl ); 162 addId( functionDecl );54 idTable.addDecl( functionDecl ); 163 55 enterScope(); 164 56 maybeAccept( functionDecl->get_functionType(), *this ); … … 198 90 leaveScope(); 199 91 debugPrint( "Adding type " << typeDecl->get_name() << std::endl ); 200 addType( typeDecl );92 typeTable.add( typeDecl ); 201 93 acceptAll( typeDecl->get_assertions(), *this ); 202 94 } … … 208 100 leaveScope(); 209 101 debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl ); 210 addType( typeDecl );102 typeTable.add( typeDecl ); 211 103 } 212 104 … … 216 108 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() ); 217 109 debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl ); 218 addStruct( &fwdDecl );110 structTable.add( &fwdDecl ); 219 111 220 112 enterScope(); … … 225 117 debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl ); 226 118 // this addition replaces the forward declaration 227 addStruct( aggregateDecl );119 structTable.add( aggregateDecl ); 228 120 } 229 121 … … 233 125 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() ); 234 126 debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl ); 235 addUnion( &fwdDecl );127 unionTable.add( &fwdDecl ); 236 128 237 129 enterScope(); … … 241 133 242 134 debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl ); 243 addUnion( aggregateDecl );135 unionTable.add( aggregateDecl ); 244 136 } 245 137 246 138 void Indexer::visit( EnumDecl *aggregateDecl ) { 247 139 debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl ); 248 addEnum( aggregateDecl );140 enumTable.add( aggregateDecl ); 249 141 // unlike structs, contexts, and unions, enums inject their members into the global scope 250 142 acceptAll( aggregateDecl->get_members(), *this ); 251 143 } 252 144 253 void Indexer::visit( TraitDecl *aggregateDecl ) {145 void Indexer::visit( ContextDecl *aggregateDecl ) { 254 146 enterScope(); 255 147 acceptAll( aggregateDecl->get_parameters(), *this ); … … 258 150 259 151 debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl ); 260 addTrait( aggregateDecl );152 contextTable.add( aggregateDecl ); 261 153 } 262 154 … … 346 238 } 347 239 348 void Indexer::visit( OffsetPackExpr *offsetPackExpr ) {349 acceptAllNewScope( offsetPackExpr->get_results(), *this );350 maybeAccept( offsetPackExpr->get_type(), *this );351 }352 353 240 void Indexer::visit( AttrExpr *attrExpr ) { 354 241 acceptAllNewScope( attrExpr->get_results(), *this ); … … 406 293 407 294 408 void Indexer::visit( TraitInstType *contextInst ) {295 void Indexer::visit( ContextInstType *contextInst ) { 409 296 acceptAll( contextInst->get_parameters(), *this ); 410 297 acceptAll( contextInst->get_members(), *this ); … … 412 299 413 300 void Indexer::visit( StructInstType *structInst ) { 414 if ( ! lookupStruct( structInst->get_name() ) ) {301 if ( ! structTable.lookup( structInst->get_name() ) ) { 415 302 debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl ); 416 addStruct( structInst->get_name() );303 structTable.add( structInst->get_name() ); 417 304 } 418 305 enterScope(); … … 422 309 423 310 void Indexer::visit( UnionInstType *unionInst ) { 424 if ( ! lookupUnion( unionInst->get_name() ) ) {311 if ( ! unionTable.lookup( unionInst->get_name() ) ) { 425 312 debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl ); 426 addUnion( unionInst->get_name() );313 unionTable.add( unionInst->get_name() ); 427 314 } 428 315 enterScope(); … … 438 325 } 439 326 440 441 442 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const { 443 std::unordered_set< std::string > foundMangleNames; 444 445 Indexer::Impl *searchTables = tables; 446 while ( searchTables ) { 447 448 IdTable::const_iterator decls = searchTables->idTable.find( id ); 449 if ( decls != searchTables->idTable.end() ) { 450 const MangleTable &mangleTable = decls->second; 451 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 452 // mark the mangled name as found, skipping this insertion if a declaration for that name has already been found 453 if ( foundMangleNames.insert( decl->first ).second == false ) continue; 454 455 out.push_back( decl->second ); 456 } 457 } 458 459 // get declarations from base indexers 460 searchTables = searchTables->base.tables; 461 } 327 328 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const { 329 idTable.lookupId( id, list ); 330 } 331 332 DeclarationWithType* Indexer::lookupId( const std::string &id) const { 333 return idTable.lookupId(id); 462 334 } 463 335 464 336 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const { 465 if ( ! tables ) return 0; 466 467 TypeTable::const_iterator ret = tables->typeTable.find( id ); 468 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id ); 337 return typeTable.lookup( id ); 469 338 } 470 339 471 340 StructDecl *Indexer::lookupStruct( const std::string &id ) const { 472 if ( ! tables ) return 0; 473 474 StructTable::const_iterator ret = tables->structTable.find( id ); 475 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id ); 341 return structTable.lookup( id ); 476 342 } 477 343 478 344 EnumDecl *Indexer::lookupEnum( const std::string &id ) const { 479 if ( ! tables ) return 0; 480 481 EnumTable::const_iterator ret = tables->enumTable.find( id ); 482 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id ); 345 return enumTable.lookup( id ); 483 346 } 484 347 485 348 UnionDecl *Indexer::lookupUnion( const std::string &id ) const { 486 if ( ! tables ) return 0; 487 488 UnionTable::const_iterator ret = tables->unionTable.find( id ); 489 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id ); 490 } 491 492 TraitDecl *Indexer::lookupTrait( const std::string &id ) const { 493 if ( ! tables ) return 0; 494 495 TraitTable::const_iterator ret = tables->traitTable.find( id ); 496 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id ); 497 } 498 499 DeclarationWithType *Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const { 500 if ( ! tables ) return 0; 501 if ( tables->scope < scope ) return 0; 502 503 IdTable::const_iterator decls = tables->idTable.find( id ); 504 if ( decls != tables->idTable.end() ) { 505 const MangleTable &mangleTable = decls->second; 506 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 507 if ( decl != mangleTable.end() ) return decl->second; 508 } 509 510 return tables->base.lookupIdAtScope( id, mangleName, scope ); 511 } 512 513 bool Indexer::hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const { 514 if ( ! tables ) return false; 515 516 IdTable::const_iterator decls = tables->idTable.find( id ); 517 if ( decls != tables->idTable.end() ) { 518 const MangleTable &mangleTable = decls->second; 519 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 520 // check for C decls with the same name, skipping 521 // those with a compatible type (by mangleName) 522 if ( decl->second->get_linkage() == LinkageSpec::C && decl->first != mangleName ) return true; 523 } 524 } 525 526 return tables->base.hasIncompatibleCDecl( id, mangleName ); 527 } 528 529 NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const { 530 if ( ! tables ) return 0; 531 if ( tables->scope < scope ) return 0; 532 533 TypeTable::const_iterator ret = tables->typeTable.find( id ); 534 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope ); 535 } 536 537 StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const { 538 if ( ! tables ) return 0; 539 if ( tables->scope < scope ) return 0; 540 541 StructTable::const_iterator ret = tables->structTable.find( id ); 542 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope ); 543 } 544 545 EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const { 546 if ( ! tables ) return 0; 547 if ( tables->scope < scope ) return 0; 548 549 EnumTable::const_iterator ret = tables->enumTable.find( id ); 550 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope ); 551 } 552 553 UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const { 554 if ( ! tables ) return 0; 555 if ( tables->scope < scope ) return 0; 556 557 UnionTable::const_iterator ret = tables->unionTable.find( id ); 558 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope ); 559 } 560 561 TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const { 562 if ( ! tables ) return 0; 563 if ( tables->scope < scope ) return 0; 564 565 TraitTable::const_iterator ret = tables->traitTable.find( id ); 566 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope ); 567 } 568 569 bool addedIdConflicts( DeclarationWithType *existing, DeclarationWithType *added ) { 570 // if we're giving the same name mangling to things of different types then there is something wrong 571 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing ) ) 572 || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing ) ) ); 573 574 if ( LinkageSpec::isOverridable( existing->get_linkage() ) ) { 575 // new definition shadows the autogenerated one, even at the same scope 576 return false; 577 } else if ( added->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) { 578 // typesCompatible doesn't really do the right thing here. When checking compatibility of function types, 579 // we should ignore outermost pointer qualifiers, except _Atomic? 580 FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( added ); 581 FunctionDecl *oldentry = dynamic_cast< FunctionDecl* >( existing ); 582 if ( newentry && oldentry ) { 583 if ( newentry->get_statements() && oldentry->get_statements() ) { 584 throw SemanticError( "duplicate function definition for ", added ); 585 } // if 586 } else { 587 // two objects with the same mangled name defined in the same scope. 588 // both objects must be marked extern or both must be intrinsic for this to be okay 589 // xxx - perhaps it's actually if either is intrinsic then this is okay? 590 // might also need to be same storage class? 591 ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( added ); 592 ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( existing ); 593 if ( newobj->get_storageClass() != DeclarationNode::Extern && oldobj->get_storageClass() != DeclarationNode::Extern ) { 594 throw SemanticError( "duplicate object definition for ", added ); 595 } // if 596 } // if 597 } else { 598 throw SemanticError( "duplicate definition for ", added ); 599 } // if 600 601 return true; 602 } 603 604 void Indexer::addId( DeclarationWithType *decl ) { 605 makeWritable(); 606 607 const std::string &name = decl->get_name(); 608 std::string mangleName; 609 if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) { 610 // mangle the name without including the appropriate suffix, so overridable routines are placed into the 611 // same "bucket" as their user defined versions. 612 mangleName = Mangler::mangle( decl, false ); 613 } else { 614 mangleName = Mangler::mangle( decl ); 615 } // if 616 617 DeclarationWithType *existing = lookupIdAtScope( name, mangleName, scope ); 618 if ( ! existing || ! addedIdConflicts( existing, decl ) ) { 619 // this ensures that no two declarations with the same unmangled name both have C linkage 620 if ( decl->get_linkage() == LinkageSpec::C && hasIncompatibleCDecl( name, mangleName ) ) { 621 throw SemanticError( "invalid overload of C function ", decl ); 622 } // NOTE this is broken in Richard's original code in such a way that it never triggers (it 623 // doesn't check decls that have the same manglename, and all C-linkage decls are defined to 624 // have their name as their manglename, hence the error can never trigger). 625 // The code here is closer to correct, but name mangling would have to be completely 626 // isomorphic to C type-compatibility, which it may not be. 627 628 tables->idTable[ name ][ mangleName ] = decl; 629 ++tables->size; 630 } 631 } 632 633 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) { 634 if ( existing->get_base() == 0 ) { 635 return false; 636 } else if ( added->get_base() == 0 ) { 637 return true; 638 } else { 639 throw SemanticError( "redeclaration of ", added ); 640 } 641 } 642 643 void Indexer::addType( NamedTypeDecl *decl ) { 644 makeWritable(); 645 646 const std::string &id = decl->get_name(); 647 TypeTable::iterator existing = tables->typeTable.find( id ); 648 if ( existing == tables->typeTable.end() ) { 649 NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope ); 650 if ( ! parent || ! addedTypeConflicts( parent, decl ) ) { 651 tables->typeTable.insert( existing, std::make_pair( id, decl ) ); 652 ++tables->size; 653 } 654 } else { 655 if ( ! addedTypeConflicts( existing->second, decl ) ) { 656 existing->second = decl; 657 } 658 } 659 } 660 661 bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) { 662 if ( existing->get_members().empty() ) { 663 return false; 664 } else if ( ! added->get_members().empty() ) { 665 throw SemanticError( "redeclaration of ", added ); 666 } // if 667 return true; 668 } 669 670 void Indexer::addStruct( const std::string &id ) { 671 addStruct( new StructDecl( id ) ); 672 } 673 674 void Indexer::addStruct( StructDecl *decl ) { 675 makeWritable(); 676 677 const std::string &id = decl->get_name(); 678 StructTable::iterator existing = tables->structTable.find( id ); 679 if ( existing == tables->structTable.end() ) { 680 StructDecl *parent = tables->base.lookupStructAtScope( id, scope ); 681 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 682 tables->structTable.insert( existing, std::make_pair( id, decl ) ); 683 ++tables->size; 684 } 685 } else { 686 if ( ! addedDeclConflicts( existing->second, decl ) ) { 687 existing->second = decl; 688 } 689 } 690 } 691 692 void Indexer::addEnum( EnumDecl *decl ) { 693 makeWritable(); 694 695 const std::string &id = decl->get_name(); 696 EnumTable::iterator existing = tables->enumTable.find( id ); 697 if ( existing == tables->enumTable.end() ) { 698 EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope ); 699 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 700 tables->enumTable.insert( existing, std::make_pair( id, decl ) ); 701 ++tables->size; 702 } 703 } else { 704 if ( ! addedDeclConflicts( existing->second, decl ) ) { 705 existing->second = decl; 706 } 707 } 708 } 709 710 void Indexer::addUnion( const std::string &id ) { 711 addUnion( new UnionDecl( id ) ); 712 } 713 714 void Indexer::addUnion( UnionDecl *decl ) { 715 makeWritable(); 716 717 const std::string &id = decl->get_name(); 718 UnionTable::iterator existing = tables->unionTable.find( id ); 719 if ( existing == tables->unionTable.end() ) { 720 UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope ); 721 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 722 tables->unionTable.insert( existing, std::make_pair( id, decl ) ); 723 ++tables->size; 724 } 725 } else { 726 if ( ! addedDeclConflicts( existing->second, decl ) ) { 727 existing->second = decl; 728 } 729 } 730 } 731 732 void Indexer::addTrait( TraitDecl *decl ) { 733 makeWritable(); 734 735 const std::string &id = decl->get_name(); 736 TraitTable::iterator existing = tables->traitTable.find( id ); 737 if ( existing == tables->traitTable.end() ) { 738 TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope ); 739 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 740 tables->traitTable.insert( existing, std::make_pair( id, decl ) ); 741 ++tables->size; 742 } 743 } else { 744 if ( ! addedDeclConflicts( existing->second, decl ) ) { 745 existing->second = decl; 746 } 747 } 349 return unionTable.lookup( id ); 350 } 351 352 ContextDecl * Indexer::lookupContext( const std::string &id ) const { 353 return contextTable.lookup( id ); 748 354 } 749 355 750 356 void Indexer::enterScope() { 751 ++scope;752 753 357 if ( doDebug ) { 754 std::cout << "--- Entering scope " << scope << std::endl; 755 } 358 std::cout << "--- Entering scope" << std::endl; 359 } 360 idTable.enterScope(); 361 typeTable.enterScope(); 362 structTable.enterScope(); 363 enumTable.enterScope(); 364 unionTable.enterScope(); 365 contextTable.enterScope(); 756 366 } 757 367 758 368 void Indexer::leaveScope() { 759 369 using std::cout; 760 761 assert( scope > 0 && "cannot leave initial scope" ); 762 --scope; 763 764 while ( tables && tables->scope > scope ) { 765 if ( doDebug ) { 766 cout << "--- Leaving scope " << tables->scope << " containing" << std::endl; 767 dump( tables->idTable, cout ); 768 dump( tables->typeTable, cout ); 769 dump( tables->structTable, cout ); 770 dump( tables->enumTable, cout ); 771 dump( tables->unionTable, cout ); 772 dump( tables->traitTable, cout ); 773 } 774 775 // swap tables for base table until we find one at an appropriate scope 776 Indexer::Impl *base = newRef( tables->base.tables ); 777 deleteRef( tables ); 778 tables = base; 779 } 370 using std::endl; 371 372 if ( doDebug ) { 373 cout << "--- Leaving scope containing" << endl; 374 idTable.dump( cout ); 375 typeTable.dump( cout ); 376 structTable.dump( cout ); 377 enumTable.dump( cout ); 378 unionTable.dump( cout ); 379 contextTable.dump( cout ); 380 } 381 idTable.leaveScope(); 382 typeTable.leaveScope(); 383 structTable.leaveScope(); 384 enumTable.leaveScope(); 385 unionTable.leaveScope(); 386 contextTable.leaveScope(); 780 387 } 781 388 782 389 void Indexer::print( std::ostream &os, int indent ) const { 783 390 using std::cerr; 784 785 cerr << "===idTable===" << std::endl; 786 if ( tables ) dump( tables->idTable, os ); 787 cerr << "===typeTable===" << std::endl; 788 if ( tables ) dump( tables->typeTable, os ); 789 cerr << "===structTable===" << std::endl; 790 if ( tables ) dump( tables->structTable, os ); 791 cerr << "===enumTable===" << std::endl; 792 if ( tables ) dump( tables->enumTable, os ); 793 cerr << "===unionTable===" << std::endl; 794 if ( tables ) dump( tables->unionTable, os ); 795 cerr << "===contextTable===" << std::endl; 796 if ( tables ) dump( tables->traitTable, os ); 391 using std::endl; 392 393 cerr << "===idTable===" << endl; 394 idTable.dump( os ); 395 cerr << "===typeTable===" << endl; 396 typeTable.dump( os ); 397 cerr << "===structTable===" << endl; 398 structTable.dump( os ); 399 cerr << "===enumTable===" << endl; 400 enumTable.dump( os ); 401 cerr << "===unionTable===" << endl; 402 unionTable.dump( os ); 403 cerr << "===contextTable===" << endl; 404 contextTable.dump( os ); 405 #if 0 406 idTable.dump( os ); 407 typeTable.dump( os ); 408 structTable.dump( os ); 409 enumTable.dump( os ); 410 unionTable.dump( os ); 411 contextTable.dump( os ); 412 #endif 797 413 } 798 414 } // namespace SymTab
Note:
See TracChangeset
for help on using the changeset viewer.