Changes in / [3e3d923:5f782f7]


Ignore:
Location:
src
Files:
10 edited

Legend:

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

    r3e3d923 r5f782f7  
    183183
    184184                } catch ( SemanticError &e ) {
     185                        e.set_location( (*i)->location );
    185186                        errors.append( e );
    186187                }
     
    292293//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    293294
     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.
    294313
    295314//--------------------------------------------------------------------------
     
    449468        indexerAddEnum( node );
    450469
    451         // unlike structs, contexts, and unions, enums inject their members into the global scope
     470        // unlike structs, traits, and unions, enums inject their members into the global scope
    452471        maybeAccept( node->parameters, *this );
    453472        maybeAccept( node->members   , *this );
     
    513532        }
    514533
     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
    515537        indexerAddType( node );
    516538
     
    532554        }
    533555
     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
    534559        indexerAddType( node );
    535560
     
    658683void PassVisitor< pass_type >::visit( IfStmt * node ) {
    659684        VISIT_START( node );
    660 
    661         visitExpression( node->condition );
    662         node->thenPart = visitStatement( node->thenPart );
    663         node->elsePart = visitStatement( node->elsePart );
    664 
     685        {
     686                // if statements introduce a level of scope (for the initialization)
     687                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        }
    665693        VISIT_END( node );
    666694}
     
    670698        MUTATE_START( node );
    671699        {
    672                 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     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 );
    673703                node->condition = mutateExpression( node->condition );
    674704                node->thenPart  = mutateStatement ( node->thenPart  );
     
    706736        VISIT_START( node );
    707737        {
     738                // for statements introduce a level of scope (for the initialization)
    708739                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    709740                maybeAccept( node->initialization, *this );
     
    719750        MUTATE_START( node );
    720751        {
     752                // for statements introduce a level of scope (for the initialization)
    721753                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    722754                maybeMutateRef( node->initialization, *this );
     
    847879        VISIT_START( node );
    848880        {
     881                // catch statements introduce a level of scope (for the caught exception)
    849882                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    850883                maybeAccept( node->decl, *this );
     
    859892        MUTATE_START( node );
    860893        {
     894                // catch statements introduce a level of scope (for the caught exception)
    861895                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    862896                maybeMutateRef( node->decl, *this );
  • src/GenPoly/Box.cc

    r3e3d923 r5f782f7  
    628628                                        } else {
    629629                                                // xxx - should this be an assertion?
    630                                                 std::string x = env ? toString( *env ) : "missing env";
    631                                                 throw SemanticError( x + "\n" + "unbound type variable: " + tyParm->first + " in application ", appExpr );
     630                                                throw SemanticError( toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ), appExpr );
    632631                                        } // if
    633632                                } // if
     
    706705                                if ( concrete == 0 ) {
    707706                                        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 );
    711707                                } // if
    712708                                return concrete;
  • src/InitTweak/FixInit.cc

    r3e3d923 r5f782f7  
    7070namespace InitTweak {
    7171        namespace {
    72                 typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap;
    7372                typedef std::unordered_map< int, int > UnqCount;
    7473
    75                 class InsertImplicitCalls : public WithTypeSubstitution {
    76                 public:
     74                struct InsertImplicitCalls : public WithTypeSubstitution {
    7775                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
    7876                        /// function calls need their parameters to be copy constructed
    79                         static void insert( std::list< Declaration * > & translationUnit, EnvMap & envMap );
    80 
    81                         InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {}
     77                        static void insert( std::list< Declaration * > & translationUnit );
    8278
    8379                        Expression * postmutate( ApplicationExpr * appExpr );
    84                         void premutate( StmtExpr * stmtExpr );
    85 
    86                         // collects environments for relevant nodes
    87                         EnvMap & envMap;
    8880                };
    8981
    90                 class ResolveCopyCtors final : public SymTab::Indexer {
    91                 public:
     82                struct ResolveCopyCtors final : public WithIndexer, public WithShortCircuiting, public WithTypeSubstitution {
    9283                        /// generate temporary ObjectDecls for each argument and return value of each ImplicitCopyCtorExpr,
    9384                        /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both
    9485                        /// arguments and return value temporaries
    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;
     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 );
    10594
    10695                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
     
    111100                        void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    112101
    113                         TypeSubstitution * env;
    114                         const EnvMap & envMap;
    115102                        UnqCount & unqCount; // count the number of times each unique expr ID appears
     103                        std::unordered_set< int > vars;
    116104                };
    117105
     
    238226                };
    239227
    240                 class GenStructMemberCalls final : public SymTab::Indexer {
    241                   public:
    242                         typedef Indexer Parent;
     228                struct GenStructMemberCalls final : public WithGuards, public WithShortCircuiting, public WithIndexer {
    243229                        /// generate default/copy ctor and dtor calls for user-defined struct ctor/dtors
    244230                        /// for any member that is missing a corresponding ctor/dtor call.
     
    246232                        static void generate( std::list< Declaration * > & translationUnit );
    247233
    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;
     234                        void previsit( FunctionDecl * funcDecl );
     235                        void postvisit( FunctionDecl * funcDecl );
     236
     237                        void previsit( MemberExpr * memberExpr );
     238                        void previsit( ApplicationExpr * appExpr );
    254239
    255240                        SemanticError errors;
     
    295280                InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
    296281
    297                 EnvMap envMap;
    298282                UnqCount unqCount;
    299283
    300                 InsertImplicitCalls::insert( translationUnit, envMap );
    301                 ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap, unqCount );
     284                InsertImplicitCalls::insert( translationUnit );
     285                ResolveCopyCtors::resolveImplicitCalls( translationUnit, unqCount );
    302286                InsertDtors::insert( translationUnit );
    303287                FixInit::fixInitializers( translationUnit );
     
    318302
    319303        namespace {
    320                 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) {
    321                         PassVisitor<InsertImplicitCalls> inserter( envMap );
     304                void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) {
     305                        PassVisitor<InsertImplicitCalls> inserter;
    322306                        mutateAll( translationUnit, inserter );
    323307                }
    324308
    325                 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount ) {
    326                         ResolveCopyCtors resolver( envMap, unqCount );
     309                void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
     310                        PassVisitor<ResolveCopyCtors> resolver( unqCount );
    327311                        acceptAll( translationUnit, resolver );
    328312                }
     
    360344
    361345                void GenStructMemberCalls::generate( std::list< Declaration * > & translationUnit ) {
    362                         GenStructMemberCalls warner;
     346                        PassVisitor<GenStructMemberCalls> warner;
    363347                        acceptAll( translationUnit, warner );
    364348                }
     
    398382                        // wrap each function call so that it is easy to identify nodes that have to be copy constructed
    399383                        ImplicitCopyCtorExpr * expr = new ImplicitCopyCtorExpr( appExpr );
    400                         // save the type substitution into the envMap so that it is easy to find.
     384                        // Move the type substitution to the new top-level, if it is attached to the appExpr.
    401385                        // Ensure it is not deleted with the ImplicitCopyCtorExpr by removing it before deletion.
    402386                        // The substitution is needed to obtain the type of temporary variables so that copy constructor
    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.
     387                        // calls can be resolved.
    408388                        assert( env );
    409                         envMap[expr] = env;
     389                        std::swap( expr->env, appExpr->env );
    410390                        return expr;
    411                 }
    412 
    413                 void InsertImplicitCalls::premutate( StmtExpr * stmtExpr ) {
    414                         assert( env );
    415                         envMap[stmtExpr] = env;
    416391                }
    417392
     
    431406                        // (VariableExpr and already resolved expression)
    432407                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    433                         Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this );
     408                        Expression * resolved = ResolvExpr::findVoidExpression( untyped, indexer );
    434409                        assert( resolved );
    435410                        if ( resolved->get_env() ) {
     
    480455                }
    481456
    482                 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     457                void ResolveCopyCtors::postvisit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    483458                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    484                         Parent::visit( impCpCtorExpr );
    485                         env = envMap.at(impCpCtorExpr);
    486                         assert( env );
    487459
    488460                        ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
     
    513485                }
    514486
    515                 void ResolveCopyCtors::visit( StmtExpr * stmtExpr ) {
    516                         Parent::visit( stmtExpr );
    517                         env = envMap.at(stmtExpr);
     487                void ResolveCopyCtors::postvisit( StmtExpr * stmtExpr ) {
     488                        assert( env );
    518489                        assert( stmtExpr->get_result() );
    519490                        Type * result = stmtExpr->get_result();
     
    537508                                stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    538509                        } // if
    539 
    540                 }
    541 
    542                 void ResolveCopyCtors::visit( UniqueExpr * unqExpr ) {
    543                         static std::unordered_set< int > vars;
     510                }
     511
     512                void ResolveCopyCtors::previsit( UniqueExpr * unqExpr ) {
    544513                        unqCount[ unqExpr->get_id() ]++;  // count the number of unique expressions for each ID
    545514                        if ( vars.count( unqExpr->get_id() ) ) {
    546515                                // 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
    547523                                return;
    548524                        }
    549525
    550                         Parent::visit( unqExpr );
    551526                        // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought
    552527                        assert( unqExpr->get_result() );
     
    585560
    586561                        // xxx - update to work with multiple return values
    587                         ObjectDecl * returnDecl = returnDecls.empty() ? NULL : returnDecls.front();
     562                        ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front();
    588563                        Expression * callExpr = impCpCtorExpr->get_callExpr();
    589564
     
    594569                        tempDecls.clear();
    595570                        returnDecls.clear();
    596                         impCpCtorExpr->set_callExpr( NULL );
    597                         impCpCtorExpr->set_env( NULL );
     571                        impCpCtorExpr->set_callExpr( nullptr );
     572                        std::swap( impCpCtorExpr->env, callExpr->env );
     573                        assert( impCpCtorExpr->env == nullptr );
    598574                        delete impCpCtorExpr;
    599575
     
    978954                }
    979955
    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 );
     956                void GenStructMemberCalls::previsit( FunctionDecl * funcDecl ) {
     957                        GuardValue( funcDecl );
     958                        GuardValue( unhandled );
     959                        GuardValue( usedUninit );
     960                        GuardValue( thisParam );
     961                        GuardValue( isCtor );
     962                        GuardValue( structDecl );
    987963                        errors = SemanticError();  // clear previous errors
    988964
     
    1010986                                }
    1011987                        }
    1012                         Parent::visit( function );
    1013 
     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 ) {
    10141004                        // remove the unhandled objects from usedUninit, because a call is inserted
    10151005                        // to handle them - only objects that are later constructed are used uninitialized.
     
    10321022                        if ( ! unhandled.empty() ) {
    10331023                                // need to explicitly re-add function parameters to the indexer in order to resolve copy constructors
    1034                                 enterScope();
    1035                                 maybeAccept( function->get_functionType(), *this );
     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 );
    10361028
    10371029                                // need to iterate through members in reverse in order for
     
    10631055                                                Statement * callStmt = stmt.front();
    10641056
    1065                                                 MutatingResolver resolver( *this );
     1057                                                MutatingResolver resolver( indexer );
    10661058                                                try {
    10671059                                                        callStmt->acceptMutator( resolver );
     
    10771069                                        }
    10781070                                }
    1079                                 leaveScope();
    10801071                        }
    10811072                        if (! errors.isEmpty()) {
     
    11071098                }
    11081099
    1109                 void GenStructMemberCalls::visit( ApplicationExpr * appExpr ) {
    1110                         if ( ! checkWarnings( function ) ) return;
     1100                void GenStructMemberCalls::previsit( ApplicationExpr * appExpr ) {
     1101                        if ( ! checkWarnings( function ) ) {
     1102                                visit_children = false;
     1103                                return;
     1104                        }
    11111105
    11121106                        std::string fname = getFunctionName( appExpr );
     
    11271121                                }
    11281122                        }
    1129                         Parent::visit( appExpr );
    1130                 }
    1131 
    1132                 void GenStructMemberCalls::visit( MemberExpr * memberExpr ) {
    1133                         if ( ! checkWarnings( function ) ) return;
    1134                         if ( ! isCtor ) return;
     1123                }
     1124
     1125                void GenStructMemberCalls::previsit( MemberExpr * memberExpr ) {
     1126                        if ( ! checkWarnings( function ) || ! isCtor ) {
     1127                                visit_children = false;
     1128                                return;
     1129                        }
    11351130
    11361131                        if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
     
    11401135                                }
    11411136                        }
    1142                         Parent::visit( memberExpr );
    11431137                }
    11441138
     
    11611155                        // in generated code. If this changes, add mutate methods for entities with
    11621156                        // scope and call {enter,leave}Scope explicitly.
    1163                         objectDecl->accept( indexer );
     1157                        indexer.addId( objectDecl );
    11641158                        return objectDecl;
    11651159                }
  • src/ResolvExpr/AlternativeFinder.cc

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

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

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

    r3e3d923 r5f782f7  
    2121#include "Alternative.h"                 // for Alternative, AltList
    2222#include "AlternativeFinder.h"           // for AlternativeFinder, resolveIn...
     23#include "Common/PassVisitor.h"          // for PassVisitor
    2324#include "Common/SemanticError.h"        // for SemanticError
    2425#include "Common/utility.h"              // for ValueGuard, group_iterate
     
    4344
    4445namespace ResolvExpr {
    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;
     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 );
    8277          private:
    8378        typedef std::list< Initializer * >::iterator InitIterator;
     
    9691
    9792        void resolve( std::list< Declaration * > translationUnit ) {
    98                 Resolver resolver;
     93                PassVisitor<Resolver> resolver;
    9994                acceptAll( translationUnit, resolver );
    10095        }
    10196
     97        // used in resolveTypeof
    10298        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
    10399                TypeEnvironment env;
    104100                return resolveInVoidContext( expr, indexer, env );
    105101        }
    106 
    107102
    108103        namespace {
     
    190185        }
    191186
    192         void Resolver::visit( ObjectDecl *objectDecl ) {
    193                 Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
     187        void Resolver::previsit( ObjectDecl *objectDecl ) {
     188                Type *new_type = resolveTypeof( objectDecl->get_type(), indexer );
    194189                objectDecl->set_type( new_type );
    195190                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable
     
    198193                // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
    199194                // the RHS.
    200                 ValueGuard<CurrentObject> temp( currentObject );
     195                GuardValue( currentObject );
    201196                currentObject = CurrentObject( objectDecl->get_type() );
    202197                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
     
    205200                        currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    206201                }
    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                 }
    212202        }
    213203
     
    216206                if ( type->get_dimension() ) {
    217207                        CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() );
    218                         Expression *newExpr = findSingleExpression( castExpr, *this );
     208                        Expression *newExpr = findSingleExpression( castExpr, indexer );
    219209                        delete type->get_dimension();
    220210                        type->set_dimension( newExpr );
     
    222212        }
    223213
    224         void Resolver::visit( ArrayType * at ) {
     214        void Resolver::previsit( ArrayType * at ) {
    225215                handlePtrType( at );
    226                 Parent::visit( at );
    227         }
    228 
    229         void Resolver::visit( PointerType * pt ) {
     216        }
     217
     218        void Resolver::previsit( PointerType * pt ) {
    230219                handlePtrType( pt );
    231                 Parent::visit( pt );
    232         }
    233 
    234         void Resolver::visit( TypeDecl *typeDecl ) {
     220        }
     221
     222        void Resolver::previsit( TypeDecl *typeDecl ) {
    235223                if ( typeDecl->get_base() ) {
    236                         Type *new_type = resolveTypeof( typeDecl->get_base(), *this );
     224                        Type *new_type = resolveTypeof( typeDecl->get_base(), indexer );
    237225                        typeDecl->set_base( new_type );
    238226                } // if
    239                 Parent::visit( typeDecl );
    240         }
    241 
    242         void Resolver::visit( FunctionDecl *functionDecl ) {
     227        }
     228
     229        void Resolver::previsit( FunctionDecl *functionDecl ) {
    243230#if 0
    244                 std::cout << "resolver visiting functiondecl ";
    245                 functionDecl->print( std::cout );
    246                 std::cout << std::endl;
     231                std::cerr << "resolver visiting functiondecl ";
     232                functionDecl->print( std::cerr );
     233                std::cerr << std::endl;
    247234#endif
    248                 Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
     235                Type *new_type = resolveTypeof( functionDecl->get_type(), indexer );
    249236                functionDecl->set_type( new_type );
    250                 ValueGuard< Type * > oldFunctionReturn( functionReturn );
     237                GuardValue( functionReturn );
    251238                functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
    252                 Parent::visit( functionDecl );
    253 
     239        }
     240
     241
     242        void Resolver::postvisit( FunctionDecl *functionDecl ) {
    254243                // default value expressions have an environment which shouldn't be there and trips up later passes.
    255244                // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently
     
    265254        }
    266255
    267         void Resolver::visit( EnumDecl * enumDecl ) {
     256        void Resolver::previsit( EnumDecl * ) {
    268257                // in case we decide to allow nested enums
    269                 ValueGuard< bool > oldInEnumDecl( inEnumDecl );
     258                GuardValue( inEnumDecl );
    270259                inEnumDecl = true;
    271                 Parent::visit( enumDecl );
    272         }
    273 
    274         void Resolver::visit( ExprStmt *exprStmt ) {
     260        }
     261
     262        void Resolver::previsit( ExprStmt *exprStmt ) {
     263                visit_children = false;
    275264                assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" );
    276                 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
     265                Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer );
    277266                delete exprStmt->get_expr();
    278267                exprStmt->set_expr( newExpr );
    279268        }
    280269
    281         void Resolver::visit( AsmExpr *asmExpr ) {
    282                 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), *this );
     270        void Resolver::previsit( AsmExpr *asmExpr ) {
     271                visit_children = false;
     272                Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer );
    283273                delete asmExpr->get_operand();
    284274                asmExpr->set_operand( newExpr );
    285275                if ( asmExpr->get_inout() ) {
    286                         newExpr = findVoidExpression( asmExpr->get_inout(), *this );
     276                        newExpr = findVoidExpression( asmExpr->get_inout(), indexer );
    287277                        delete asmExpr->get_inout();
    288278                        asmExpr->set_inout( newExpr );
     
    290280        }
    291281
    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 );
     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 );
    299290                delete ifStmt->get_condition();
    300291                ifStmt->set_condition( newExpr );
    301                 Parent::visit( ifStmt );
    302         }
    303 
    304         void Resolver::visit( WhileStmt *whileStmt ) {
    305                 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this );
     292        }
     293
     294        void Resolver::previsit( WhileStmt *whileStmt ) {
     295                Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer );
    306296                delete whileStmt->get_condition();
    307297                whileStmt->set_condition( newExpr );
    308                 Parent::visit( whileStmt );
    309         }
    310 
    311         void Resolver::visit( ForStmt *forStmt ) {
    312                 Parent::visit( forStmt );
    313 
     298        }
     299
     300        void Resolver::previsit( ForStmt *forStmt ) {
    314301                if ( forStmt->get_condition() ) {
    315                         Expression * newExpr = findSingleExpression( forStmt->get_condition(), *this );
     302                        Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer );
    316303                        delete forStmt->get_condition();
    317304                        forStmt->set_condition( newExpr );
     
    319306
    320307                if ( forStmt->get_increment() ) {
    321                         Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
     308                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer );
    322309                        delete forStmt->get_increment();
    323310                        forStmt->set_increment( newExpr );
     
    325312        }
    326313
    327         void Resolver::visit( SwitchStmt *switchStmt ) {
    328                 ValueGuard< CurrentObject > oldCurrentObject( currentObject );
     314        void Resolver::previsit( SwitchStmt *switchStmt ) {
     315                GuardValue( currentObject );
    329316                Expression *newExpr;
    330                 newExpr = findIntegralExpression( switchStmt->get_condition(), *this );
     317                newExpr = findIntegralExpression( switchStmt->get_condition(), indexer );
    331318                delete switchStmt->get_condition();
    332319                switchStmt->set_condition( newExpr );
    333320
    334321                currentObject = CurrentObject( newExpr->get_result() );
    335                 Parent::visit( switchStmt );
    336         }
    337 
    338         void Resolver::visit( CaseStmt *caseStmt ) {
     322        }
     323
     324        void Resolver::previsit( CaseStmt *caseStmt ) {
    339325                if ( caseStmt->get_condition() ) {
    340326                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    341327                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
    342328                        CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
    343                         Expression * newExpr = findSingleExpression( castExpr, *this );
     329                        Expression * newExpr = findSingleExpression( castExpr, indexer );
    344330                        castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    345331                        caseStmt->set_condition( castExpr->get_arg() );
     
    347333                        delete castExpr;
    348334                }
    349                 Parent::visit( caseStmt );
    350         }
    351 
    352         void Resolver::visit( BranchStmt *branchStmt ) {
     335        }
     336
     337        void Resolver::previsit( BranchStmt *branchStmt ) {
     338                visit_children = false;
    353339                // must resolve the argument for a computed goto
    354340                if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement
     
    357343                                PointerType pt( Type::Qualifiers(), v.clone() );
    358344                                CastExpr * castExpr = new CastExpr( arg, pt.clone() );
    359                                 Expression * newExpr = findSingleExpression( castExpr, *this ); // find best expression
     345                                Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression
    360346                                branchStmt->set_target( newExpr );
    361347                        } // if
     
    363349        }
    364350
    365         void Resolver::visit( ReturnStmt *returnStmt ) {
     351        void Resolver::previsit( ReturnStmt *returnStmt ) {
     352                visit_children = false;
    366353                if ( returnStmt->get_expr() ) {
    367354                        CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() );
    368                         Expression *newExpr = findSingleExpression( castExpr, *this );
     355                        Expression *newExpr = findSingleExpression( castExpr, indexer );
    369356                        delete castExpr;
    370357                        returnStmt->set_expr( newExpr );
     
    372359        }
    373360
    374         void Resolver::visit( ThrowStmt *throwStmt ) {
     361        void Resolver::previsit( ThrowStmt *throwStmt ) {
     362                visit_children = false;
    375363                // TODO: Replace *exception type with &exception type.
    376364                if ( throwStmt->get_expr() ) {
    377365                        StructDecl * exception_decl =
    378                                 lookupStruct( "__cfaehm__base_exception_t" );
     366                                indexer.lookupStruct( "__cfaehm__base_exception_t" );
    379367                        assert( exception_decl );
    380368                        Expression * wrapped = new CastExpr(
     
    388376                                        )
    389377                                );
    390                         Expression * newExpr = findSingleExpression( wrapped, *this );
     378                        Expression * newExpr = findSingleExpression( wrapped, indexer );
    391379                        throwStmt->set_expr( newExpr );
    392380                }
    393381        }
    394382
    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 
     383        void Resolver::previsit( CatchStmt *catchStmt ) {
    401384                if ( catchStmt->get_cond() ) {
    402385                        Expression * wrapped = new CastExpr(
     
    404387                                new BasicType( noQualifiers, BasicType::Bool )
    405388                                );
    406                         catchStmt->set_cond( findSingleExpression( wrapped, *this ) );
    407                 }
    408 
    409                 Parent::leaveScope();
     389                        catchStmt->set_cond( findSingleExpression( wrapped, indexer ) );
     390                }
    410391        }
    411392
     
    419400        }
    420401
    421         void Resolver::visit( SingleInit *singleInit ) {
     402        void Resolver::previsit( SingleInit *singleInit ) {
     403                visit_children = false;
    422404                // resolve initialization using the possibilities as determined by the currentObject cursor
    423405                UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
    424                 Expression * newExpr = findSingleExpression( untyped, *this );
     406                Expression * newExpr = findSingleExpression( untyped, indexer );
    425407                InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr );
    426408
     
    461443        }
    462444
    463         void Resolver::visit( ListInit * listInit ) {
     445        void Resolver::previsit( ListInit * listInit ) {
     446                visit_children = false;
    464447                // move cursor into brace-enclosed initializer-list
    465448                currentObject.enterListInit();
     
    472455                        Initializer * init = std::get<1>(p);
    473456                        newDesignations.push_back( currentObject.findNext( des ) );
    474                         init->accept( *this );
     457                        init->accept( *visitor );
    475458                }
    476459                // set the set of 'resolved' designations and leave the brace-enclosed initializer-list
     
    501484                delete ctorInit->get_dtor();
    502485                ctorInit->set_dtor( NULL );
    503                 maybeAccept( ctorInit->get_init(), *this );
     486                maybeAccept( ctorInit->get_init(), *visitor );
    504487        }
    505488
     
    507490        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ) {
    508491                assert( ctorInit );
    509                 Resolver resolver( indexer );
     492                PassVisitor<Resolver> resolver( indexer );
    510493                ctorInit->accept( resolver );
    511494        }
     
    513496        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ) {
    514497                assert( stmtExpr );
    515                 Resolver resolver( indexer );
     498                PassVisitor<Resolver> resolver( indexer );
    516499                stmtExpr->accept( resolver );
    517500        }
    518501
    519         void Resolver::visit( ConstructorInit *ctorInit ) {
     502        void Resolver::previsit( ConstructorInit *ctorInit ) {
     503                visit_children = false;
    520504                // xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit
    521                 maybeAccept( ctorInit->get_ctor(), *this );
    522                 maybeAccept( ctorInit->get_dtor(), *this );
     505                maybeAccept( ctorInit->get_ctor(), *visitor );
     506                maybeAccept( ctorInit->get_dtor(), *visitor );
    523507
    524508                // found a constructor - can get rid of C-style initializer
  • src/SymTab/Indexer.cc

    r3e3d923 r5f782f7  
    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();
    577232        }
    578233
     
    762417
    763418        void Indexer::addId( DeclarationWithType *decl ) {
     419                debugPrint( "Adding Id " << decl->name << std::endl );
    764420                makeWritable();
    765421
     
    811467
    812468        void Indexer::addType( NamedTypeDecl *decl ) {
     469                debugPrint( "Adding type " << decl->name << std::endl );
    813470                makeWritable();
    814471
     
    838495
    839496        void Indexer::addStruct( const std::string &id ) {
     497                debugPrint( "Adding fwd decl for struct " << id << std::endl );
    840498                addStruct( new StructDecl( id ) );
    841499        }
    842500
    843501        void Indexer::addStruct( StructDecl *decl ) {
     502                debugPrint( "Adding struct " << decl->name << std::endl );
    844503                makeWritable();
    845504
     
    860519
    861520        void Indexer::addEnum( EnumDecl *decl ) {
     521                debugPrint( "Adding enum " << decl->name << std::endl );
    862522                makeWritable();
    863523
     
    878538
    879539        void Indexer::addUnion( const std::string &id ) {
     540                debugPrint( "Adding fwd decl for union " << id << std::endl );
    880541                addUnion( new UnionDecl( id ) );
    881542        }
    882543
    883544        void Indexer::addUnion( UnionDecl *decl ) {
     545                debugPrint( "Adding union " << decl->name << std::endl );
    884546                makeWritable();
    885547
     
    900562
    901563        void Indexer::addTrait( TraitDecl *decl ) {
     564                debugPrint( "Adding trait " << decl->name << std::endl );
    902565                makeWritable();
    903566
  • src/SymTab/Indexer.h

    r3e3d923 r5f782f7  
    2424
    2525namespace SymTab {
    26         class Indexer : public Visitor {
     26        class Indexer {
    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 );
    8635
    8736                // when using an indexer manually (e.g., within a mutator traversal), it is necessary to tell the indexer
  • src/main.cc

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