Changeset 52c2a72
- Timestamp:
- Mar 8, 2016, 4:28:40 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- bed4c63e
- Parents:
- e8032b0
- Location:
- src/SymTab
- Files:
-
- 4 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Indexer.cc
re8032b0 r52c2a72 16 16 #include "Indexer.h" 17 17 18 #include <string> 19 #include <typeinfo> 20 #include <unordered_map> 21 #include <utility> 22 18 23 #include "IdTable.h" 19 #include "AggregateTable.h"20 #include "TypeTable.h"21 24 22 25 #include "SynTree/Declaration.h" … … 26 29 #include "SynTree/Statement.h" 27 30 28 #include <typeinfo>29 #include <utility>30 31 #include "Common/utility.h" 31 32 … … 40 41 } 41 42 43 typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable; 44 typedef std::unordered_map< std::string, StructDecl* > StructTable; 45 typedef std::unordered_map< std::string, EnumDecl* > EnumTable; 46 typedef std::unordered_map< std::string, UnionDecl* > UnionTable; 47 typedef std::unordered_map< std::string, TraitDecl* > TraitTable; 48 49 template< typename Decl > 50 void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) { 51 for ( typename std::unordered_map< std::string, Decl* >::const_iterator it = table.begin(); it != table.end(); ++it ) { 52 os << it->second << std::endl; 53 } // for 54 } 55 42 56 struct Indexer::Impl { 43 Impl( ) : refCount(1), size(0), base(),57 Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(), 44 58 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {} 45 Impl( const Indexer &_base ) : refCount(1), size(0), base( _base ),59 Impl( unsigned long _scope, Indexer &&_base ) : refCount(1), scope( _scope ), size( 0 ), base( _base ), 46 60 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {} 47 61 unsigned long refCount; ///< Number of references to these tables 62 unsigned long scope; ///< Scope these tables are associated with 48 63 unsigned long size; ///< Number of elements stored in this table 49 64 const Indexer base; ///< Base indexer this extends … … 75 90 void Indexer::makeWritable() { 76 91 if ( ! tables ) { 77 tables = new Indexer::Impl;78 } else if ( tables->refCount > 1 ) {79 // tables->base inherits the ref that used to belong to this indexer80 // this is basically equivalent to std::move( *this ) as the argument81 tables = new Indexer::Impl( Indexer( tables, doDebug) );82 } 83 } 84 85 Indexer::Indexer( bool _doDebug ) : tables( 0), doDebug( _doDebug ) {}86 87 Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), doDebug( that.doDebug ) {}88 89 Indexer::Indexer( Indexer &&that ) : tables( that.tables ), doDebug( that.doDebug ) {92 // create indexer if not yet set 93 tables = new Indexer::Impl( scope ); 94 } else if ( tables->refCount > 1 || tables->scope != scope ) { 95 // make this indexer the base of a fresh indexer at the current scope 96 tables = new Indexer::Impl( scope, std::move( *this ) ); 97 } 98 } 99 100 Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {} 101 102 Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {} 103 104 Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) { 90 105 that.tables = 0; 91 106 } … … 99 114 100 115 tables = newRef( that.tables ); 116 scope = that.scope; 101 117 doDebug = that.doDebug; 102 118 … … 108 124 109 125 tables = that.tables; 126 scope = that.scope; 110 127 doDebug = that.doDebug; 111 128 … … 421 438 if ( ! tables ) return 0; 422 439 423 NamedTypeDecl *ret = tables->typeTable.lookup( id );424 return ret ? ret: tables->base.lookupType( id );440 TypeTable::const_iterator ret = tables->typeTable.find( id ); 441 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id ); 425 442 } 426 443 … … 428 445 if ( ! tables ) return 0; 429 446 430 Struct Decl *ret = tables->structTable.lookup( id );431 return ret ? ret: tables->base.lookupStruct( id );447 StructTable::const_iterator ret = tables->structTable.find( id ); 448 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id ); 432 449 } 433 450 … … 435 452 if ( ! tables ) return 0; 436 453 437 Enum Decl *ret = tables->enumTable.lookup( id );438 return ret ? ret: tables->base.lookupEnum( id );454 EnumTable::const_iterator ret = tables->enumTable.find( id ); 455 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id ); 439 456 } 440 457 … … 442 459 if ( ! tables ) return 0; 443 460 444 Union Decl *ret = tables->unionTable.lookup( id );445 return ret ? ret: tables->base.lookupUnion( id );461 UnionTable::const_iterator ret = tables->unionTable.find( id ); 462 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id ); 446 463 } 447 464 … … 449 466 if ( ! tables ) return 0; 450 467 451 TraitDecl *ret = tables->traitTable.lookup( id ); 452 return ret ? ret : tables->base.lookupTrait( id ); 468 TraitTable::const_iterator ret = tables->traitTable.find( id ); 469 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id ); 470 } 471 472 NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const { 473 if ( ! tables ) return 0; 474 if ( tables->scope < scope ) return 0; 475 476 TypeTable::const_iterator ret = tables->typeTable.find( id ); 477 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope ); 478 } 479 480 StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const { 481 if ( ! tables ) return 0; 482 if ( tables->scope < scope ) return 0; 483 484 StructTable::const_iterator ret = tables->structTable.find( id ); 485 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope ); 486 } 487 488 EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const { 489 if ( ! tables ) return 0; 490 if ( tables->scope < scope ) return 0; 491 492 EnumTable::const_iterator ret = tables->enumTable.find( id ); 493 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope ); 494 } 495 496 UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const { 497 if ( ! tables ) return 0; 498 if ( tables->scope < scope ) return 0; 499 500 UnionTable::const_iterator ret = tables->unionTable.find( id ); 501 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope ); 502 } 503 504 TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const { 505 if ( ! tables ) return 0; 506 if ( tables->scope < scope ) return 0; 507 508 TraitTable::const_iterator ret = tables->traitTable.find( id ); 509 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope ); 453 510 } 454 511 … … 458 515 ++tables->size; 459 516 } 517 518 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) { 519 if ( existing->get_base() == 0 ) { 520 return false; 521 } else if ( added->get_base() == 0 ) { 522 return true; 523 } else { 524 throw SemanticError( "redeclaration of ", added ); 525 } 526 } 460 527 461 528 void Indexer::addType( NamedTypeDecl *decl ) { 462 529 makeWritable(); 463 tables->typeTable.add( decl ); 464 ++tables->size; 530 531 const std::string &id = decl->get_name(); 532 TypeTable::iterator existing = tables->typeTable.find( id ); 533 if ( existing == tables->typeTable.end() ) { 534 NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope ); 535 if ( ! parent || ! addedTypeConflicts( parent, decl ) ) { 536 tables->typeTable.insert( existing, std::make_pair( id, decl ) ); 537 ++tables->size; 538 } 539 } else { 540 if ( ! addedTypeConflicts( existing->second, decl ) ) { 541 existing->second = decl; 542 } 543 } 544 } 545 546 bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) { 547 if ( existing->get_members().empty() ) { 548 return false; 549 } else if ( ! added->get_members().empty() ) { 550 throw SemanticError( "redeclaration of ", added ); 551 } // if 552 return true; 465 553 } 466 554 467 555 void Indexer::addStruct( const std::string &id ) { 468 makeWritable(); 469 tables->structTable.add( id ); 470 ++tables->size; 556 addStruct( new StructDecl( id ) ); 471 557 } 472 558 473 559 void Indexer::addStruct( StructDecl *decl ) { 474 560 makeWritable(); 475 tables->structTable.add( decl ); 476 ++tables->size; 561 562 const std::string &id = decl->get_name(); 563 StructTable::iterator existing = tables->structTable.find( id ); 564 if ( existing == tables->structTable.end() ) { 565 StructDecl *parent = tables->base.lookupStructAtScope( id, scope ); 566 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 567 tables->structTable.insert( existing, std::make_pair( id, decl ) ); 568 ++tables->size; 569 } 570 } else { 571 if ( ! addedDeclConflicts( existing->second, decl ) ) { 572 existing->second = decl; 573 } 574 } 477 575 } 478 576 479 577 void Indexer::addEnum( EnumDecl *decl ) { 480 578 makeWritable(); 481 tables->enumTable.add( decl ); 482 ++tables->size; 579 580 const std::string &id = decl->get_name(); 581 EnumTable::iterator existing = tables->enumTable.find( id ); 582 if ( existing == tables->enumTable.end() ) { 583 EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope ); 584 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 585 tables->enumTable.insert( existing, std::make_pair( id, decl ) ); 586 ++tables->size; 587 } 588 } else { 589 if ( ! addedDeclConflicts( existing->second, decl ) ) { 590 existing->second = decl; 591 } 592 } 483 593 } 484 594 485 595 void Indexer::addUnion( const std::string &id ) { 486 makeWritable(); 487 tables->unionTable.add( id ); 488 ++tables->size; 596 addUnion( new UnionDecl( id ) ); 489 597 } 490 598 491 599 void Indexer::addUnion( UnionDecl *decl ) { 492 600 makeWritable(); 493 tables->unionTable.add( decl ); 494 ++tables->size; 601 602 const std::string &id = decl->get_name(); 603 UnionTable::iterator existing = tables->unionTable.find( id ); 604 if ( existing == tables->unionTable.end() ) { 605 UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope ); 606 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 607 tables->unionTable.insert( existing, std::make_pair( id, decl ) ); 608 ++tables->size; 609 } 610 } else { 611 if ( ! addedDeclConflicts( existing->second, decl ) ) { 612 existing->second = decl; 613 } 614 } 495 615 } 496 616 497 617 void Indexer::addTrait( TraitDecl *decl ) { 498 618 makeWritable(); 499 tables->traitTable.add( decl ); 500 ++tables->size; 619 620 const std::string &id = decl->get_name(); 621 TraitTable::iterator existing = tables->traitTable.find( id ); 622 if ( existing == tables->traitTable.end() ) { 623 TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope ); 624 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 625 tables->traitTable.insert( existing, std::make_pair( id, decl ) ); 626 ++tables->size; 627 } 628 } else { 629 if ( ! addedDeclConflicts( existing->second, decl ) ) { 630 existing->second = decl; 631 } 632 } 501 633 } 502 634 503 635 void Indexer::enterScope() { 504 makeWritable();636 ++scope; 505 637 506 638 if ( doDebug ) { 507 std::cout << "--- Entering scope" << std::endl; 508 } 509 510 tables->idTable.enterScope(); 511 tables->typeTable.enterScope(); 512 tables->structTable.enterScope(); 513 tables->enumTable.enterScope(); 514 tables->unionTable.enterScope(); 515 tables->traitTable.enterScope(); 639 std::cout << "--- Entering scope " << scope << std::endl; 640 } 516 641 } 517 642 518 643 void Indexer::leaveScope() { 519 644 using std::cout; 520 521 makeWritable(); 522 523 if ( doDebug ) { 524 cout << "--- Leaving scope containing" << std::endl; 525 tables->idTable.dump( cout ); 526 tables->typeTable.dump( cout ); 527 tables->structTable.dump( cout ); 528 tables->enumTable.dump( cout ); 529 tables->unionTable.dump( cout ); 530 tables->traitTable.dump( cout ); 531 } 532 tables->idTable.leaveScope(); 533 tables->typeTable.leaveScope(); 534 tables->structTable.leaveScope(); 535 tables->enumTable.leaveScope(); 536 tables->unionTable.leaveScope(); 537 tables->traitTable.leaveScope(); 645 646 assert( scope > 0 && "cannot leave initial scope" ); 647 --scope; 648 649 while ( tables && tables->scope > scope ) { 650 if ( doDebug ) { 651 cout << "--- Leaving scope " << tables->scope << " containing" << std::endl; 652 tables->idTable.dump( cout ); 653 dump( tables->typeTable, cout ); 654 dump( tables->structTable, cout ); 655 dump( tables->enumTable, cout ); 656 dump( tables->unionTable, cout ); 657 dump( tables->traitTable, cout ); 658 } 659 660 // swap tables for base table until we find one at an appropriate scope 661 Indexer::Impl *base = newRef( tables->base.tables ); 662 deleteRef( tables ); 663 tables = base; 664 } 538 665 } 539 666 … … 544 671 if ( tables ) tables->idTable.dump( os ); 545 672 cerr << "===typeTable===" << std::endl; 546 if ( tables ) tables->typeTable.dump(os );673 if ( tables ) dump( tables->typeTable, os ); 547 674 cerr << "===structTable===" << std::endl; 548 if ( tables ) tables->structTable.dump(os );675 if ( tables ) dump( tables->structTable, os ); 549 676 cerr << "===enumTable===" << std::endl; 550 if ( tables ) tables->enumTable.dump(os );677 if ( tables ) dump( tables->enumTable, os ); 551 678 cerr << "===unionTable===" << std::endl; 552 if ( tables ) tables->unionTable.dump(os );679 if ( tables ) dump( tables->unionTable, os ); 553 680 cerr << "===contextTable===" << std::endl; 554 if ( tables ) tables->traitTable.dump(os );681 if ( tables ) dump( tables->traitTable, os ); 555 682 } 556 683 } // namespace SymTab -
src/SymTab/Indexer.h
re8032b0 r52c2a72 90 90 void print( std::ostream &os, int indent = 0 ) const; 91 91 private: 92 // equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope) 93 NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const; 94 StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const; 95 EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const; 96 UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const; 97 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const; 98 92 99 void addId( DeclarationWithType *decl ); 93 100 void addType( NamedTypeDecl *decl ); … … 100 107 101 108 struct Impl; 102 Impl *tables; ///< Copy-on-write instance of table data structure 103 bool doDebug; ///< Display debugging trace? 104 105 Indexer( Impl *_tables, bool _doDebug ) : tables( _tables ), doDebug( _doDebug ) {} 109 Impl *tables; ///< Copy-on-write instance of table data structure 110 unsigned long scope; ///< Scope index of this pointer 111 bool doDebug; ///< Display debugging trace? 106 112 107 113 /// Takes a new ref to a table (returns null if null) … … 110 116 static void deleteRef( Impl *toFree ); 111 117 112 /// Ensures that tables variable is writable (i.e. allocated and uniquely owned by this Indexer)118 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope) 113 119 void makeWritable(); 114 120 };
Note: See TracChangeset
for help on using the changeset viewer.