Changeset bed4c63e for src/SymTab
- Timestamp:
- Mar 8, 2016, 5:52:39 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:
- ac633d0, ae357ec
- Parents:
- 52c2a72
- Location:
- src/SymTab
- Files:
-
- 2 deleted
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Indexer.cc
r52c2a72 rbed4c63e 21 21 #include <utility> 22 22 23 #include "IdTable.h" 23 #include "Mangler.h" 24 25 #include "Common/utility.h" 26 27 #include "ResolvExpr/typeops.h" 24 28 25 29 #include "SynTree/Declaration.h" … … 28 32 #include "SynTree/Initializer.h" 29 33 #include "SynTree/Statement.h" 30 31 #include "Common/utility.h"32 34 33 35 #define debugPrint(x) if ( doDebug ) { std::cout << x; } … … 41 43 } 42 44 45 typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable; 46 typedef std::unordered_map< std::string, MangleTable > IdTable; 43 47 typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable; 44 48 typedef std::unordered_map< std::string, StructDecl* > StructTable; … … 47 51 typedef std::unordered_map< std::string, TraitDecl* > TraitTable; 48 52 53 void dump( const IdTable &table, std::ostream &os ) { 54 for ( IdTable::const_iterator id = table.begin(); id != table.end(); ++id ) { 55 for ( MangleTable::const_iterator mangle = id->second.begin(); mangle != id->second.end(); ++mangle ) { 56 os << mangle->second << std::endl; 57 } 58 } 59 } 60 49 61 template< typename Decl > 50 62 void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) { … … 420 432 } 421 433 422 423 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const { 434 435 436 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const { 424 437 if ( ! tables ) return; 438 439 IdTable::const_iterator decls = tables->idTable.find( id ); 440 if ( decls != tables->idTable.end() ) { 441 const MangleTable &mangleTable = decls->second; 442 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 443 out.push_back( decl->second ); 444 } 445 } 425 446 426 tables->idTable.lookupId( id, list ); 427 tables->base.lookupId( id, list ); 428 } 429 430 DeclarationWithType* Indexer::lookupId( const std::string &id) const { 431 if ( ! tables ) return 0; 432 433 DeclarationWithType *ret = tables->idTable.lookupId(id); 434 return ret ? ret : tables->base.lookupId(id); 447 // get declarations from base indexers 448 tables->base.lookupId( id, out ); 435 449 } 436 450 … … 470 484 } 471 485 486 DeclarationWithType *Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const { 487 if ( ! tables ) return 0; 488 if ( tables->scope < scope ) return 0; 489 490 IdTable::const_iterator decls = tables->idTable.find( id ); 491 if ( decls != tables->idTable.end() ) { 492 const MangleTable &mangleTable = decls->second; 493 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 494 if ( decl != mangleTable.end() ) return decl->second; 495 } 496 497 return tables->base.lookupIdAtScope( id, mangleName, scope ); 498 } 499 500 bool Indexer::hasCDeclWithName( const std::string &id ) const { 501 if ( ! tables ) return false; 502 503 IdTable::const_iterator decls = tables->idTable.find( id ); 504 if ( decls != tables->idTable.end() ) { 505 const MangleTable &mangleTable = decls->second; 506 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 507 if ( decl->second->get_linkage() == LinkageSpec::C ) return true; 508 } 509 } 510 511 return tables->base.hasCDeclWithName( id ); 512 } 513 472 514 NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const { 473 515 if ( ! tables ) return 0; … … 510 552 } 511 553 554 bool addedIdConflicts( DeclarationWithType *existing, DeclarationWithType *added ) { 555 // if we're giving the same name mangling to things of different types then there is something wrong 556 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing ) ) 557 || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing ) ) ); 558 559 if ( LinkageSpec::isOverridable( existing->get_linkage() ) ) { 560 // new definition shadows the autogenerated one, even at the same scope 561 return false; 562 } else if ( added->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) { 563 // typesCompatible doesn't really do the right thing here. When checking compatibility of function types, 564 // we should ignore outermost pointer qualifiers, except _Atomic? 565 FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( added ); 566 FunctionDecl *oldentry = dynamic_cast< FunctionDecl* >( existing ); 567 if ( newentry && oldentry ) { 568 if ( newentry->get_statements() && oldentry->get_statements() ) { 569 throw SemanticError( "duplicate function definition for ", added ); 570 } // if 571 } else { 572 // two objects with the same mangled name defined in the same scope. 573 // both objects must be marked extern or both must be intrinsic for this to be okay 574 // xxx - perhaps it's actually if either is intrinsic then this is okay? 575 // might also need to be same storage class? 576 ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( added ); 577 ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( existing ); 578 if ( newobj->get_storageClass() != DeclarationNode::Extern && oldobj->get_storageClass() != DeclarationNode::Extern ) { 579 throw SemanticError( "duplicate object definition for ", added ); 580 } // if 581 } // if 582 } else { 583 throw SemanticError( "duplicate definition for ", added ); 584 } // if 585 586 return true; 587 } 588 512 589 void Indexer::addId( DeclarationWithType *decl ) { 513 590 makeWritable(); 514 tables->idTable.addDecl( decl ); 515 ++tables->size; 591 592 const std::string &name = decl->get_name(); 593 std::string mangleName; 594 if ( decl->get_linkage() == LinkageSpec::C ) { 595 mangleName = name; 596 } else if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) { 597 // mangle the name without including the appropriate suffix, so overridable routines are placed into the 598 // same "bucket" as their user defined versions. 599 mangleName = Mangler::mangle( decl, false ); 600 } else { 601 mangleName = Mangler::mangle( decl ); 602 } // if 603 604 DeclarationWithType *existing = lookupIdAtScope( name, mangleName, scope ); 605 if ( ! existing || ! addedIdConflicts( existing, decl ) ) { 606 // this ensures that no two declarations with the same unmangled name both have C linkage 607 if ( decl->get_linkage() == LinkageSpec::C && hasCDeclWithName( name ) ) { 608 throw SemanticError( "invalid overload of C function ", decl ); 609 } 610 611 tables->idTable[ name ][ mangleName ] = decl; 612 ++tables->size; 613 } 516 614 } 517 615 … … 650 748 if ( doDebug ) { 651 749 cout << "--- Leaving scope " << tables->scope << " containing" << std::endl; 652 tables->idTable.dump(cout );750 dump( tables->idTable, cout ); 653 751 dump( tables->typeTable, cout ); 654 752 dump( tables->structTable, cout ); … … 669 767 670 768 cerr << "===idTable===" << std::endl; 671 if ( tables ) tables->idTable.dump(os );769 if ( tables ) dump( tables->idTable, os ); 672 770 cerr << "===typeTable===" << std::endl; 673 771 if ( tables ) dump( tables->typeTable, os ); -
src/SymTab/Indexer.h
r52c2a72 rbed4c63e 80 80 void leaveScope(); 81 81 82 /// Gets all declarations with the given ID 82 83 void lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const; 83 DeclarationWithType* lookupId( const std::string &id ) const;84 /// Gets the top-most type declaration with the given ID 84 85 NamedTypeDecl *lookupType( const std::string &id ) const; 86 /// Gets the top-most struct declaration with the given ID 85 87 StructDecl *lookupStruct( const std::string &id ) const; 88 /// Gets the top-most enum declaration with the given ID 86 89 EnumDecl *lookupEnum( const std::string &id ) const; 90 /// Gets the top-most union declaration with the given ID 87 91 UnionDecl *lookupUnion( const std::string &id ) const; 92 /// Gets the top-most trait declaration with the given ID 88 93 TraitDecl *lookupTrait( const std::string &id ) const; 89 94 90 95 void print( std::ostream &os, int indent = 0 ) const; 91 96 private: 97 /// looks up a specific mangled ID at the given scope 98 DeclarationWithType *lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const; 99 /// returns true if there exists a declaration with C linkage and the given name 100 bool hasCDeclWithName( const std::string &id ) const; 92 101 // equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope) 93 102 NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const; -
src/SymTab/module.mk
r52c2a72 rbed4c63e 15 15 ############################################################################### 16 16 17 SRC += SymTab/IdTable.cc \ 18 SymTab/Indexer.cc \ 17 SRC += SymTab/Indexer.cc \ 19 18 SymTab/Mangler.cc \ 20 19 SymTab/Validate.cc \
Note: See TracChangeset
for help on using the changeset viewer.