Changeset ae357ec for src/SymTab


Ignore:
Timestamp:
Mar 8, 2016, 10:25:06 PM (10 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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, stuck-waitfor-destruct, with_gc
Children:
5447e09
Parents:
b63e376 (diff), bed4c63e (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.
Message:

Merge branch 'master' of plg2:software/cfa/cfa-cc

Location:
src/SymTab
Files:
6 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    rb63e376 rae357ec  
    1414//
    1515
     16#include "Indexer.h"
     17
     18#include <string>
     19#include <typeinfo>
     20#include <unordered_map>
     21#include <utility>
     22
     23#include "Mangler.h"
     24
     25#include "Common/utility.h"
     26
     27#include "ResolvExpr/typeops.h"
     28
    1629#include "SynTree/Declaration.h"
    1730#include "SynTree/Type.h"
     
    1932#include "SynTree/Initializer.h"
    2033#include "SynTree/Statement.h"
    21 #include "Indexer.h"
    22 #include <typeinfo>
    23 #include "Common/utility.h"
    2434
    2535#define debugPrint(x) if ( doDebug ) { std::cout << x; }
     
    3343        }
    3444
    35         Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {}
    36 
    37         Indexer::~Indexer() {}
     45        typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
     46        typedef std::unordered_map< std::string, MangleTable > IdTable;
     47        typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable;
     48        typedef std::unordered_map< std::string, StructDecl* > StructTable;
     49        typedef std::unordered_map< std::string, EnumDecl* > EnumTable;
     50        typedef std::unordered_map< std::string, UnionDecl* > UnionTable;
     51        typedef std::unordered_map< std::string, TraitDecl* > TraitTable;
     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       
     61        template< typename Decl >
     62        void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) {
     63                for ( typename std::unordered_map< std::string, Decl* >::const_iterator it = table.begin(); it != table.end(); ++it ) {
     64                        os << it->second << std::endl;
     65                } // for
     66        }
     67       
     68        struct Indexer::Impl {
     69                Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(),
     70                                idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
     71                Impl( unsigned long _scope, Indexer &&_base ) : refCount(1), scope( _scope ), size( 0 ), base( _base ),
     72                                idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
     73                unsigned long refCount;   ///< Number of references to these tables
     74                unsigned long scope;      ///< Scope these tables are associated with
     75                unsigned long size;       ///< Number of elements stored in this table
     76                const Indexer base;       ///< Base indexer this extends
     77               
     78                IdTable idTable;          ///< Identifier namespace
     79                TypeTable typeTable;      ///< Type namespace
     80                StructTable structTable;  ///< Struct namespace
     81                EnumTable enumTable;      ///< Enum namespace
     82                UnionTable unionTable;    ///< Union namespace
     83                TraitTable traitTable;    ///< Trait namespace
     84        };
     85
     86        Indexer::Impl *Indexer::newRef( Indexer::Impl *toClone ) {
     87                if ( ! toClone ) return 0;
     88
     89                // shorten the search chain by skipping empty links
     90                Indexer::Impl *ret = toClone->size == 0 ? toClone->base.tables : toClone;
     91                if ( ret ) { ++ret->refCount; }
     92
     93                return ret;
     94        }
     95
     96        void Indexer::deleteRef( Indexer::Impl *toFree ) {
     97                if ( ! toFree ) return;
     98
     99                if ( --toFree->refCount == 0 ) delete toFree;
     100        }
     101
     102        void Indexer::makeWritable() {
     103                if ( ! tables ) {
     104                        // create indexer if not yet set
     105                        tables = new Indexer::Impl( scope );
     106                } else if ( tables->refCount > 1 || tables->scope != scope ) {
     107                        // make this indexer the base of a fresh indexer at the current scope
     108                        tables = new Indexer::Impl( scope, std::move( *this ) );
     109                }
     110        }
     111
     112        Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {}
     113
     114        Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {}
     115
     116        Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) {
     117                that.tables = 0;
     118        }
     119
     120        Indexer::~Indexer() {
     121                deleteRef( tables );
     122        }
     123
     124        Indexer& Indexer::operator= ( const Indexer &that ) {
     125                deleteRef( tables );
     126
     127                tables = newRef( that.tables );
     128                scope = that.scope;
     129                doDebug = that.doDebug;
     130
     131                return *this;
     132        }
     133
     134        Indexer& Indexer::operator= ( Indexer &&that ) {
     135                deleteRef( tables );
     136
     137                tables = that.tables;
     138                scope = that.scope;
     139                doDebug = that.doDebug;
     140
     141                that.tables = 0;
     142
     143                return *this;
     144        }
    38145
    39146        void Indexer::visit( ObjectDecl *objectDecl ) {
     
    45152                if ( objectDecl->get_name() != "" ) {
    46153                        debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
    47                         idTable.addDecl( objectDecl );
     154                        addId( objectDecl );
    48155                } // if
    49156        }
     
    52159                if ( functionDecl->get_name() == "" ) return;
    53160                debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
    54                 idTable.addDecl( functionDecl );
     161                addId( functionDecl );
    55162                enterScope();
    56163                maybeAccept( functionDecl->get_functionType(), *this );
     
    90197                leaveScope();
    91198                debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
    92                 typeTable.add( typeDecl );
     199                addType( typeDecl );
    93200                acceptAll( typeDecl->get_assertions(), *this );
    94201        }
     
    100207                leaveScope();
    101208                debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
    102                 typeTable.add( typeDecl );
     209                addType( typeDecl );
    103210        }
    104211
     
    108215                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
    109216                debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
    110                 structTable.add( &fwdDecl );
     217                addStruct( &fwdDecl );
    111218 
    112219                enterScope();
     
    117224                debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
    118225                // this addition replaces the forward declaration
    119                 structTable.add( aggregateDecl );
     226                addStruct( aggregateDecl );
    120227        }
    121228
     
    125232                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
    126233                debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
    127                 unionTable.add( &fwdDecl );
     234                addUnion( &fwdDecl );
    128235 
    129236                enterScope();
     
    133240 
    134241                debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
    135                 unionTable.add( aggregateDecl );
     242                addUnion( aggregateDecl );
    136243        }
    137244
    138245        void Indexer::visit( EnumDecl *aggregateDecl ) {
    139246                debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
    140                 enumTable.add( aggregateDecl );
     247                addEnum( aggregateDecl );
    141248                // unlike structs, contexts, and unions, enums inject their members into the global scope
    142249                acceptAll( aggregateDecl->get_members(), *this );
     
    150257 
    151258                debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
    152                 contextTable.add( aggregateDecl );
     259                addTrait( aggregateDecl );
    153260        }
    154261
     
    299406
    300407        void Indexer::visit( StructInstType *structInst ) {
    301                 if ( ! structTable.lookup( structInst->get_name() ) ) {
     408                if ( ! lookupStruct( structInst->get_name() ) ) {
    302409                        debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
    303                         structTable.add( structInst->get_name() );
     410                        addStruct( structInst->get_name() );
    304411                }
    305412                enterScope();
     
    309416
    310417        void Indexer::visit( UnionInstType *unionInst ) {
    311                 if ( ! unionTable.lookup( unionInst->get_name() ) ) {
     418                if ( ! lookupUnion( unionInst->get_name() ) ) {
    312419                        debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
    313                         unionTable.add( unionInst->get_name() );
     420                        addUnion( unionInst->get_name() );
    314421                }
    315422                enterScope();
     
    325432        }
    326433
    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);
     434       
     435
     436        void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const {
     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                }
     446               
     447                // get declarations from base indexers
     448                tables->base.lookupId( id, out );
    334449        }
    335450
    336451        NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
    337                 return typeTable.lookup( id );
     452                if ( ! tables ) return 0;
     453
     454                TypeTable::const_iterator ret = tables->typeTable.find( id );
     455                return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id );
    338456        }
    339457
    340458        StructDecl *Indexer::lookupStruct( const std::string &id ) const {
    341                 return structTable.lookup( id );
     459                if ( ! tables ) return 0;
     460
     461                StructTable::const_iterator ret = tables->structTable.find( id );
     462                return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id );
    342463        }
    343464
    344465        EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
    345                 return enumTable.lookup( id );
     466                if ( ! tables ) return 0;
     467
     468                EnumTable::const_iterator ret = tables->enumTable.find( id );
     469                return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id );
    346470        }
    347471
    348472        UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
    349                 return unionTable.lookup( id );
    350         }
    351 
    352         TraitDecl  * Indexer::lookupTrait( const std::string &id ) const {
    353                 return contextTable.lookup( id );
     473                if ( ! tables ) return 0;
     474
     475                UnionTable::const_iterator ret = tables->unionTable.find( id );
     476                return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id );
     477        }
     478
     479        TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
     480                if ( ! tables ) return 0;
     481
     482                TraitTable::const_iterator ret = tables->traitTable.find( id );
     483                return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id );
     484        }
     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       
     514        NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const {
     515                if ( ! tables ) return 0;
     516                if ( tables->scope < scope ) return 0;
     517
     518                TypeTable::const_iterator ret = tables->typeTable.find( id );
     519                return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope );
     520        }
     521       
     522        StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const {
     523                if ( ! tables ) return 0;
     524                if ( tables->scope < scope ) return 0;
     525
     526                StructTable::const_iterator ret = tables->structTable.find( id );
     527                return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope );
     528        }
     529       
     530        EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const {
     531                if ( ! tables ) return 0;
     532                if ( tables->scope < scope ) return 0;
     533
     534                EnumTable::const_iterator ret = tables->enumTable.find( id );
     535                return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope );
     536        }
     537       
     538        UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const {
     539                if ( ! tables ) return 0;
     540                if ( tables->scope < scope ) return 0;
     541
     542                UnionTable::const_iterator ret = tables->unionTable.find( id );
     543                return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope );
     544        }
     545       
     546        TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const {
     547                if ( ! tables ) return 0;
     548                if ( tables->scope < scope ) return 0;
     549
     550                TraitTable::const_iterator ret = tables->traitTable.find( id );
     551                return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope );
     552        }
     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       
     589        void Indexer::addId( DeclarationWithType *decl ) {
     590                makeWritable();
     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                }
     614        }
     615
     616        bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
     617                if ( existing->get_base() == 0 ) {
     618                        return false;
     619                } else if ( added->get_base() == 0 ) {
     620                        return true;
     621                } else {
     622                        throw SemanticError( "redeclaration of ", added );
     623                }
     624        }
     625       
     626        void Indexer::addType( NamedTypeDecl *decl ) {
     627                makeWritable();
     628
     629                const std::string &id = decl->get_name();
     630                TypeTable::iterator existing = tables->typeTable.find( id );
     631                if ( existing == tables->typeTable.end() ) {
     632                        NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope );
     633                        if ( ! parent || ! addedTypeConflicts( parent, decl ) ) {
     634                                tables->typeTable.insert( existing, std::make_pair( id, decl ) );
     635                                ++tables->size;
     636                        }
     637                } else {
     638                        if ( ! addedTypeConflicts( existing->second, decl ) ) {
     639                                existing->second = decl;
     640                        }
     641                }
     642        }
     643
     644        bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) {
     645                if ( existing->get_members().empty() ) {
     646                        return false;
     647                } else if ( ! added->get_members().empty() ) {
     648                        throw SemanticError( "redeclaration of ", added );
     649                } // if
     650                return true;
     651        }
     652
     653        void Indexer::addStruct( const std::string &id ) {
     654                addStruct( new StructDecl( id ) );
     655        }
     656       
     657        void Indexer::addStruct( StructDecl *decl ) {
     658                makeWritable();
     659
     660                const std::string &id = decl->get_name();
     661                StructTable::iterator existing = tables->structTable.find( id );
     662                if ( existing == tables->structTable.end() ) {
     663                        StructDecl *parent = tables->base.lookupStructAtScope( id, scope );
     664                        if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
     665                                tables->structTable.insert( existing, std::make_pair( id, decl ) );
     666                                ++tables->size;
     667                        }
     668                } else {
     669                        if ( ! addedDeclConflicts( existing->second, decl ) ) {
     670                                existing->second = decl;
     671                        }
     672                }
     673        }
     674       
     675        void Indexer::addEnum( EnumDecl *decl ) {
     676                makeWritable();
     677
     678                const std::string &id = decl->get_name();
     679                EnumTable::iterator existing = tables->enumTable.find( id );
     680                if ( existing == tables->enumTable.end() ) {
     681                        EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope );
     682                        if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
     683                                tables->enumTable.insert( existing, std::make_pair( id, decl ) );
     684                                ++tables->size;
     685                        }
     686                } else {
     687                        if ( ! addedDeclConflicts( existing->second, decl ) ) {
     688                                existing->second = decl;
     689                        }
     690                }
     691        }
     692
     693        void Indexer::addUnion( const std::string &id ) {
     694                addUnion( new UnionDecl( id ) );
     695        }
     696       
     697        void Indexer::addUnion( UnionDecl *decl ) {
     698                makeWritable();
     699
     700                const std::string &id = decl->get_name();
     701                UnionTable::iterator existing = tables->unionTable.find( id );
     702                if ( existing == tables->unionTable.end() ) {
     703                        UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope );
     704                        if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
     705                                tables->unionTable.insert( existing, std::make_pair( id, decl ) );
     706                                ++tables->size;
     707                        }
     708                } else {
     709                        if ( ! addedDeclConflicts( existing->second, decl ) ) {
     710                                existing->second = decl;
     711                        }
     712                }
     713        }
     714       
     715        void Indexer::addTrait( TraitDecl *decl ) {
     716                makeWritable();
     717
     718                const std::string &id = decl->get_name();
     719                TraitTable::iterator existing = tables->traitTable.find( id );
     720                if ( existing == tables->traitTable.end() ) {
     721                        TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope );
     722                        if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
     723                                tables->traitTable.insert( existing, std::make_pair( id, decl ) );
     724                                ++tables->size;
     725                        }
     726                } else {
     727                        if ( ! addedDeclConflicts( existing->second, decl ) ) {
     728                                existing->second = decl;
     729                        }
     730                }
    354731        }
    355732
    356733        void Indexer::enterScope() {
     734                ++scope;
     735               
    357736                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();
     737                        std::cout << "--- Entering scope " << scope << std::endl;
     738                }
    366739        }
    367740
    368741        void Indexer::leaveScope() {
    369742                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();
     743
     744                assert( scope > 0 && "cannot leave initial scope" );
     745                --scope;
     746
     747                while ( tables && tables->scope > scope ) {
     748                        if ( doDebug ) {
     749                                cout << "--- Leaving scope " << tables->scope << " containing" << std::endl;
     750                                dump( tables->idTable, cout );
     751                                dump( tables->typeTable, cout );
     752                                dump( tables->structTable, cout );
     753                                dump( tables->enumTable, cout );
     754                                dump( tables->unionTable, cout );
     755                                dump( tables->traitTable, cout );
     756                        }
     757
     758                        // swap tables for base table until we find one at an appropriate scope
     759                        Indexer::Impl *base = newRef( tables->base.tables );
     760                        deleteRef( tables );
     761                        tables = base;
     762                }
    387763        }
    388764
    389765        void Indexer::print( std::ostream &os, int indent ) const {
    390766            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
     767
     768            cerr << "===idTable===" << std::endl;
     769            if ( tables ) dump( tables->idTable, os );
     770            cerr << "===typeTable===" << std::endl;
     771            if ( tables ) dump( tables->typeTable, os );
     772            cerr << "===structTable===" << std::endl;
     773            if ( tables ) dump( tables->structTable, os );
     774            cerr << "===enumTable===" << std::endl;
     775            if ( tables ) dump( tables->enumTable, os );
     776            cerr << "===unionTable===" << std::endl;
     777            if ( tables ) dump( tables->unionTable, os );
     778            cerr << "===contextTable===" << std::endl;
     779            if ( tables ) dump( tables->traitTable, os );
    413780        }
    414781} // namespace SymTab
  • src/SymTab/Indexer.h

    rb63e376 rae357ec  
    2121
    2222#include "SynTree/Visitor.h"
    23 #include "IdTable.h"
    24 #include "AggregateTable.h"
    25 #include "TypeTable.h"
    2623
    2724namespace SymTab {
     
    2926          public:
    3027                Indexer( bool useDebug = false );
     28
     29                Indexer( const Indexer &that );
     30                Indexer( Indexer &&that );
    3131                virtual ~Indexer();
     32                Indexer& operator= ( const Indexer &that );
     33                Indexer& operator= ( Indexer &&that );
    3234
    3335                //using Visitor::visit;
     
    7880                void leaveScope();
    7981
    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
    8285                NamedTypeDecl *lookupType( const std::string &id ) const;
     86                /// Gets the top-most struct declaration with the given ID
    8387                StructDecl *lookupStruct( const std::string &id ) const;
     88                /// Gets the top-most enum declaration with the given ID
    8489                EnumDecl *lookupEnum( const std::string &id ) const;
     90                /// Gets the top-most union declaration with the given ID
    8591                UnionDecl *lookupUnion( const std::string &id ) const;
     92                /// Gets the top-most trait declaration with the given ID
    8693                TraitDecl *lookupTrait( const std::string &id ) const;
    8794 
    8895                void print( std::ostream &os, int indent = 0 ) const;
    8996          private:
    90                 IdTable idTable;
    91                 TypeTable typeTable;
    92                 StructTable structTable;
    93                 EnumTable enumTable;
    94                 UnionTable unionTable;
    95                 TraitTable 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
     100                bool hasCDeclWithName( const std::string &id ) 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();
    98129        };
    99130} // namespace SymTab
  • src/SymTab/module.mk

    rb63e376 rae357ec  
    1515###############################################################################
    1616
    17 SRC += SymTab/IdTable.cc \
    18        SymTab/Indexer.cc \
     17SRC += SymTab/Indexer.cc \
    1918       SymTab/Mangler.cc \
    2019       SymTab/Validate.cc \
Note: See TracChangeset for help on using the changeset viewer.