Changeset a5a71d0 for src/SymTab


Ignore:
Timestamp:
Apr 6, 2016, 5:11:32 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
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.
Message:

Merge branch 'fix-memory-error' into ctor

Conflicts:

src/CodeGen/CodeGenerator.cc
src/Makefile.in
src/Parser/DeclarationNode.cc
src/Parser/ParseNode.h
src/Parser/TypeData.cc
src/Parser/parser.cc
src/Parser/parser.yy
src/ResolvExpr/Resolver.cc
src/SymTab/Validate.cc
src/SynTree/Declaration.h
src/SynTree/Mutator.cc
src/SynTree/Mutator.h
src/SynTree/SynTree.h
src/SynTree/Visitor.cc
src/SynTree/Visitor.h
src/libcfa/prelude.cf

Location:
src/SymTab
Files:
6 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r39786813 ra5a71d0  
    1010// Created On       : Thu Mar 03 15:45:56 2016
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Thu Mar 03 15:45:56 2016
     12// Last Modified On : Mon Apr 04 17:19:28 2016
    1313// Update Count     : 1
    1414//
     
    3434                virtual void visit( UnionDecl *structDecl );
    3535                virtual void visit( TypeDecl *typeDecl );
    36                 virtual void visit( ContextDecl *ctxDecl );
     36                virtual void visit( TraitDecl *ctxDecl );
    3737                virtual void visit( FunctionDecl *functionDecl );
    3838
     
    468468        }
    469469
    470         void AutogenerateRoutines::visit( ContextDecl *) {
    471                 // ensure that we don't add assignment ops for types defined as part of the context
     470        void AutogenerateRoutines::visit( TraitDecl *) {
     471                // ensure that we don't add assignment ops for types defined as part of the trait
    472472        }
    473473
  • src/SymTab/FixFunction.cc

    r39786813 ra5a71d0  
    1010// Created On       : Sun May 17 16:19:49 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 16:22:54 2015
    13 // Update Count     : 2
     12// Last Modified On : Wed Mar  2 17:31:10 2016
     13// Update Count     : 3
    1414//
    1515
     
    6161        }
    6262
    63         Type * FixFunction::mutate(ContextInstType *aggregateUseType) {
     63        Type * FixFunction::mutate(TraitInstType *aggregateUseType) {
    6464                return aggregateUseType;
    6565        }
  • src/SymTab/FixFunction.h

    r39786813 ra5a71d0  
    1010// Created On       : Sun May 17 17:02:08 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 17:03:43 2015
    13 // Update Count     : 2
     12// Last Modified On : Wed Mar  2 17:34:06 2016
     13// Update Count     : 3
    1414//
    1515
     
    3838                virtual Type* mutate(UnionInstType *aggregateUseType);
    3939                virtual Type* mutate(EnumInstType *aggregateUseType);
    40                 virtual Type* mutate(ContextInstType *aggregateUseType);
     40                virtual Type* mutate(TraitInstType *aggregateUseType);
    4141                virtual Type* mutate(TypeInstType *aggregateUseType);
    4242                virtual Type* mutate(TupleType *tupleType);
  • src/SymTab/ImplementationType.cc

    r39786813 ra5a71d0  
    1010// Created On       : Sun May 17 21:32:01 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 21:34:40 2015
    13 // Update Count     : 2
     12// Last Modified On : Wed Mar  2 17:31:20 2016
     13// Update Count     : 3
    1414//
    1515
     
    3737                virtual void visit(UnionInstType *aggregateUseType);
    3838                virtual void visit(EnumInstType *aggregateUseType);
    39                 virtual void visit(ContextInstType *aggregateUseType);
     39                virtual void visit(TraitInstType *aggregateUseType);
    4040                virtual void visit(TypeInstType *aggregateUseType);
    4141                virtual void visit(TupleType *tupleType);
     
    9696        }
    9797
    98         void ImplementationType::visit(ContextInstType *aggregateUseType) {
     98        void ImplementationType::visit(TraitInstType *aggregateUseType) {
    9999        }
    100100
  • src/SymTab/Indexer.cc

    r39786813 ra5a71d0  
    99// Author           : Richard C. Bilson
    1010// 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"
    1529
    1630#include "SynTree/Declaration.h"
     
    1933#include "SynTree/Initializer.h"
    2034#include "SynTree/Statement.h"
    21 #include "Indexer.h"
    22 #include <typeinfo>
    23 #include "Common/utility.h"
    2435
    2536#define debugPrint(x) if ( doDebug ) { std::cout << x; }
     
    3344        }
    3445
    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        }
    38146
    39147        void Indexer::visit( ObjectDecl *objectDecl ) {
     
    45153                if ( objectDecl->get_name() != "" ) {
    46154                        debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
    47                         idTable.addDecl( objectDecl );
     155                        addId( objectDecl );
    48156                } // if
    49157        }
     
    52160                if ( functionDecl->get_name() == "" ) return;
    53161                debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
    54                 idTable.addDecl( functionDecl );
     162                addId( functionDecl );
    55163                enterScope();
    56164                maybeAccept( functionDecl->get_functionType(), *this );
     
    90198                leaveScope();
    91199                debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
    92                 typeTable.add( typeDecl );
     200                addType( typeDecl );
    93201                acceptAll( typeDecl->get_assertions(), *this );
    94202        }
     
    100208                leaveScope();
    101209                debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
    102                 typeTable.add( typeDecl );
     210                addType( typeDecl );
    103211        }
    104212
     
    108216                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
    109217                debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
    110                 structTable.add( &fwdDecl );
     218                addStruct( &fwdDecl );
    111219 
    112220                enterScope();
     
    117225                debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
    118226                // this addition replaces the forward declaration
    119                 structTable.add( aggregateDecl );
     227                addStruct( aggregateDecl );
    120228        }
    121229
     
    125233                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
    126234                debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
    127                 unionTable.add( &fwdDecl );
     235                addUnion( &fwdDecl );
    128236 
    129237                enterScope();
     
    133241 
    134242                debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
    135                 unionTable.add( aggregateDecl );
     243                addUnion( aggregateDecl );
    136244        }
    137245
    138246        void Indexer::visit( EnumDecl *aggregateDecl ) {
    139247                debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
    140                 enumTable.add( aggregateDecl );
     248                addEnum( aggregateDecl );
    141249                // unlike structs, contexts, and unions, enums inject their members into the global scope
    142250                acceptAll( aggregateDecl->get_members(), *this );
    143251        }
    144252
    145         void Indexer::visit( ContextDecl *aggregateDecl ) {
     253        void Indexer::visit( TraitDecl *aggregateDecl ) {
    146254                enterScope();
    147255                acceptAll( aggregateDecl->get_parameters(), *this );
     
    150258 
    151259                debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
    152                 contextTable.add( aggregateDecl );
     260                addTrait( aggregateDecl );
    153261        }
    154262
     
    293401
    294402
    295         void Indexer::visit( ContextInstType *contextInst ) {
     403        void Indexer::visit( TraitInstType *contextInst ) {
    296404                acceptAll( contextInst->get_parameters(), *this );
    297405                acceptAll( contextInst->get_members(), *this );
     
    299407
    300408        void Indexer::visit( StructInstType *structInst ) {
    301                 if ( ! structTable.lookup( structInst->get_name() ) ) {
     409                if ( ! lookupStruct( structInst->get_name() ) ) {
    302410                        debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
    303                         structTable.add( structInst->get_name() );
     411                        addStruct( structInst->get_name() );
    304412                }
    305413                enterScope();
     
    309417
    310418        void Indexer::visit( UnionInstType *unionInst ) {
    311                 if ( ! unionTable.lookup( unionInst->get_name() ) ) {
     419                if ( ! lookupUnion( unionInst->get_name() ) ) {
    312420                        debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
    313                         unionTable.add( unionInst->get_name() );
     421                        addUnion( unionInst->get_name() );
    314422                }
    315423                enterScope();
     
    325433        }
    326434
    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                }
    334457        }
    335458
    336459        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 );
    338464        }
    339465
    340466        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 );
    342471        }
    343472
    344473        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 );
    346478        }
    347479
    348480        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                }
    354743        }
    355744
    356745        void Indexer::enterScope() {
     746                ++scope;
     747               
    357748                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                }
    366751        }
    367752
    368753        void Indexer::leaveScope() {
    369754                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                }
    387775        }
    388776
    389777        void Indexer::print( std::ostream &os, int indent ) const {
    390778            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 );
    413792        }
    414793} // namespace SymTab
  • src/SymTab/Indexer.h

    r39786813 ra5a71d0  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:38:55 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Thu Sep 17 16:05:38 2015
    13 // Update Count     : 5
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Mar  2 17:34:14 2016
     13// Update Count     : 6
    1414//
    1515
     
    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;
     
    3941                virtual void visit( UnionDecl *aggregateDecl );
    4042                virtual void visit( EnumDecl *aggregateDecl );
    41                 virtual void visit( ContextDecl *aggregateDecl );
     43                virtual void visit( TraitDecl *aggregateDecl );
    4244
    4345                virtual void visit( CompoundStmt *compoundStmt );
     
    6769                virtual void visit( UntypedValofExpr *valofExpr );
    6870
    69                 virtual void visit( ContextInstType *contextInst );
     71                virtual void visit( TraitInstType *contextInst );
    7072                virtual void visit( StructInstType *contextInst );
    7173                virtual void visit( UnionInstType *contextInst );
     
    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;
    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;
    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                 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();
    98129        };
    99130} // namespace SymTab
  • src/SymTab/Mangler.cc

    r39786813 ra5a71d0  
    227227
    228228        void Mangler::visit( VarArgsType *varArgsType ) {
     229                printQualifiers( varArgsType );
    229230                mangleName << "VARGS";
    230231        }
  • src/SymTab/TypeEquality.cc

    r39786813 ra5a71d0  
    194194
    195195        void TypeEquality::visit( VarArgsType *varArgsType ) {
    196                 // don't handle qualifiers; var args pack shouldn't have any
     196                handleQualifiers( varArgsType );
    197197                if ( ! dynamic_cast< VarArgsType * >( other ) ) {
    198198                        result = false;
  • src/SymTab/Validate.cc

    r39786813 ra5a71d0  
    1010// Created On       : Sun May 17 21:50:04 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon Feb 22 12:26:37 2016
     12// Last Modified On : Mon Apr 04 17:13:29 2016
    1313// Update Count     : 297
    1414//
     
    102102                virtual void visit( StructInstType *structInst );
    103103                virtual void visit( UnionInstType *unionInst );
    104                 virtual void visit( ContextInstType *contextInst );
     104                virtual void visit( TraitInstType *contextInst );
    105105                virtual void visit( StructDecl *structDecl );
    106106                virtual void visit( UnionDecl *unionDecl );
     
    158158                virtual Declaration *mutate( UnionDecl * unionDecl );
    159159                virtual Declaration *mutate( EnumDecl * enumDecl );
    160                 virtual Declaration *mutate( ContextDecl * contextDecl );
     160                virtual Declaration *mutate( TraitDecl * contextDecl );
    161161
    162162                template<typename AggDecl>
     
    370370        }
    371371
    372         void Pass2::visit( ContextInstType *contextInst ) {
     372        void Pass2::visit( TraitInstType *contextInst ) {
    373373                Parent::visit( contextInst );
    374                 ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
     374                TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() );
    375375                if ( ! ctx ) {
    376376                        throw SemanticError( "use of undeclared context " + contextInst->get_name() );
     
    378378                for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
    379379                        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 ) ) {
    381381                                        cloneAll( otherCtx->get_members(), contextInst->get_members() );
    382382                                } else {
     
    442442                        while ( ! toBeDone.empty() ) {
    443443                                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() ) ) {
    445445                                                for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
    446446                                                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
     
    652652        }
    653653
    654                 Declaration *EliminateTypedef::mutate( ContextDecl * contextDecl ) {
     654                Declaration *EliminateTypedef::mutate( TraitDecl * contextDecl ) {
    655655                Mutator::mutate( contextDecl );
    656656                return handleAggregate( contextDecl );
  • src/SymTab/module.mk

    r39786813 ra5a71d0  
    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.