Changeset 52c2a72


Ignore:
Timestamp:
Mar 8, 2016, 4:28:40 PM (6 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, string, with_gc
Children:
bed4c63e
Parents:
e8032b0
Message:

Fold StackTable? variants into indexer

Location:
src/SymTab
Files:
4 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    re8032b0 r52c2a72  
    1616#include "Indexer.h"
    1717
     18#include <string>
     19#include <typeinfo>
     20#include <unordered_map>
     21#include <utility>
     22
    1823#include "IdTable.h"
    19 #include "AggregateTable.h"
    20 #include "TypeTable.h"
    2124
    2225#include "SynTree/Declaration.h"
     
    2629#include "SynTree/Statement.h"
    2730
    28 #include <typeinfo>
    29 #include <utility>
    3031#include "Common/utility.h"
    3132
     
    4041        }
    4142
     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       
    4256        struct Indexer::Impl {
    43                 Impl() : refCount(1), size(0), base(),
     57                Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(),
    4458                                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 ),
    4660                                idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
    4761                unsigned long refCount;   ///< Number of references to these tables
     62                unsigned long scope;      ///< Scope these tables are associated with
    4863                unsigned long size;       ///< Number of elements stored in this table
    4964                const Indexer base;       ///< Base indexer this extends
     
    7590        void Indexer::makeWritable() {
    7691                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 indexer
    80                         // this is basically equivalent to std::move( *this ) as the argument
    81                         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 ) {
    90105                that.tables = 0;
    91106        }
     
    99114
    100115                tables = newRef( that.tables );
     116                scope = that.scope;
    101117                doDebug = that.doDebug;
    102118
     
    108124
    109125                tables = that.tables;
     126                scope = that.scope;
    110127                doDebug = that.doDebug;
    111128
     
    421438                if ( ! tables ) return 0;
    422439
    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 );
    425442        }
    426443
     
    428445                if ( ! tables ) return 0;
    429446
    430                 StructDecl *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 );
    432449        }
    433450
     
    435452                if ( ! tables ) return 0;
    436453
    437                 EnumDecl *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 );
    439456        }
    440457
     
    442459                if ( ! tables ) return 0;
    443460
    444                 UnionDecl *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 );
    446463        }
    447464
     
    449466                if ( ! tables ) return 0;
    450467
    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 );
    453510        }
    454511
     
    458515                ++tables->size;
    459516        }
     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        }
    460527       
    461528        void Indexer::addType( NamedTypeDecl *decl ) {
    462529                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;
    465553        }
    466554
    467555        void Indexer::addStruct( const std::string &id ) {
    468                 makeWritable();
    469                 tables->structTable.add( id );
    470                 ++tables->size;
     556                addStruct( new StructDecl( id ) );
    471557        }
    472558       
    473559        void Indexer::addStruct( StructDecl *decl ) {
    474560                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                }
    477575        }
    478576       
    479577        void Indexer::addEnum( EnumDecl *decl ) {
    480578                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                }
    483593        }
    484594
    485595        void Indexer::addUnion( const std::string &id ) {
    486                 makeWritable();
    487                 tables->unionTable.add( id );
    488                 ++tables->size;
     596                addUnion( new UnionDecl( id ) );
    489597        }
    490598       
    491599        void Indexer::addUnion( UnionDecl *decl ) {
    492600                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                }
    495615        }
    496616       
    497617        void Indexer::addTrait( TraitDecl *decl ) {
    498618                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                }
    501633        }
    502634
    503635        void Indexer::enterScope() {
    504                 makeWritable();
     636                ++scope;
    505637               
    506638                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                }
    516641        }
    517642
    518643        void Indexer::leaveScope() {
    519644                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                }
    538665        }
    539666
     
    544671            if ( tables ) tables->idTable.dump( os );
    545672            cerr << "===typeTable===" << std::endl;
    546             if ( tables ) tables->typeTable.dump( os );
     673            if ( tables ) dump( tables->typeTable, os );
    547674            cerr << "===structTable===" << std::endl;
    548             if ( tables ) tables->structTable.dump( os );
     675            if ( tables ) dump( tables->structTable, os );
    549676            cerr << "===enumTable===" << std::endl;
    550             if ( tables ) tables->enumTable.dump( os );
     677            if ( tables ) dump( tables->enumTable, os );
    551678            cerr << "===unionTable===" << std::endl;
    552             if ( tables ) tables->unionTable.dump( os );
     679            if ( tables ) dump( tables->unionTable, os );
    553680            cerr << "===contextTable===" << std::endl;
    554             if ( tables ) tables->traitTable.dump( os );
     681            if ( tables ) dump( tables->traitTable, os );
    555682        }
    556683} // namespace SymTab
  • src/SymTab/Indexer.h

    re8032b0 r52c2a72  
    9090                void print( std::ostream &os, int indent = 0 ) const;
    9191          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               
    9299                void addId( DeclarationWithType *decl );
    93100                void addType( NamedTypeDecl *decl );
     
    100107               
    101108                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?
    106112
    107113                /// Takes a new ref to a table (returns null if null)
     
    110116                static void deleteRef( Impl *toFree );
    111117
    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)
    113119                void makeWritable();
    114120        };
Note: See TracChangeset for help on using the changeset viewer.