Changes in / [5f782f7:3e3d923]


Ignore:
Location:
src
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • src/Common/PassVisitor.impl.h

    r5f782f7 r3e3d923  
    183183
    184184                } catch ( SemanticError &e ) {
    185                         e.set_location( (*i)->location );
    186185                        errors.append( e );
    187186                }
     
    293292//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    294293
    295 // A NOTE ON THE ORDER OF TRAVERSAL
    296 //
    297 // Types and typedefs have their base types visited before they are added to the type table.  This is ok, since there is
    298 // no such thing as a recursive type or typedef.
    299 //
    300 //             typedef struct { T *x; } T; // never allowed
    301 //
    302 // for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
    303 // members are traversed, and then the complete type should be added (assuming the type is completed by this particular
    304 // declaration).
    305 //
    306 //             struct T { struct T *x; }; // allowed
    307 //
    308 // It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
    309 // traversal may modify the definition of the type and these modifications should be visible when the symbol table is
    310 // queried later in this pass.
    311 //
    312 // TODO: figure out whether recursive contexts are sensible/possible/reasonable.
    313294
    314295//--------------------------------------------------------------------------
     
    468449        indexerAddEnum( node );
    469450
    470         // unlike structs, traits, and unions, enums inject their members into the global scope
     451        // unlike structs, contexts, and unions, enums inject their members into the global scope
    471452        maybeAccept( node->parameters, *this );
    472453        maybeAccept( node->members   , *this );
     
    532513        }
    533514
    534         // see A NOTE ON THE ORDER OF TRAVERSAL, above
    535         // note that assertions come after the type is added to the symtab, since they are not part of the type proper
    536         // and may depend on the type itself
    537515        indexerAddType( node );
    538516
     
    554532        }
    555533
    556         // see A NOTE ON THE ORDER OF TRAVERSAL, above
    557         // note that assertions come after the type is added to the symtab, since they are not part of the type proper
    558         // and may depend on the type itself
    559534        indexerAddType( node );
    560535
     
    683658void PassVisitor< pass_type >::visit( IfStmt * node ) {
    684659        VISIT_START( node );
    685         {
    686                 // if statements introduce a level of scope (for the initialization)
     660
     661        visitExpression( node->condition );
     662        node->thenPart = visitStatement( node->thenPart );
     663        node->elsePart = visitStatement( node->elsePart );
     664
     665        VISIT_END( node );
     666}
     667
     668template< typename pass_type >
     669Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
     670        MUTATE_START( node );
     671        {
    687672                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    688                 acceptAll( node->get_initialization(), *this );
    689                 visitExpression( node->condition );
    690                 node->thenPart = visitStatement( node->thenPart );
    691                 node->elsePart = visitStatement( node->elsePart );
    692         }
    693         VISIT_END( node );
    694 }
    695 
    696 template< typename pass_type >
    697 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
    698         MUTATE_START( node );
    699         {
    700                 // if statements introduce a level of scope (for the initialization)
    701                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    702                 maybeMutateRef( node->get_initialization(), *this );
    703673                node->condition = mutateExpression( node->condition );
    704674                node->thenPart  = mutateStatement ( node->thenPart  );
     
    736706        VISIT_START( node );
    737707        {
    738                 // for statements introduce a level of scope (for the initialization)
    739708                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    740709                maybeAccept( node->initialization, *this );
     
    750719        MUTATE_START( node );
    751720        {
    752                 // for statements introduce a level of scope (for the initialization)
    753721                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    754722                maybeMutateRef( node->initialization, *this );
     
    879847        VISIT_START( node );
    880848        {
    881                 // catch statements introduce a level of scope (for the caught exception)
    882849                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    883850                maybeAccept( node->decl, *this );
     
    892859        MUTATE_START( node );
    893860        {
    894                 // catch statements introduce a level of scope (for the caught exception)
    895861                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    896862                maybeMutateRef( node->decl, *this );
  • src/GenPoly/Box.cc

    r5f782f7 r3e3d923  
    628628                                        } else {
    629629                                                // xxx - should this be an assertion?
    630                                                 throw SemanticError( toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ), appExpr );
     630                                                std::string x = env ? toString( *env ) : "missing env";
     631                                                throw SemanticError( x + "\n" + "unbound type variable: " + tyParm->first + " in application ", appExpr );
    631632                                        } // if
    632633                                } // if
     
    705706                                if ( concrete == 0 ) {
    706707                                        return typeInst;
     708                                        // xxx - should this be an assertion?
     709//                                      std::string x = env ? toString( *env ) : "missing env";
     710//                                      throw SemanticError( x + "\n" + "Unbound type variable " + typeInst->get_name() + " in ", appExpr );
    707711                                } // if
    708712                                return concrete;
  • src/InitTweak/FixInit.cc

    r5f782f7 r3e3d923  
    7070namespace InitTweak {
    7171        namespace {
     72                typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap;
    7273                typedef std::unordered_map< int, int > UnqCount;
    7374
    74                 struct InsertImplicitCalls : public WithTypeSubstitution {
     75                class InsertImplicitCalls : public WithTypeSubstitution {
     76                public:
    7577                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
    7678                        /// function calls need their parameters to be copy constructed
    77                         static void insert( std::list< Declaration * > & translationUnit );
     79                        static void insert( std::list< Declaration * > & translationUnit, EnvMap & envMap );
     80
     81                        InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {}
    7882
    7983                        Expression * postmutate( ApplicationExpr * appExpr );
     84                        void premutate( StmtExpr * stmtExpr );
     85
     86                        // collects environments for relevant nodes
     87                        EnvMap & envMap;
    8088                };
    8189
    82                 struct ResolveCopyCtors final : public WithIndexer, public WithShortCircuiting, public WithTypeSubstitution {
     90                class ResolveCopyCtors final : public SymTab::Indexer {
     91                public:
    8392                        /// generate temporary ObjectDecls for each argument and return value of each ImplicitCopyCtorExpr,
    8493                        /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both
    8594                        /// arguments and return value temporaries
    86                         static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount );
    87 
    88                         ResolveCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ) {}
    89 
    90                         void postvisit( ImplicitCopyCtorExpr * impCpCtorExpr );
    91                         void postvisit( StmtExpr * stmtExpr );
    92                         void previsit( UniqueExpr * unqExpr );
    93                         void postvisit( UniqueExpr * unqExpr );
     95                        static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount );
     96
     97                        typedef SymTab::Indexer Parent;
     98                        using Parent::visit;
     99
     100                        ResolveCopyCtors( const EnvMap & envMap, UnqCount & unqCount ) : envMap( envMap ), unqCount( unqCount ) {}
     101
     102                        virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
     103                        virtual void visit( UniqueExpr * unqExpr ) override;
     104                        virtual void visit( StmtExpr * stmtExpr ) override;
    94105
    95106                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
     
    100111                        void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    101112
     113                        TypeSubstitution * env;
     114                        const EnvMap & envMap;
    102115                        UnqCount & unqCount; // count the number of times each unique expr ID appears
    103                         std::unordered_set< int > vars;
    104116                };
    105117
     
    226238                };
    227239
    228                 struct GenStructMemberCalls final : public WithGuards, public WithShortCircuiting, public WithIndexer {
     240                class GenStructMemberCalls final : public SymTab::Indexer {
     241                  public:
     242                        typedef Indexer Parent;
    229243                        /// generate default/copy ctor and dtor calls for user-defined struct ctor/dtors
    230244                        /// for any member that is missing a corresponding ctor/dtor call.
     
    232246                        static void generate( std::list< Declaration * > & translationUnit );
    233247
    234                         void previsit( FunctionDecl * funcDecl );
    235                         void postvisit( FunctionDecl * funcDecl );
    236 
    237                         void previsit( MemberExpr * memberExpr );
    238                         void previsit( ApplicationExpr * appExpr );
     248                        using Parent::visit;
     249
     250                        virtual void visit( FunctionDecl * funcDecl ) override;
     251
     252                        virtual void visit( MemberExpr * memberExpr ) override;
     253                        virtual void visit( ApplicationExpr * appExpr ) override;
    239254
    240255                        SemanticError errors;
     
    280295                InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
    281296
     297                EnvMap envMap;
    282298                UnqCount unqCount;
    283299
    284                 InsertImplicitCalls::insert( translationUnit );
    285                 ResolveCopyCtors::resolveImplicitCalls( translationUnit, unqCount );
     300                InsertImplicitCalls::insert( translationUnit, envMap );
     301                ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap, unqCount );
    286302                InsertDtors::insert( translationUnit );
    287303                FixInit::fixInitializers( translationUnit );
     
    302318
    303319        namespace {
    304                 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) {
    305                         PassVisitor<InsertImplicitCalls> inserter;
     320                void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) {
     321                        PassVisitor<InsertImplicitCalls> inserter( envMap );
    306322                        mutateAll( translationUnit, inserter );
    307323                }
    308324
    309                 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
    310                         PassVisitor<ResolveCopyCtors> resolver( unqCount );
     325                void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount ) {
     326                        ResolveCopyCtors resolver( envMap, unqCount );
    311327                        acceptAll( translationUnit, resolver );
    312328                }
     
    344360
    345361                void GenStructMemberCalls::generate( std::list< Declaration * > & translationUnit ) {
    346                         PassVisitor<GenStructMemberCalls> warner;
     362                        GenStructMemberCalls warner;
    347363                        acceptAll( translationUnit, warner );
    348364                }
     
    382398                        // wrap each function call so that it is easy to identify nodes that have to be copy constructed
    383399                        ImplicitCopyCtorExpr * expr = new ImplicitCopyCtorExpr( appExpr );
    384                         // Move the type substitution to the new top-level, if it is attached to the appExpr.
     400                        // save the type substitution into the envMap so that it is easy to find.
    385401                        // Ensure it is not deleted with the ImplicitCopyCtorExpr by removing it before deletion.
    386402                        // The substitution is needed to obtain the type of temporary variables so that copy constructor
    387                         // calls can be resolved.
     403                        // calls can be resolved. Normally this is what PolyMutator is for, but the pass that resolves
     404                        // copy constructor calls must be an Indexer. We could alternatively make a PolyIndexer which
     405                        // saves the environment, or compute the types of temporaries here, but it's much simpler to
     406                        // save the environment here, and more cohesive to compute temporary variables and resolve copy
     407                        // constructor calls together.
    388408                        assert( env );
    389                         std::swap( expr->env, appExpr->env );
     409                        envMap[expr] = env;
    390410                        return expr;
     411                }
     412
     413                void InsertImplicitCalls::premutate( StmtExpr * stmtExpr ) {
     414                        assert( env );
     415                        envMap[stmtExpr] = env;
    391416                }
    392417
     
    406431                        // (VariableExpr and already resolved expression)
    407432                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    408                         Expression * resolved = ResolvExpr::findVoidExpression( untyped, indexer );
     433                        Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this );
    409434                        assert( resolved );
    410435                        if ( resolved->get_env() ) {
     
    455480                }
    456481
    457                 void ResolveCopyCtors::postvisit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     482                void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    458483                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
     484                        Parent::visit( impCpCtorExpr );
     485                        env = envMap.at(impCpCtorExpr);
     486                        assert( env );
    459487
    460488                        ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
     
    485513                }
    486514
    487                 void ResolveCopyCtors::postvisit( StmtExpr * stmtExpr ) {
    488                         assert( env );
     515                void ResolveCopyCtors::visit( StmtExpr * stmtExpr ) {
     516                        Parent::visit( stmtExpr );
     517                        env = envMap.at(stmtExpr);
    489518                        assert( stmtExpr->get_result() );
    490519                        Type * result = stmtExpr->get_result();
     
    508537                                stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    509538                        } // if
    510                 }
    511 
    512                 void ResolveCopyCtors::previsit( UniqueExpr * unqExpr ) {
     539
     540                }
     541
     542                void ResolveCopyCtors::visit( UniqueExpr * unqExpr ) {
     543                        static std::unordered_set< int > vars;
    513544                        unqCount[ unqExpr->get_id() ]++;  // count the number of unique expressions for each ID
    514545                        if ( vars.count( unqExpr->get_id() ) ) {
    515546                                // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
    516                                 visit_children = false;
    517                         }
    518                 }
    519 
    520                 void ResolveCopyCtors::postvisit( UniqueExpr * unqExpr ) {
    521                         if ( vars.count( unqExpr->get_id() ) ) {
    522                                 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
    523547                                return;
    524548                        }
    525549
     550                        Parent::visit( unqExpr );
    526551                        // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought
    527552                        assert( unqExpr->get_result() );
     
    560585
    561586                        // xxx - update to work with multiple return values
    562                         ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front();
     587                        ObjectDecl * returnDecl = returnDecls.empty() ? NULL : returnDecls.front();
    563588                        Expression * callExpr = impCpCtorExpr->get_callExpr();
    564589
     
    569594                        tempDecls.clear();
    570595                        returnDecls.clear();
    571                         impCpCtorExpr->set_callExpr( nullptr );
    572                         std::swap( impCpCtorExpr->env, callExpr->env );
    573                         assert( impCpCtorExpr->env == nullptr );
     596                        impCpCtorExpr->set_callExpr( NULL );
     597                        impCpCtorExpr->set_env( NULL );
    574598                        delete impCpCtorExpr;
    575599
     
    954978                }
    955979
    956                 void GenStructMemberCalls::previsit( FunctionDecl * funcDecl ) {
    957                         GuardValue( funcDecl );
    958                         GuardValue( unhandled );
    959                         GuardValue( usedUninit );
    960                         GuardValue( thisParam );
    961                         GuardValue( isCtor );
    962                         GuardValue( structDecl );
     980                void GenStructMemberCalls::visit( FunctionDecl * funcDecl ) {
     981                        ValueGuard< FunctionDecl * > oldFunction( funcDecl );
     982                        ValueGuard< std::set< DeclarationWithType * > > oldUnhandled( unhandled );
     983                        ValueGuard< std::map< DeclarationWithType *, CodeLocation > > oldUsedUninit( usedUninit );
     984                        ValueGuard< ObjectDecl * > oldThisParam( thisParam );
     985                        ValueGuard< bool > oldIsCtor( isCtor );
     986                        ValueGuard< StructDecl * > oldStructDecl( structDecl );
    963987                        errors = SemanticError();  // clear previous errors
    964988
     
    9861010                                }
    9871011                        }
    988                 }
    989 
    990                 void addIds( SymTab::Indexer & indexer, const std::list< DeclarationWithType * > & decls ) {
    991                         for ( auto d : decls ) {
    992                                 indexer.addId( d );
    993                         }
    994                 }
    995 
    996                 void addTypes( SymTab::Indexer & indexer, const std::list< TypeDecl * > & tds ) {
    997                         for ( auto td : tds ) {
    998                                 indexer.addType( td );
    999                                 addIds( indexer, td->assertions );
    1000                         }
    1001                 }
    1002 
    1003                 void GenStructMemberCalls::postvisit( FunctionDecl * funcDecl ) {
     1012                        Parent::visit( function );
     1013
    10041014                        // remove the unhandled objects from usedUninit, because a call is inserted
    10051015                        // to handle them - only objects that are later constructed are used uninitialized.
     
    10221032                        if ( ! unhandled.empty() ) {
    10231033                                // need to explicitly re-add function parameters to the indexer in order to resolve copy constructors
    1024                                 auto guard = makeFuncGuard( [this]() { indexer.enterScope(); }, [this]() { indexer.leaveScope(); } );
    1025                                 addTypes( indexer, function->type->forall );
    1026                                 addIds( indexer, function->type->returnVals );
    1027                                 addIds( indexer, function->type->parameters );
     1034                                enterScope();
     1035                                maybeAccept( function->get_functionType(), *this );
    10281036
    10291037                                // need to iterate through members in reverse in order for
     
    10551063                                                Statement * callStmt = stmt.front();
    10561064
    1057                                                 MutatingResolver resolver( indexer );
     1065                                                MutatingResolver resolver( *this );
    10581066                                                try {
    10591067                                                        callStmt->acceptMutator( resolver );
     
    10691077                                        }
    10701078                                }
     1079                                leaveScope();
    10711080                        }
    10721081                        if (! errors.isEmpty()) {
     
    10981107                }
    10991108
    1100                 void GenStructMemberCalls::previsit( ApplicationExpr * appExpr ) {
    1101                         if ( ! checkWarnings( function ) ) {
    1102                                 visit_children = false;
    1103                                 return;
    1104                         }
     1109                void GenStructMemberCalls::visit( ApplicationExpr * appExpr ) {
     1110                        if ( ! checkWarnings( function ) ) return;
    11051111
    11061112                        std::string fname = getFunctionName( appExpr );
     
    11211127                                }
    11221128                        }
    1123                 }
    1124 
    1125                 void GenStructMemberCalls::previsit( MemberExpr * memberExpr ) {
    1126                         if ( ! checkWarnings( function ) || ! isCtor ) {
    1127                                 visit_children = false;
    1128                                 return;
    1129                         }
     1129                        Parent::visit( appExpr );
     1130                }
     1131
     1132                void GenStructMemberCalls::visit( MemberExpr * memberExpr ) {
     1133                        if ( ! checkWarnings( function ) ) return;
     1134                        if ( ! isCtor ) return;
    11301135
    11311136                        if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
     
    11351140                                }
    11361141                        }
     1142                        Parent::visit( memberExpr );
    11371143                }
    11381144
     
    11551161                        // in generated code. If this changes, add mutate methods for entities with
    11561162                        // scope and call {enter,leave}Scope explicitly.
    1157                         indexer.addId( objectDecl );
     1163                        objectDecl->accept( indexer );
    11581164                        return objectDecl;
    11591165                }
  • src/ResolvExpr/AlternativeFinder.cc

    r5f782f7 r3e3d923  
    523523                for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
    524524                        if ( i->second.isUsed ) {
    525                                 indexer.addId( i->first );
     525                                i->first->accept( indexer );
    526526                        }
    527527                }
  • src/ResolvExpr/AlternativePrinter.cc

    r5f782f7 r3e3d923  
    2626
    2727namespace ResolvExpr {
    28         AlternativePrinter::AlternativePrinter( std::ostream &os ) : os( os ) {}
     28        AlternativePrinter::AlternativePrinter( std::ostream &os ) : SymTab::Indexer( false ), os( os ) {}
    2929
    30         void AlternativePrinter::postvisit( ExprStmt *exprStmt ) {
     30        void AlternativePrinter::visit( ExprStmt *exprStmt ) {
    3131                TypeEnvironment env;
    32                 AlternativeFinder finder( indexer, env );
     32                AlternativeFinder finder( *this, env );
    3333                finder.findWithAdjustment( exprStmt->get_expr() );
    3434                int count = 1;
  • src/ResolvExpr/AlternativePrinter.h

    r5f782f7 r3e3d923  
    1818#include <iostream>          // for ostream
    1919
    20 #include "Common/PassVisitor.h"
     20#include "SymTab/Indexer.h"  // for Indexer
    2121
    2222class ExprStmt;
    2323
    2424namespace ResolvExpr {
    25         class AlternativePrinter final : public WithIndexer {
     25        class AlternativePrinter final : public SymTab::Indexer {
    2626          public:
    2727                AlternativePrinter( std::ostream &os );
    2828
    29                 void postvisit( ExprStmt *exprStmt );
     29                using SymTab::Indexer::visit;
     30                virtual void visit( ExprStmt *exprStmt ) override;
    3031          private:
    3132                std::ostream &os;
  • src/ResolvExpr/Resolver.cc

    r5f782f7 r3e3d923  
    2121#include "Alternative.h"                 // for Alternative, AltList
    2222#include "AlternativeFinder.h"           // for AlternativeFinder, resolveIn...
    23 #include "Common/PassVisitor.h"          // for PassVisitor
    2423#include "Common/SemanticError.h"        // for SemanticError
    2524#include "Common/utility.h"              // for ValueGuard, group_iterate
     
    4443
    4544namespace ResolvExpr {
    46         struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting {
    47                 Resolver() {}
    48                 Resolver( const SymTab::Indexer & other ) {
    49                         indexer = other;
    50                 }
    51 
    52                 void previsit( FunctionDecl *functionDecl );
    53                 void postvisit( FunctionDecl *functionDecl );
    54                 void previsit( ObjectDecl *functionDecl );
    55                 void previsit( TypeDecl *typeDecl );
    56                 void previsit( EnumDecl * enumDecl );
    57 
    58                 void previsit( ArrayType * at );
    59                 void previsit( PointerType * at );
    60 
    61                 void previsit( ExprStmt *exprStmt );
    62                 void previsit( AsmExpr *asmExpr );
    63                 void previsit( AsmStmt *asmStmt );
    64                 void previsit( IfStmt *ifStmt );
    65                 void previsit( WhileStmt *whileStmt );
    66                 void previsit( ForStmt *forStmt );
    67                 void previsit( SwitchStmt *switchStmt );
    68                 void previsit( CaseStmt *caseStmt );
    69                 void previsit( BranchStmt *branchStmt );
    70                 void previsit( ReturnStmt *returnStmt );
    71                 void previsit( ThrowStmt *throwStmt );
    72                 void previsit( CatchStmt *catchStmt );
    73 
    74                 void previsit( SingleInit *singleInit );
    75                 void previsit( ListInit *listInit );
    76                 void previsit( ConstructorInit *ctorInit );
     45        class Resolver final : public SymTab::Indexer {
     46          public:
     47                Resolver() : SymTab::Indexer( false ) {}
     48                Resolver( const SymTab:: Indexer & other ) : SymTab::Indexer( other ) {
     49                        if ( const Resolver * res = dynamic_cast< const Resolver * >( &other ) ) {
     50                                functionReturn = res->functionReturn;
     51                                currentObject = res->currentObject;
     52                                inEnumDecl = res->inEnumDecl;
     53                        }
     54                }
     55
     56                typedef SymTab::Indexer Parent;
     57                using Parent::visit;
     58                virtual void visit( FunctionDecl *functionDecl ) override;
     59                virtual void visit( ObjectDecl *functionDecl ) override;
     60                virtual void visit( TypeDecl *typeDecl ) override;
     61                virtual void visit( EnumDecl * enumDecl ) override;
     62
     63                virtual void visit( ArrayType * at ) override;
     64                virtual void visit( PointerType * at ) override;
     65
     66                virtual void visit( ExprStmt *exprStmt ) override;
     67                virtual void visit( AsmExpr *asmExpr ) override;
     68                virtual void visit( AsmStmt *asmStmt ) override;
     69                virtual void visit( IfStmt *ifStmt ) override;
     70                virtual void visit( WhileStmt *whileStmt ) override;
     71                virtual void visit( ForStmt *forStmt ) override;
     72                virtual void visit( SwitchStmt *switchStmt ) override;
     73                virtual void visit( CaseStmt *caseStmt ) override;
     74                virtual void visit( BranchStmt *branchStmt ) override;
     75                virtual void visit( ReturnStmt *returnStmt ) override;
     76                virtual void visit( ThrowStmt *throwStmt ) override;
     77                virtual void visit( CatchStmt *catchStmt ) override;
     78
     79                virtual void visit( SingleInit *singleInit ) override;
     80                virtual void visit( ListInit *listInit ) override;
     81                virtual void visit( ConstructorInit *ctorInit ) override;
    7782          private:
    7883        typedef std::list< Initializer * >::iterator InitIterator;
     
    9196
    9297        void resolve( std::list< Declaration * > translationUnit ) {
    93                 PassVisitor<Resolver> resolver;
     98                Resolver resolver;
    9499                acceptAll( translationUnit, resolver );
    95100        }
    96101
    97         // used in resolveTypeof
    98102        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
    99103                TypeEnvironment env;
    100104                return resolveInVoidContext( expr, indexer, env );
    101105        }
     106
    102107
    103108        namespace {
     
    185190        }
    186191
    187         void Resolver::previsit( ObjectDecl *objectDecl ) {
    188                 Type *new_type = resolveTypeof( objectDecl->get_type(), indexer );
     192        void Resolver::visit( ObjectDecl *objectDecl ) {
     193                Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
    189194                objectDecl->set_type( new_type );
    190195                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable
     
    193198                // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
    194199                // the RHS.
    195                 GuardValue( currentObject );
     200                ValueGuard<CurrentObject> temp( currentObject );
    196201                currentObject = CurrentObject( objectDecl->get_type() );
    197202                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
     
    200205                        currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    201206                }
     207                Parent::visit( objectDecl );
     208                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
     209                        // delete newly created signed int type
     210                        // delete currentObject.getType();
     211                }
    202212        }
    203213
     
    206216                if ( type->get_dimension() ) {
    207217                        CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() );
    208                         Expression *newExpr = findSingleExpression( castExpr, indexer );
     218                        Expression *newExpr = findSingleExpression( castExpr, *this );
    209219                        delete type->get_dimension();
    210220                        type->set_dimension( newExpr );
     
    212222        }
    213223
    214         void Resolver::previsit( ArrayType * at ) {
     224        void Resolver::visit( ArrayType * at ) {
    215225                handlePtrType( at );
    216         }
    217 
    218         void Resolver::previsit( PointerType * pt ) {
     226                Parent::visit( at );
     227        }
     228
     229        void Resolver::visit( PointerType * pt ) {
    219230                handlePtrType( pt );
    220         }
    221 
    222         void Resolver::previsit( TypeDecl *typeDecl ) {
     231                Parent::visit( pt );
     232        }
     233
     234        void Resolver::visit( TypeDecl *typeDecl ) {
    223235                if ( typeDecl->get_base() ) {
    224                         Type *new_type = resolveTypeof( typeDecl->get_base(), indexer );
     236                        Type *new_type = resolveTypeof( typeDecl->get_base(), *this );
    225237                        typeDecl->set_base( new_type );
    226238                } // if
    227         }
    228 
    229         void Resolver::previsit( FunctionDecl *functionDecl ) {
     239                Parent::visit( typeDecl );
     240        }
     241
     242        void Resolver::visit( FunctionDecl *functionDecl ) {
    230243#if 0
    231                 std::cerr << "resolver visiting functiondecl ";
    232                 functionDecl->print( std::cerr );
    233                 std::cerr << std::endl;
     244                std::cout << "resolver visiting functiondecl ";
     245                functionDecl->print( std::cout );
     246                std::cout << std::endl;
    234247#endif
    235                 Type *new_type = resolveTypeof( functionDecl->get_type(), indexer );
     248                Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
    236249                functionDecl->set_type( new_type );
    237                 GuardValue( functionReturn );
     250                ValueGuard< Type * > oldFunctionReturn( functionReturn );
    238251                functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
    239         }
    240 
    241 
    242         void Resolver::postvisit( FunctionDecl *functionDecl ) {
     252                Parent::visit( functionDecl );
     253
    243254                // default value expressions have an environment which shouldn't be there and trips up later passes.
    244255                // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently
     
    254265        }
    255266
    256         void Resolver::previsit( EnumDecl * ) {
     267        void Resolver::visit( EnumDecl * enumDecl ) {
    257268                // in case we decide to allow nested enums
    258                 GuardValue( inEnumDecl );
     269                ValueGuard< bool > oldInEnumDecl( inEnumDecl );
    259270                inEnumDecl = true;
    260         }
    261 
    262         void Resolver::previsit( ExprStmt *exprStmt ) {
    263                 visit_children = false;
     271                Parent::visit( enumDecl );
     272        }
     273
     274        void Resolver::visit( ExprStmt *exprStmt ) {
    264275                assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" );
    265                 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer );
     276                Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
    266277                delete exprStmt->get_expr();
    267278                exprStmt->set_expr( newExpr );
    268279        }
    269280
    270         void Resolver::previsit( AsmExpr *asmExpr ) {
    271                 visit_children = false;
    272                 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer );
     281        void Resolver::visit( AsmExpr *asmExpr ) {
     282                Expression *newExpr = findVoidExpression( asmExpr->get_operand(), *this );
    273283                delete asmExpr->get_operand();
    274284                asmExpr->set_operand( newExpr );
    275285                if ( asmExpr->get_inout() ) {
    276                         newExpr = findVoidExpression( asmExpr->get_inout(), indexer );
     286                        newExpr = findVoidExpression( asmExpr->get_inout(), *this );
    277287                        delete asmExpr->get_inout();
    278288                        asmExpr->set_inout( newExpr );
     
    280290        }
    281291
    282         void Resolver::previsit( AsmStmt *asmStmt ) {
    283                 visit_children = false;
    284                 acceptAll( asmStmt->get_input(), *visitor );
    285                 acceptAll( asmStmt->get_output(), *visitor );
    286         }
    287 
    288         void Resolver::previsit( IfStmt *ifStmt ) {
    289                 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), indexer );
     292        void Resolver::visit( AsmStmt *asmStmt ) {
     293                acceptAll( asmStmt->get_input(), *this);
     294                acceptAll( asmStmt->get_output(), *this);
     295        }
     296
     297        void Resolver::visit( IfStmt *ifStmt ) {
     298                Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this );
    290299                delete ifStmt->get_condition();
    291300                ifStmt->set_condition( newExpr );
    292         }
    293 
    294         void Resolver::previsit( WhileStmt *whileStmt ) {
    295                 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer );
     301                Parent::visit( ifStmt );
     302        }
     303
     304        void Resolver::visit( WhileStmt *whileStmt ) {
     305                Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this );
    296306                delete whileStmt->get_condition();
    297307                whileStmt->set_condition( newExpr );
    298         }
    299 
    300         void Resolver::previsit( ForStmt *forStmt ) {
     308                Parent::visit( whileStmt );
     309        }
     310
     311        void Resolver::visit( ForStmt *forStmt ) {
     312                Parent::visit( forStmt );
     313
    301314                if ( forStmt->get_condition() ) {
    302                         Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer );
     315                        Expression * newExpr = findSingleExpression( forStmt->get_condition(), *this );
    303316                        delete forStmt->get_condition();
    304317                        forStmt->set_condition( newExpr );
     
    306319
    307320                if ( forStmt->get_increment() ) {
    308                         Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer );
     321                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
    309322                        delete forStmt->get_increment();
    310323                        forStmt->set_increment( newExpr );
     
    312325        }
    313326
    314         void Resolver::previsit( SwitchStmt *switchStmt ) {
    315                 GuardValue( currentObject );
     327        void Resolver::visit( SwitchStmt *switchStmt ) {
     328                ValueGuard< CurrentObject > oldCurrentObject( currentObject );
    316329                Expression *newExpr;
    317                 newExpr = findIntegralExpression( switchStmt->get_condition(), indexer );
     330                newExpr = findIntegralExpression( switchStmt->get_condition(), *this );
    318331                delete switchStmt->get_condition();
    319332                switchStmt->set_condition( newExpr );
    320333
    321334                currentObject = CurrentObject( newExpr->get_result() );
    322         }
    323 
    324         void Resolver::previsit( CaseStmt *caseStmt ) {
     335                Parent::visit( switchStmt );
     336        }
     337
     338        void Resolver::visit( CaseStmt *caseStmt ) {
    325339                if ( caseStmt->get_condition() ) {
    326340                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    327341                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
    328342                        CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
    329                         Expression * newExpr = findSingleExpression( castExpr, indexer );
     343                        Expression * newExpr = findSingleExpression( castExpr, *this );
    330344                        castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    331345                        caseStmt->set_condition( castExpr->get_arg() );
     
    333347                        delete castExpr;
    334348                }
    335         }
    336 
    337         void Resolver::previsit( BranchStmt *branchStmt ) {
    338                 visit_children = false;
     349                Parent::visit( caseStmt );
     350        }
     351
     352        void Resolver::visit( BranchStmt *branchStmt ) {
    339353                // must resolve the argument for a computed goto
    340354                if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement
     
    343357                                PointerType pt( Type::Qualifiers(), v.clone() );
    344358                                CastExpr * castExpr = new CastExpr( arg, pt.clone() );
    345                                 Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression
     359                                Expression * newExpr = findSingleExpression( castExpr, *this ); // find best expression
    346360                                branchStmt->set_target( newExpr );
    347361                        } // if
     
    349363        }
    350364
    351         void Resolver::previsit( ReturnStmt *returnStmt ) {
    352                 visit_children = false;
     365        void Resolver::visit( ReturnStmt *returnStmt ) {
    353366                if ( returnStmt->get_expr() ) {
    354367                        CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() );
    355                         Expression *newExpr = findSingleExpression( castExpr, indexer );
     368                        Expression *newExpr = findSingleExpression( castExpr, *this );
    356369                        delete castExpr;
    357370                        returnStmt->set_expr( newExpr );
     
    359372        }
    360373
    361         void Resolver::previsit( ThrowStmt *throwStmt ) {
    362                 visit_children = false;
     374        void Resolver::visit( ThrowStmt *throwStmt ) {
    363375                // TODO: Replace *exception type with &exception type.
    364376                if ( throwStmt->get_expr() ) {
    365377                        StructDecl * exception_decl =
    366                                 indexer.lookupStruct( "__cfaehm__base_exception_t" );
     378                                lookupStruct( "__cfaehm__base_exception_t" );
    367379                        assert( exception_decl );
    368380                        Expression * wrapped = new CastExpr(
     
    376388                                        )
    377389                                );
    378                         Expression * newExpr = findSingleExpression( wrapped, indexer );
     390                        Expression * newExpr = findSingleExpression( wrapped, *this );
    379391                        throwStmt->set_expr( newExpr );
    380392                }
    381393        }
    382394
    383         void Resolver::previsit( CatchStmt *catchStmt ) {
     395        void Resolver::visit( CatchStmt *catchStmt ) {
     396                // inline Indexer::visit so that the exception variable is still in-scope for
     397                // findSingleExpression() below
     398                Parent::enterScope();
     399                Visitor::visit( catchStmt );
     400
    384401                if ( catchStmt->get_cond() ) {
    385402                        Expression * wrapped = new CastExpr(
     
    387404                                new BasicType( noQualifiers, BasicType::Bool )
    388405                                );
    389                         catchStmt->set_cond( findSingleExpression( wrapped, indexer ) );
    390                 }
     406                        catchStmt->set_cond( findSingleExpression( wrapped, *this ) );
     407                }
     408
     409                Parent::leaveScope();
    391410        }
    392411
     
    400419        }
    401420
    402         void Resolver::previsit( SingleInit *singleInit ) {
    403                 visit_children = false;
     421        void Resolver::visit( SingleInit *singleInit ) {
    404422                // resolve initialization using the possibilities as determined by the currentObject cursor
    405423                UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
    406                 Expression * newExpr = findSingleExpression( untyped, indexer );
     424                Expression * newExpr = findSingleExpression( untyped, *this );
    407425                InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr );
    408426
     
    443461        }
    444462
    445         void Resolver::previsit( ListInit * listInit ) {
    446                 visit_children = false;
     463        void Resolver::visit( ListInit * listInit ) {
    447464                // move cursor into brace-enclosed initializer-list
    448465                currentObject.enterListInit();
     
    455472                        Initializer * init = std::get<1>(p);
    456473                        newDesignations.push_back( currentObject.findNext( des ) );
    457                         init->accept( *visitor );
     474                        init->accept( *this );
    458475                }
    459476                // set the set of 'resolved' designations and leave the brace-enclosed initializer-list
     
    484501                delete ctorInit->get_dtor();
    485502                ctorInit->set_dtor( NULL );
    486                 maybeAccept( ctorInit->get_init(), *visitor );
     503                maybeAccept( ctorInit->get_init(), *this );
    487504        }
    488505
     
    490507        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ) {
    491508                assert( ctorInit );
    492                 PassVisitor<Resolver> resolver( indexer );
     509                Resolver resolver( indexer );
    493510                ctorInit->accept( resolver );
    494511        }
     
    496513        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ) {
    497514                assert( stmtExpr );
    498                 PassVisitor<Resolver> resolver( indexer );
     515                Resolver resolver( indexer );
    499516                stmtExpr->accept( resolver );
    500517        }
    501518
    502         void Resolver::previsit( ConstructorInit *ctorInit ) {
    503                 visit_children = false;
     519        void Resolver::visit( ConstructorInit *ctorInit ) {
    504520                // xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit
    505                 maybeAccept( ctorInit->get_ctor(), *visitor );
    506                 maybeAccept( ctorInit->get_dtor(), *visitor );
     521                maybeAccept( ctorInit->get_ctor(), *this );
     522                maybeAccept( ctorInit->get_dtor(), *this );
    507523
    508524                // found a constructor - can get rid of C-style initializer
  • src/SymTab/Indexer.cc

    r5f782f7 r3e3d923  
    230230
    231231                return *this;
     232        }
     233
     234        void Indexer::visit( ObjectDecl *objectDecl ) {
     235                enterScope();
     236                maybeAccept( objectDecl->get_type(), *this );
     237                leaveScope();
     238                maybeAccept( objectDecl->get_init(), *this );
     239                maybeAccept( objectDecl->get_bitfieldWidth(), *this );
     240                if ( objectDecl->get_name() != "" ) {
     241                        debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
     242                        addId( objectDecl );
     243                } // if
     244        }
     245
     246        void Indexer::visit( FunctionDecl *functionDecl ) {
     247                if ( functionDecl->get_name() == "" ) return;
     248                debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
     249                addId( functionDecl );
     250                enterScope();
     251                maybeAccept( functionDecl->get_functionType(), *this );
     252                maybeAccept( functionDecl->get_statements(), *this );
     253                leaveScope();
     254        }
     255
     256
     257// A NOTE ON THE ORDER OF TRAVERSAL
     258//
     259// Types and typedefs have their base types visited before they are added to the type table.  This is ok, since there is
     260// no such thing as a recursive type or typedef.
     261//
     262//             typedef struct { T *x; } T; // never allowed
     263//
     264// for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
     265// members are traversed, and then the complete type should be added (assuming the type is completed by this particular
     266// declaration).
     267//
     268//             struct T { struct T *x; }; // allowed
     269//
     270// It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
     271// traversal may modify the definition of the type and these modifications should be visible when the symbol table is
     272// queried later in this pass.
     273//
     274// TODO: figure out whether recursive contexts are sensible/possible/reasonable.
     275
     276
     277        void Indexer::visit( TypeDecl *typeDecl ) {
     278                // see A NOTE ON THE ORDER OF TRAVERSAL, above
     279                // note that assertions come after the type is added to the symtab, since they are not part of the type proper
     280                // and may depend on the type itself
     281                enterScope();
     282                acceptAll( typeDecl->get_parameters(), *this );
     283                maybeAccept( typeDecl->get_base(), *this );
     284                leaveScope();
     285                debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
     286                addType( typeDecl );
     287                acceptAll( typeDecl->get_assertions(), *this );
     288                acceptNewScope( typeDecl->get_init(), *this );
     289        }
     290
     291        void Indexer::visit( TypedefDecl *typeDecl ) {
     292                enterScope();
     293                acceptAll( typeDecl->get_parameters(), *this );
     294                maybeAccept( typeDecl->get_base(), *this );
     295                leaveScope();
     296                debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
     297                addType( typeDecl );
     298        }
     299
     300        void Indexer::visit( StructDecl *aggregateDecl ) {
     301                // make up a forward declaration and add it before processing the members
     302                // needs to be on the heap because addStruct saves the pointer
     303                StructDecl &fwdDecl = *new StructDecl( aggregateDecl->get_name() );
     304                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
     305                debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
     306                addStruct( &fwdDecl );
     307
     308                enterScope();
     309                acceptAll( aggregateDecl->get_parameters(), *this );
     310                acceptAll( aggregateDecl->get_members(), *this );
     311                leaveScope();
     312
     313                debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
     314                // this addition replaces the forward declaration
     315                addStruct( aggregateDecl );
     316        }
     317
     318        void Indexer::visit( UnionDecl *aggregateDecl ) {
     319                // make up a forward declaration and add it before processing the members
     320                UnionDecl fwdDecl( aggregateDecl->get_name() );
     321                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
     322                debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
     323                addUnion( &fwdDecl );
     324
     325                enterScope();
     326                acceptAll( aggregateDecl->get_parameters(), *this );
     327                acceptAll( aggregateDecl->get_members(), *this );
     328                leaveScope();
     329
     330                debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
     331                addUnion( aggregateDecl );
     332        }
     333
     334        void Indexer::visit( EnumDecl *aggregateDecl ) {
     335                debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
     336                addEnum( aggregateDecl );
     337                // unlike structs, contexts, and unions, enums inject their members into the global scope
     338                acceptAll( aggregateDecl->get_members(), *this );
     339        }
     340
     341        void Indexer::visit( TraitDecl *aggregateDecl ) {
     342                enterScope();
     343                acceptAll( aggregateDecl->get_parameters(), *this );
     344                acceptAll( aggregateDecl->get_members(), *this );
     345                leaveScope();
     346
     347                debugPrint( "Adding trait " << aggregateDecl->get_name() << std::endl );
     348                addTrait( aggregateDecl );
     349        }
     350
     351        void Indexer::visit( CompoundStmt *compoundStmt ) {
     352                enterScope();
     353                acceptAll( compoundStmt->get_kids(), *this );
     354                leaveScope();
     355        }
     356
     357        void Indexer::visit( IfStmt *ifStmt ) {
     358            // for statements introduce a level of scope
     359            enterScope();
     360            Visitor::visit( ifStmt );
     361            leaveScope();
     362        }
     363
     364        void Indexer::visit( ForStmt *forStmt ) {
     365            // for statements introduce a level of scope
     366            enterScope();
     367            Visitor::visit( forStmt );
     368            leaveScope();
     369        }
     370
     371        void Indexer::visit( CatchStmt *catchStmt ) {
     372                // catch statements introduce a level of scope (for the caught exception)
     373                enterScope();
     374                Visitor::visit( catchStmt );
     375                leaveScope();
     376        }
     377
     378        void Indexer::visit( ApplicationExpr *applicationExpr ) {
     379                acceptNewScope( applicationExpr->get_result(), *this );
     380                maybeAccept( applicationExpr->get_function(), *this );
     381                acceptAll( applicationExpr->get_args(), *this );
     382        }
     383
     384        void Indexer::visit( UntypedExpr *untypedExpr ) {
     385                acceptNewScope( untypedExpr->get_result(), *this );
     386                acceptAll( untypedExpr->get_args(), *this );
     387        }
     388
     389        void Indexer::visit( NameExpr *nameExpr ) {
     390                acceptNewScope( nameExpr->get_result(), *this );
     391        }
     392
     393        void Indexer::visit( AddressExpr *addressExpr ) {
     394                acceptNewScope( addressExpr->get_result(), *this );
     395                maybeAccept( addressExpr->get_arg(), *this );
     396        }
     397
     398        void Indexer::visit( LabelAddressExpr *labAddressExpr ) {
     399                acceptNewScope( labAddressExpr->get_result(), *this );
     400        }
     401
     402        void Indexer::visit( CastExpr *castExpr ) {
     403                acceptNewScope( castExpr->get_result(), *this );
     404                maybeAccept( castExpr->get_arg(), *this );
     405        }
     406
     407        void Indexer::visit( UntypedMemberExpr *memberExpr ) {
     408                acceptNewScope( memberExpr->get_result(), *this );
     409                maybeAccept( memberExpr->get_aggregate(), *this );
     410        }
     411
     412        void Indexer::visit( MemberExpr *memberExpr ) {
     413                acceptNewScope( memberExpr->get_result(), *this );
     414                maybeAccept( memberExpr->get_aggregate(), *this );
     415        }
     416
     417        void Indexer::visit( VariableExpr *variableExpr ) {
     418                acceptNewScope( variableExpr->get_result(), *this );
     419        }
     420
     421        void Indexer::visit( ConstantExpr *constantExpr ) {
     422                acceptNewScope( constantExpr->get_result(), *this );
     423                maybeAccept( constantExpr->get_constant(), *this );
     424        }
     425
     426        void Indexer::visit( SizeofExpr *sizeofExpr ) {
     427                acceptNewScope( sizeofExpr->get_result(), *this );
     428                if ( sizeofExpr->get_isType() ) {
     429                        maybeAccept( sizeofExpr->get_type(), *this );
     430                } else {
     431                        maybeAccept( sizeofExpr->get_expr(), *this );
     432                }
     433        }
     434
     435        void Indexer::visit( AlignofExpr *alignofExpr ) {
     436                acceptNewScope( alignofExpr->get_result(), *this );
     437                if ( alignofExpr->get_isType() ) {
     438                        maybeAccept( alignofExpr->get_type(), *this );
     439                } else {
     440                        maybeAccept( alignofExpr->get_expr(), *this );
     441                }
     442        }
     443
     444        void Indexer::visit( UntypedOffsetofExpr *offsetofExpr ) {
     445                acceptNewScope( offsetofExpr->get_result(), *this );
     446                maybeAccept( offsetofExpr->get_type(), *this );
     447        }
     448
     449        void Indexer::visit( OffsetofExpr *offsetofExpr ) {
     450                acceptNewScope( offsetofExpr->get_result(), *this );
     451                maybeAccept( offsetofExpr->get_type(), *this );
     452                maybeAccept( offsetofExpr->get_member(), *this );
     453        }
     454
     455        void Indexer::visit( OffsetPackExpr *offsetPackExpr ) {
     456                acceptNewScope( offsetPackExpr->get_result(), *this );
     457                maybeAccept( offsetPackExpr->get_type(), *this );
     458        }
     459
     460        void Indexer::visit( AttrExpr *attrExpr ) {
     461                acceptNewScope( attrExpr->get_result(), *this );
     462                if ( attrExpr->get_isType() ) {
     463                        maybeAccept( attrExpr->get_type(), *this );
     464                } else {
     465                        maybeAccept( attrExpr->get_expr(), *this );
     466                }
     467        }
     468
     469        void Indexer::visit( LogicalExpr *logicalExpr ) {
     470                acceptNewScope( logicalExpr->get_result(), *this );
     471                maybeAccept( logicalExpr->get_arg1(), *this );
     472                maybeAccept( logicalExpr->get_arg2(), *this );
     473        }
     474
     475        void Indexer::visit( ConditionalExpr *conditionalExpr ) {
     476                acceptNewScope( conditionalExpr->get_result(), *this );
     477                maybeAccept( conditionalExpr->get_arg1(), *this );
     478                maybeAccept( conditionalExpr->get_arg2(), *this );
     479                maybeAccept( conditionalExpr->get_arg3(), *this );
     480        }
     481
     482        void Indexer::visit( CommaExpr *commaExpr ) {
     483                acceptNewScope( commaExpr->get_result(), *this );
     484                maybeAccept( commaExpr->get_arg1(), *this );
     485                maybeAccept( commaExpr->get_arg2(), *this );
     486        }
     487
     488        void Indexer::visit( TypeExpr *typeExpr ) {
     489                acceptNewScope( typeExpr->get_result(), *this );
     490                maybeAccept( typeExpr->get_type(), *this );
     491        }
     492
     493        void Indexer::visit( AsmExpr *asmExpr ) {
     494                maybeAccept( asmExpr->get_inout(), *this );
     495                maybeAccept( asmExpr->get_constraint(), *this );
     496                maybeAccept( asmExpr->get_operand(), *this );
     497        }
     498
     499        void Indexer::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     500                acceptNewScope( impCpCtorExpr->get_result(), *this );
     501                maybeAccept( impCpCtorExpr->get_callExpr(), *this );
     502                acceptAll( impCpCtorExpr->get_tempDecls(), *this );
     503                acceptAll( impCpCtorExpr->get_returnDecls(), *this );
     504                acceptAll( impCpCtorExpr->get_dtors(), *this );
     505        }
     506
     507        void Indexer::visit( ConstructorExpr * ctorExpr ) {
     508                acceptNewScope( ctorExpr->get_result(), *this );
     509                maybeAccept( ctorExpr->get_callExpr(), *this );
     510        }
     511
     512        void Indexer::visit( CompoundLiteralExpr *compLitExpr ) {
     513                acceptNewScope( compLitExpr->get_result(), *this );
     514                maybeAccept( compLitExpr->get_initializer(), *this );
     515        }
     516
     517        void Indexer::visit( RangeExpr *rangeExpr ) {
     518                maybeAccept( rangeExpr->get_low(), *this );
     519                maybeAccept( rangeExpr->get_high(), *this );
     520        }
     521
     522        void Indexer::visit( UntypedTupleExpr *tupleExpr ) {
     523                acceptNewScope( tupleExpr->get_result(), *this );
     524                acceptAll( tupleExpr->get_exprs(), *this );
     525        }
     526
     527        void Indexer::visit( TupleExpr *tupleExpr ) {
     528                acceptNewScope( tupleExpr->get_result(), *this );
     529                acceptAll( tupleExpr->get_exprs(), *this );
     530        }
     531
     532        void Indexer::visit( TupleIndexExpr *tupleExpr ) {
     533                acceptNewScope( tupleExpr->get_result(), *this );
     534                maybeAccept( tupleExpr->get_tuple(), *this );
     535        }
     536
     537        void Indexer::visit( TupleAssignExpr *tupleExpr ) {
     538                acceptNewScope( tupleExpr->get_result(), *this );
     539                maybeAccept( tupleExpr->get_stmtExpr(), *this );
     540        }
     541
     542        void Indexer::visit( StmtExpr *stmtExpr ) {
     543                acceptNewScope( stmtExpr->get_result(), *this );
     544                maybeAccept( stmtExpr->get_statements(), *this );
     545                acceptAll( stmtExpr->get_returnDecls(), *this );
     546                acceptAll( stmtExpr->get_dtors(), *this );
     547        }
     548
     549        void Indexer::visit( UniqueExpr *uniqueExpr ) {
     550                acceptNewScope( uniqueExpr->get_result(), *this );
     551                maybeAccept( uniqueExpr->get_expr(), *this );
     552        }
     553
     554
     555        void Indexer::visit( TraitInstType *traitInst ) {
     556                acceptAll( traitInst->get_parameters(), *this );
     557        }
     558
     559        void Indexer::visit( StructInstType *structInst ) {
     560                if ( ! lookupStruct( structInst->get_name() ) ) {
     561                        debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
     562                        addStruct( structInst->get_name() );
     563                }
     564                enterScope();
     565                acceptAll( structInst->get_parameters(), *this );
     566                leaveScope();
     567        }
     568
     569        void Indexer::visit( UnionInstType *unionInst ) {
     570                if ( ! lookupUnion( unionInst->get_name() ) ) {
     571                        debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
     572                        addUnion( unionInst->get_name() );
     573                }
     574                enterScope();
     575                acceptAll( unionInst->get_parameters(), *this );
     576                leaveScope();
    232577        }
    233578
     
    417762
    418763        void Indexer::addId( DeclarationWithType *decl ) {
    419                 debugPrint( "Adding Id " << decl->name << std::endl );
    420764                makeWritable();
    421765
     
    467811
    468812        void Indexer::addType( NamedTypeDecl *decl ) {
    469                 debugPrint( "Adding type " << decl->name << std::endl );
    470813                makeWritable();
    471814
     
    495838
    496839        void Indexer::addStruct( const std::string &id ) {
    497                 debugPrint( "Adding fwd decl for struct " << id << std::endl );
    498840                addStruct( new StructDecl( id ) );
    499841        }
    500842
    501843        void Indexer::addStruct( StructDecl *decl ) {
    502                 debugPrint( "Adding struct " << decl->name << std::endl );
    503844                makeWritable();
    504845
     
    519860
    520861        void Indexer::addEnum( EnumDecl *decl ) {
    521                 debugPrint( "Adding enum " << decl->name << std::endl );
    522862                makeWritable();
    523863
     
    538878
    539879        void Indexer::addUnion( const std::string &id ) {
    540                 debugPrint( "Adding fwd decl for union " << id << std::endl );
    541880                addUnion( new UnionDecl( id ) );
    542881        }
    543882
    544883        void Indexer::addUnion( UnionDecl *decl ) {
    545                 debugPrint( "Adding union " << decl->name << std::endl );
    546884                makeWritable();
    547885
     
    562900
    563901        void Indexer::addTrait( TraitDecl *decl ) {
    564                 debugPrint( "Adding trait " << decl->name << std::endl );
    565902                makeWritable();
    566903
  • src/SymTab/Indexer.h

    r5f782f7 r3e3d923  
    2424
    2525namespace SymTab {
    26         class Indexer {
     26        class Indexer : public Visitor {
    2727          public:
    2828                explicit Indexer( bool useDebug = false );
     
    3333                Indexer& operator= ( const Indexer &that );
    3434                Indexer& operator= ( Indexer &&that );
     35
     36                using Visitor::visit;
     37                virtual void visit( ObjectDecl *objectDecl );
     38                virtual void visit( FunctionDecl *functionDecl );
     39                virtual void visit( TypeDecl *typeDecl );
     40                virtual void visit( TypedefDecl *typeDecl );
     41                virtual void visit( StructDecl *aggregateDecl );
     42                virtual void visit( UnionDecl *aggregateDecl );
     43                virtual void visit( EnumDecl *aggregateDecl );
     44                virtual void visit( TraitDecl *aggregateDecl );
     45
     46                virtual void visit( CompoundStmt *compoundStmt );
     47                virtual void visit( IfStmt *ifStmt );
     48                virtual void visit( ForStmt *forStmt );
     49                virtual void visit( CatchStmt *catchStmt );
     50
     51                virtual void visit( ApplicationExpr *applicationExpr );
     52                virtual void visit( UntypedExpr *untypedExpr );
     53                virtual void visit( NameExpr *nameExpr );
     54                virtual void visit( CastExpr *castExpr );
     55                virtual void visit( AddressExpr *addressExpr );
     56                virtual void visit( LabelAddressExpr *labAddressExpr );
     57                virtual void visit( UntypedMemberExpr *memberExpr );
     58                virtual void visit( MemberExpr *memberExpr );
     59                virtual void visit( VariableExpr *variableExpr );
     60                virtual void visit( ConstantExpr *constantExpr );
     61                virtual void visit( SizeofExpr *sizeofExpr );
     62                virtual void visit( AlignofExpr *alignofExpr );
     63                virtual void visit( UntypedOffsetofExpr *offsetofExpr );
     64                virtual void visit( OffsetofExpr *offsetofExpr );
     65                virtual void visit( OffsetPackExpr *offsetPackExpr );
     66                virtual void visit( AttrExpr *attrExpr );
     67                virtual void visit( LogicalExpr *logicalExpr );
     68                virtual void visit( ConditionalExpr *conditionalExpr );
     69                virtual void visit( CommaExpr *commaExpr );
     70                virtual void visit( TypeExpr *typeExpr );
     71                virtual void visit( AsmExpr *asmExpr );
     72                virtual void visit( ImplicitCopyCtorExpr *impCpCtorExpr );
     73                virtual void visit( ConstructorExpr * ctorExpr );
     74                virtual void visit( CompoundLiteralExpr *compLitExpr );
     75                virtual void visit( RangeExpr *rangeExpr );
     76                virtual void visit( UntypedTupleExpr *tupleExpr );
     77                virtual void visit( TupleExpr *tupleExpr );
     78                virtual void visit( TupleIndexExpr *tupleExpr );
     79                virtual void visit( TupleAssignExpr *tupleExpr );
     80                virtual void visit( StmtExpr * stmtExpr );
     81                virtual void visit( UniqueExpr * uniqueExpr );
     82
     83                virtual void visit( TraitInstType *contextInst );
     84                virtual void visit( StructInstType *contextInst );
     85                virtual void visit( UnionInstType *contextInst );
    3586
    3687                // when using an indexer manually (e.g., within a mutator traversal), it is necessary to tell the indexer
  • src/main.cc

    r5f782f7 r3e3d923  
    3535#include "CodeTools/DeclStats.h"            // for printDeclStats
    3636#include "CodeTools/TrackLoc.h"             // for fillLocations
    37 #include "Common/PassVisitor.h"
    3837#include "Common/CompilerError.h"           // for CompilerError
    3938#include "Common/SemanticError.h"           // for SemanticError
     
    251250
    252251                if ( expraltp ) {
    253                         PassVisitor<ResolvExpr::AlternativePrinter> printer( cout );
     252                        ResolvExpr::AlternativePrinter printer( cout );
    254253                        acceptAll( translationUnit, printer );
    255254                        return 0;
Note: See TracChangeset for help on using the changeset viewer.