Changeset a5a71d0 for src/SymTab
- Timestamp:
- Apr 6, 2016, 5:11:32 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, with_gc
- Children:
- eab39cd
- Parents:
- 39786813 (diff), 3aba311 (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 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.cc
r39786813 ra5a71d0 10 10 // Created On : Thu Mar 03 15:45:56 2016 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Mar 03 15:45:56201612 // Last Modified On : Mon Apr 04 17:19:28 2016 13 13 // Update Count : 1 14 14 // … … 34 34 virtual void visit( UnionDecl *structDecl ); 35 35 virtual void visit( TypeDecl *typeDecl ); 36 virtual void visit( ContextDecl *ctxDecl );36 virtual void visit( TraitDecl *ctxDecl ); 37 37 virtual void visit( FunctionDecl *functionDecl ); 38 38 … … 468 468 } 469 469 470 void AutogenerateRoutines::visit( ContextDecl *) {471 // ensure that we don't add assignment ops for types defined as part of the context470 void AutogenerateRoutines::visit( TraitDecl *) { 471 // ensure that we don't add assignment ops for types defined as part of the trait 472 472 } 473 473 -
src/SymTab/FixFunction.cc
r39786813 ra5a71d0 10 10 // Created On : Sun May 17 16:19:49 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 17 16:22:54 201513 // Update Count : 212 // Last Modified On : Wed Mar 2 17:31:10 2016 13 // Update Count : 3 14 14 // 15 15 … … 61 61 } 62 62 63 Type * FixFunction::mutate( ContextInstType *aggregateUseType) {63 Type * FixFunction::mutate(TraitInstType *aggregateUseType) { 64 64 return aggregateUseType; 65 65 } -
src/SymTab/FixFunction.h
r39786813 ra5a71d0 10 10 // Created On : Sun May 17 17:02:08 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 17 17:03:43 201513 // Update Count : 212 // Last Modified On : Wed Mar 2 17:34:06 2016 13 // Update Count : 3 14 14 // 15 15 … … 38 38 virtual Type* mutate(UnionInstType *aggregateUseType); 39 39 virtual Type* mutate(EnumInstType *aggregateUseType); 40 virtual Type* mutate( ContextInstType *aggregateUseType);40 virtual Type* mutate(TraitInstType *aggregateUseType); 41 41 virtual Type* mutate(TypeInstType *aggregateUseType); 42 42 virtual Type* mutate(TupleType *tupleType); -
src/SymTab/ImplementationType.cc
r39786813 ra5a71d0 10 10 // Created On : Sun May 17 21:32:01 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 17 21:34:40 201513 // Update Count : 212 // Last Modified On : Wed Mar 2 17:31:20 2016 13 // Update Count : 3 14 14 // 15 15 … … 37 37 virtual void visit(UnionInstType *aggregateUseType); 38 38 virtual void visit(EnumInstType *aggregateUseType); 39 virtual void visit( ContextInstType *aggregateUseType);39 virtual void visit(TraitInstType *aggregateUseType); 40 40 virtual void visit(TypeInstType *aggregateUseType); 41 41 virtual void visit(TupleType *tupleType); … … 96 96 } 97 97 98 void ImplementationType::visit( ContextInstType *aggregateUseType) {98 void ImplementationType::visit(TraitInstType *aggregateUseType) { 99 99 } 100 100 -
src/SymTab/Indexer.cc
r39786813 ra5a71d0 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:37:33 2015 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Aug 05 13:52:42 2015 13 // Update Count : 10 14 // 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" 15 29 16 30 #include "SynTree/Declaration.h" … … 19 33 #include "SynTree/Initializer.h" 20 34 #include "SynTree/Statement.h" 21 #include "Indexer.h"22 #include <typeinfo>23 #include "Common/utility.h"24 35 25 36 #define debugPrint(x) if ( doDebug ) { std::cout << x; } … … 33 44 } 34 45 35 Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {} 36 37 Indexer::~Indexer() {} 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 } 38 146 39 147 void Indexer::visit( ObjectDecl *objectDecl ) { … … 45 153 if ( objectDecl->get_name() != "" ) { 46 154 debugPrint( "Adding object " << objectDecl->get_name() << std::endl ); 47 idTable.addDecl( objectDecl );155 addId( objectDecl ); 48 156 } // if 49 157 } … … 52 160 if ( functionDecl->get_name() == "" ) return; 53 161 debugPrint( "Adding function " << functionDecl->get_name() << std::endl ); 54 idTable.addDecl( functionDecl );162 addId( functionDecl ); 55 163 enterScope(); 56 164 maybeAccept( functionDecl->get_functionType(), *this ); … … 90 198 leaveScope(); 91 199 debugPrint( "Adding type " << typeDecl->get_name() << std::endl ); 92 typeTable.add( typeDecl );200 addType( typeDecl ); 93 201 acceptAll( typeDecl->get_assertions(), *this ); 94 202 } … … 100 208 leaveScope(); 101 209 debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl ); 102 typeTable.add( typeDecl );210 addType( typeDecl ); 103 211 } 104 212 … … 108 216 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() ); 109 217 debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl ); 110 structTable.add( &fwdDecl );218 addStruct( &fwdDecl ); 111 219 112 220 enterScope(); … … 117 225 debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl ); 118 226 // this addition replaces the forward declaration 119 structTable.add( aggregateDecl );227 addStruct( aggregateDecl ); 120 228 } 121 229 … … 125 233 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() ); 126 234 debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl ); 127 unionTable.add( &fwdDecl );235 addUnion( &fwdDecl ); 128 236 129 237 enterScope(); … … 133 241 134 242 debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl ); 135 unionTable.add( aggregateDecl );243 addUnion( aggregateDecl ); 136 244 } 137 245 138 246 void Indexer::visit( EnumDecl *aggregateDecl ) { 139 247 debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl ); 140 enumTable.add( aggregateDecl );248 addEnum( aggregateDecl ); 141 249 // unlike structs, contexts, and unions, enums inject their members into the global scope 142 250 acceptAll( aggregateDecl->get_members(), *this ); 143 251 } 144 252 145 void Indexer::visit( ContextDecl *aggregateDecl ) {253 void Indexer::visit( TraitDecl *aggregateDecl ) { 146 254 enterScope(); 147 255 acceptAll( aggregateDecl->get_parameters(), *this ); … … 150 258 151 259 debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl ); 152 contextTable.add( aggregateDecl );260 addTrait( aggregateDecl ); 153 261 } 154 262 … … 293 401 294 402 295 void Indexer::visit( ContextInstType *contextInst ) {403 void Indexer::visit( TraitInstType *contextInst ) { 296 404 acceptAll( contextInst->get_parameters(), *this ); 297 405 acceptAll( contextInst->get_members(), *this ); … … 299 407 300 408 void Indexer::visit( StructInstType *structInst ) { 301 if ( ! structTable.lookup( structInst->get_name() ) ) {409 if ( ! lookupStruct( structInst->get_name() ) ) { 302 410 debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl ); 303 structTable.add( structInst->get_name() );411 addStruct( structInst->get_name() ); 304 412 } 305 413 enterScope(); … … 309 417 310 418 void Indexer::visit( UnionInstType *unionInst ) { 311 if ( ! unionTable.lookup( unionInst->get_name() ) ) {419 if ( ! lookupUnion( unionInst->get_name() ) ) { 312 420 debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl ); 313 unionTable.add( unionInst->get_name() );421 addUnion( unionInst->get_name() ); 314 422 } 315 423 enterScope(); … … 325 433 } 326 434 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); 435 436 437 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const { 438 std::unordered_set< std::string > foundMangleNames; 439 440 Indexer::Impl *searchTables = tables; 441 while ( searchTables ) { 442 443 IdTable::const_iterator decls = searchTables->idTable.find( id ); 444 if ( decls != searchTables->idTable.end() ) { 445 const MangleTable &mangleTable = decls->second; 446 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 447 // mark the mangled name as found, skipping this insertion if a declaration for that name has already been found 448 if ( foundMangleNames.insert( decl->first ).second == false ) continue; 449 450 out.push_back( decl->second ); 451 } 452 } 453 454 // get declarations from base indexers 455 searchTables = searchTables->base.tables; 456 } 334 457 } 335 458 336 459 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const { 337 return typeTable.lookup( id ); 460 if ( ! tables ) return 0; 461 462 TypeTable::const_iterator ret = tables->typeTable.find( id ); 463 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id ); 338 464 } 339 465 340 466 StructDecl *Indexer::lookupStruct( const std::string &id ) const { 341 return structTable.lookup( id ); 467 if ( ! tables ) return 0; 468 469 StructTable::const_iterator ret = tables->structTable.find( id ); 470 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id ); 342 471 } 343 472 344 473 EnumDecl *Indexer::lookupEnum( const std::string &id ) const { 345 return enumTable.lookup( id ); 474 if ( ! tables ) return 0; 475 476 EnumTable::const_iterator ret = tables->enumTable.find( id ); 477 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id ); 346 478 } 347 479 348 480 UnionDecl *Indexer::lookupUnion( const std::string &id ) const { 349 return unionTable.lookup( id ); 350 } 351 352 ContextDecl * Indexer::lookupContext( const std::string &id ) const { 353 return contextTable.lookup( id ); 481 if ( ! tables ) return 0; 482 483 UnionTable::const_iterator ret = tables->unionTable.find( id ); 484 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id ); 485 } 486 487 TraitDecl *Indexer::lookupTrait( const std::string &id ) const { 488 if ( ! tables ) return 0; 489 490 TraitTable::const_iterator ret = tables->traitTable.find( id ); 491 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id ); 492 } 493 494 DeclarationWithType *Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const { 495 if ( ! tables ) return 0; 496 if ( tables->scope < scope ) return 0; 497 498 IdTable::const_iterator decls = tables->idTable.find( id ); 499 if ( decls != tables->idTable.end() ) { 500 const MangleTable &mangleTable = decls->second; 501 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 502 if ( decl != mangleTable.end() ) return decl->second; 503 } 504 505 return tables->base.lookupIdAtScope( id, mangleName, scope ); 506 } 507 508 bool Indexer::hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const { 509 if ( ! tables ) return false; 510 511 IdTable::const_iterator decls = tables->idTable.find( id ); 512 if ( decls != tables->idTable.end() ) { 513 const MangleTable &mangleTable = decls->second; 514 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 515 // check for C decls with the same name, skipping 516 // those with a compatible type (by mangleName) 517 if ( decl->second->get_linkage() == LinkageSpec::C && decl->first != mangleName ) return true; 518 } 519 } 520 521 return tables->base.hasIncompatibleCDecl( id, mangleName ); 522 } 523 524 NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const { 525 if ( ! tables ) return 0; 526 if ( tables->scope < scope ) return 0; 527 528 TypeTable::const_iterator ret = tables->typeTable.find( id ); 529 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope ); 530 } 531 532 StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const { 533 if ( ! tables ) return 0; 534 if ( tables->scope < scope ) return 0; 535 536 StructTable::const_iterator ret = tables->structTable.find( id ); 537 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope ); 538 } 539 540 EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const { 541 if ( ! tables ) return 0; 542 if ( tables->scope < scope ) return 0; 543 544 EnumTable::const_iterator ret = tables->enumTable.find( id ); 545 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope ); 546 } 547 548 UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const { 549 if ( ! tables ) return 0; 550 if ( tables->scope < scope ) return 0; 551 552 UnionTable::const_iterator ret = tables->unionTable.find( id ); 553 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope ); 554 } 555 556 TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const { 557 if ( ! tables ) return 0; 558 if ( tables->scope < scope ) return 0; 559 560 TraitTable::const_iterator ret = tables->traitTable.find( id ); 561 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope ); 562 } 563 564 bool addedIdConflicts( DeclarationWithType *existing, DeclarationWithType *added ) { 565 // if we're giving the same name mangling to things of different types then there is something wrong 566 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing ) ) 567 || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing ) ) ); 568 569 if ( LinkageSpec::isOverridable( existing->get_linkage() ) ) { 570 // new definition shadows the autogenerated one, even at the same scope 571 return false; 572 } else if ( added->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) { 573 // typesCompatible doesn't really do the right thing here. When checking compatibility of function types, 574 // we should ignore outermost pointer qualifiers, except _Atomic? 575 FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( added ); 576 FunctionDecl *oldentry = dynamic_cast< FunctionDecl* >( existing ); 577 if ( newentry && oldentry ) { 578 if ( newentry->get_statements() && oldentry->get_statements() ) { 579 throw SemanticError( "duplicate function definition for ", added ); 580 } // if 581 } else { 582 // two objects with the same mangled name defined in the same scope. 583 // both objects must be marked extern or both must be intrinsic for this to be okay 584 // xxx - perhaps it's actually if either is intrinsic then this is okay? 585 // might also need to be same storage class? 586 ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( added ); 587 ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( existing ); 588 if ( newobj->get_storageClass() != DeclarationNode::Extern && oldobj->get_storageClass() != DeclarationNode::Extern ) { 589 throw SemanticError( "duplicate object definition for ", added ); 590 } // if 591 } // if 592 } else { 593 throw SemanticError( "duplicate definition for ", added ); 594 } // if 595 596 return true; 597 } 598 599 void Indexer::addId( DeclarationWithType *decl ) { 600 makeWritable(); 601 602 const std::string &name = decl->get_name(); 603 std::string mangleName; 604 if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) { 605 // mangle the name without including the appropriate suffix, so overridable routines are placed into the 606 // same "bucket" as their user defined versions. 607 mangleName = Mangler::mangle( decl, false ); 608 } else { 609 mangleName = Mangler::mangle( decl ); 610 } // if 611 612 DeclarationWithType *existing = lookupIdAtScope( name, mangleName, scope ); 613 if ( ! existing || ! addedIdConflicts( existing, decl ) ) { 614 // this ensures that no two declarations with the same unmangled name both have C linkage 615 if ( decl->get_linkage() == LinkageSpec::C && hasIncompatibleCDecl( name, mangleName ) ) { 616 throw SemanticError( "invalid overload of C function ", decl ); 617 } // NOTE this is broken in Richard's original code in such a way that it never triggers (it 618 // doesn't check decls that have the same manglename, and all C-linkage decls are defined to 619 // have their name as their manglename, hence the error can never trigger). 620 // The code here is closer to correct, but name mangling would have to be completely 621 // isomorphic to C type-compatibility, which it may not be. 622 623 tables->idTable[ name ][ mangleName ] = decl; 624 ++tables->size; 625 } 626 } 627 628 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) { 629 if ( existing->get_base() == 0 ) { 630 return false; 631 } else if ( added->get_base() == 0 ) { 632 return true; 633 } else { 634 throw SemanticError( "redeclaration of ", added ); 635 } 636 } 637 638 void Indexer::addType( NamedTypeDecl *decl ) { 639 makeWritable(); 640 641 const std::string &id = decl->get_name(); 642 TypeTable::iterator existing = tables->typeTable.find( id ); 643 if ( existing == tables->typeTable.end() ) { 644 NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope ); 645 if ( ! parent || ! addedTypeConflicts( parent, decl ) ) { 646 tables->typeTable.insert( existing, std::make_pair( id, decl ) ); 647 ++tables->size; 648 } 649 } else { 650 if ( ! addedTypeConflicts( existing->second, decl ) ) { 651 existing->second = decl; 652 } 653 } 654 } 655 656 bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) { 657 if ( existing->get_members().empty() ) { 658 return false; 659 } else if ( ! added->get_members().empty() ) { 660 throw SemanticError( "redeclaration of ", added ); 661 } // if 662 return true; 663 } 664 665 void Indexer::addStruct( const std::string &id ) { 666 addStruct( new StructDecl( id ) ); 667 } 668 669 void Indexer::addStruct( StructDecl *decl ) { 670 makeWritable(); 671 672 const std::string &id = decl->get_name(); 673 StructTable::iterator existing = tables->structTable.find( id ); 674 if ( existing == tables->structTable.end() ) { 675 StructDecl *parent = tables->base.lookupStructAtScope( id, scope ); 676 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 677 tables->structTable.insert( existing, std::make_pair( id, decl ) ); 678 ++tables->size; 679 } 680 } else { 681 if ( ! addedDeclConflicts( existing->second, decl ) ) { 682 existing->second = decl; 683 } 684 } 685 } 686 687 void Indexer::addEnum( EnumDecl *decl ) { 688 makeWritable(); 689 690 const std::string &id = decl->get_name(); 691 EnumTable::iterator existing = tables->enumTable.find( id ); 692 if ( existing == tables->enumTable.end() ) { 693 EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope ); 694 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 695 tables->enumTable.insert( existing, std::make_pair( id, decl ) ); 696 ++tables->size; 697 } 698 } else { 699 if ( ! addedDeclConflicts( existing->second, decl ) ) { 700 existing->second = decl; 701 } 702 } 703 } 704 705 void Indexer::addUnion( const std::string &id ) { 706 addUnion( new UnionDecl( id ) ); 707 } 708 709 void Indexer::addUnion( UnionDecl *decl ) { 710 makeWritable(); 711 712 const std::string &id = decl->get_name(); 713 UnionTable::iterator existing = tables->unionTable.find( id ); 714 if ( existing == tables->unionTable.end() ) { 715 UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope ); 716 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 717 tables->unionTable.insert( existing, std::make_pair( id, decl ) ); 718 ++tables->size; 719 } 720 } else { 721 if ( ! addedDeclConflicts( existing->second, decl ) ) { 722 existing->second = decl; 723 } 724 } 725 } 726 727 void Indexer::addTrait( TraitDecl *decl ) { 728 makeWritable(); 729 730 const std::string &id = decl->get_name(); 731 TraitTable::iterator existing = tables->traitTable.find( id ); 732 if ( existing == tables->traitTable.end() ) { 733 TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope ); 734 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 735 tables->traitTable.insert( existing, std::make_pair( id, decl ) ); 736 ++tables->size; 737 } 738 } else { 739 if ( ! addedDeclConflicts( existing->second, decl ) ) { 740 existing->second = decl; 741 } 742 } 354 743 } 355 744 356 745 void Indexer::enterScope() { 746 ++scope; 747 357 748 if ( doDebug ) { 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(); 749 std::cout << "--- Entering scope " << scope << std::endl; 750 } 366 751 } 367 752 368 753 void Indexer::leaveScope() { 369 754 using std::cout; 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(); 755 756 assert( scope > 0 && "cannot leave initial scope" ); 757 --scope; 758 759 while ( tables && tables->scope > scope ) { 760 if ( doDebug ) { 761 cout << "--- Leaving scope " << tables->scope << " containing" << std::endl; 762 dump( tables->idTable, cout ); 763 dump( tables->typeTable, cout ); 764 dump( tables->structTable, cout ); 765 dump( tables->enumTable, cout ); 766 dump( tables->unionTable, cout ); 767 dump( tables->traitTable, cout ); 768 } 769 770 // swap tables for base table until we find one at an appropriate scope 771 Indexer::Impl *base = newRef( tables->base.tables ); 772 deleteRef( tables ); 773 tables = base; 774 } 387 775 } 388 776 389 777 void Indexer::print( std::ostream &os, int indent ) const { 390 778 using std::cerr; 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 779 780 cerr << "===idTable===" << std::endl; 781 if ( tables ) dump( tables->idTable, os ); 782 cerr << "===typeTable===" << std::endl; 783 if ( tables ) dump( tables->typeTable, os ); 784 cerr << "===structTable===" << std::endl; 785 if ( tables ) dump( tables->structTable, os ); 786 cerr << "===enumTable===" << std::endl; 787 if ( tables ) dump( tables->enumTable, os ); 788 cerr << "===unionTable===" << std::endl; 789 if ( tables ) dump( tables->unionTable, os ); 790 cerr << "===contextTable===" << std::endl; 791 if ( tables ) dump( tables->traitTable, os ); 413 792 } 414 793 } // namespace SymTab -
src/SymTab/Indexer.h
r39786813 ra5a71d0 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:38:55 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Thu Sep 17 16:05:38 201513 // Update Count : 511 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:34:14 2016 13 // Update Count : 6 14 14 // 15 15 … … 21 21 22 22 #include "SynTree/Visitor.h" 23 #include "IdTable.h"24 #include "AggregateTable.h"25 #include "TypeTable.h"26 23 27 24 namespace SymTab { … … 29 26 public: 30 27 Indexer( bool useDebug = false ); 28 29 Indexer( const Indexer &that ); 30 Indexer( Indexer &&that ); 31 31 virtual ~Indexer(); 32 Indexer& operator= ( const Indexer &that ); 33 Indexer& operator= ( Indexer &&that ); 32 34 33 35 //using Visitor::visit; … … 39 41 virtual void visit( UnionDecl *aggregateDecl ); 40 42 virtual void visit( EnumDecl *aggregateDecl ); 41 virtual void visit( ContextDecl *aggregateDecl );43 virtual void visit( TraitDecl *aggregateDecl ); 42 44 43 45 virtual void visit( CompoundStmt *compoundStmt ); … … 67 69 virtual void visit( UntypedValofExpr *valofExpr ); 68 70 69 virtual void visit( ContextInstType *contextInst );71 virtual void visit( TraitInstType *contextInst ); 70 72 virtual void visit( StructInstType *contextInst ); 71 73 virtual void visit( UnionInstType *contextInst ); … … 78 80 void leaveScope(); 79 81 80 void lookupId( const std::string &id, std::list< DeclarationWithType* >& ) const; 81 DeclarationWithType* lookupId( const std::string &id) const; 82 /// Gets all declarations with the given ID 83 void lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const; 84 /// Gets the top-most type declaration with the given ID 82 85 NamedTypeDecl *lookupType( const std::string &id ) const; 86 /// Gets the top-most struct declaration with the given ID 83 87 StructDecl *lookupStruct( const std::string &id ) const; 88 /// Gets the top-most enum declaration with the given ID 84 89 EnumDecl *lookupEnum( const std::string &id ) const; 90 /// Gets the top-most union declaration with the given ID 85 91 UnionDecl *lookupUnion( const std::string &id ) const; 86 ContextDecl *lookupContext( const std::string &id ) const; 92 /// Gets the top-most trait declaration with the given ID 93 TraitDecl *lookupTrait( const std::string &id ) const; 87 94 88 95 void print( std::ostream &os, int indent = 0 ) const; 89 96 private: 90 IdTable idTable; 91 TypeTable typeTable; 92 StructTable structTable; 93 EnumTable enumTable; 94 UnionTable unionTable; 95 ContextTable contextTable; 96 97 bool doDebug; // display debugging trace 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 with a different mangled name 100 bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const; 101 // equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope) 102 NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const; 103 StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const; 104 EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const; 105 UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const; 106 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const; 107 108 void addId( DeclarationWithType *decl ); 109 void addType( NamedTypeDecl *decl ); 110 void addStruct( const std::string &id ); 111 void addStruct( StructDecl *decl ); 112 void addEnum( EnumDecl *decl ); 113 void addUnion( const std::string &id ); 114 void addUnion( UnionDecl *decl ); 115 void addTrait( TraitDecl *decl ); 116 117 struct Impl; 118 Impl *tables; ///< Copy-on-write instance of table data structure 119 unsigned long scope; ///< Scope index of this pointer 120 bool doDebug; ///< Display debugging trace? 121 122 /// Takes a new ref to a table (returns null if null) 123 static Impl *newRef( Impl *toClone ); 124 /// Clears a ref to a table (does nothing if null) 125 static void deleteRef( Impl *toFree ); 126 127 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope) 128 void makeWritable(); 98 129 }; 99 130 } // namespace SymTab -
src/SymTab/Mangler.cc
r39786813 ra5a71d0 227 227 228 228 void Mangler::visit( VarArgsType *varArgsType ) { 229 printQualifiers( varArgsType ); 229 230 mangleName << "VARGS"; 230 231 } -
src/SymTab/TypeEquality.cc
r39786813 ra5a71d0 194 194 195 195 void TypeEquality::visit( VarArgsType *varArgsType ) { 196 // don't handle qualifiers; var args pack shouldn't have any196 handleQualifiers( varArgsType ); 197 197 if ( ! dynamic_cast< VarArgsType * >( other ) ) { 198 198 result = false; -
src/SymTab/Validate.cc
r39786813 ra5a71d0 10 10 // Created On : Sun May 17 21:50:04 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon Feb 22 12:26:37201612 // Last Modified On : Mon Apr 04 17:13:29 2016 13 13 // Update Count : 297 14 14 // … … 102 102 virtual void visit( StructInstType *structInst ); 103 103 virtual void visit( UnionInstType *unionInst ); 104 virtual void visit( ContextInstType *contextInst );104 virtual void visit( TraitInstType *contextInst ); 105 105 virtual void visit( StructDecl *structDecl ); 106 106 virtual void visit( UnionDecl *unionDecl ); … … 158 158 virtual Declaration *mutate( UnionDecl * unionDecl ); 159 159 virtual Declaration *mutate( EnumDecl * enumDecl ); 160 virtual Declaration *mutate( ContextDecl * contextDecl );160 virtual Declaration *mutate( TraitDecl * contextDecl ); 161 161 162 162 template<typename AggDecl> … … 370 370 } 371 371 372 void Pass2::visit( ContextInstType *contextInst ) {372 void Pass2::visit( TraitInstType *contextInst ) { 373 373 Parent::visit( contextInst ); 374 ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );374 TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() ); 375 375 if ( ! ctx ) { 376 376 throw SemanticError( "use of undeclared context " + contextInst->get_name() ); … … 378 378 for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) { 379 379 for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) { 380 if ( ContextInstType *otherCtx = dynamic_cast< ContextInstType * >(*assert ) ) {380 if ( TraitInstType *otherCtx = dynamic_cast< TraitInstType * >(*assert ) ) { 381 381 cloneAll( otherCtx->get_members(), contextInst->get_members() ); 382 382 } else { … … 442 442 while ( ! toBeDone.empty() ) { 443 443 for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) { 444 if ( ContextInstType *ctx = dynamic_cast< ContextInstType * >( (*assertion )->get_type() ) ) {444 if ( TraitInstType *ctx = dynamic_cast< TraitInstType * >( (*assertion )->get_type() ) ) { 445 445 for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) { 446 446 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i ); … … 652 652 } 653 653 654 Declaration *EliminateTypedef::mutate( ContextDecl * contextDecl ) {654 Declaration *EliminateTypedef::mutate( TraitDecl * contextDecl ) { 655 655 Mutator::mutate( contextDecl ); 656 656 return handleAggregate( contextDecl ); -
src/SymTab/module.mk
r39786813 ra5a71d0 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.