Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    rc5283ba r2a6292d  
    3030#include "RenameVars.h"                  // for RenameVars, global_renamer
    3131#include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment
    32 #include "ResolveTypeof.h"               // for resolveTypeof
    3332#include "Resolver.h"
    3433#include "SymTab/Autogen.h"              // for SizeType
     
    5756                void postvisit( FunctionDecl *functionDecl );
    5857                void previsit( ObjectDecl *objectDecll );
    59                 void previsit( TypeDecl *typeDecl );
    6058                void previsit( EnumDecl * enumDecl );
    6159                void previsit( StaticAssertDecl * assertDecl );
     
    7775                void previsit( CatchStmt *catchStmt );
    7876                void previsit( WaitForStmt * stmt );
    79                 void previsit( WithStmt * withStmt );
    8077
    8178                void previsit( SingleInit *singleInit );
     
    8885                void handlePtrType( PtrType * type );
    8986
    90                 void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts );
    9187                void fallbackInit( ConstructorInit * ctorInit );
    9288
     
    9490                CurrentObject currentObject = nullptr;
    9591                bool inEnumDecl = false;
     92        };
     93
     94        struct ResolveWithExprs : public WithIndexer, public WithGuards, public WithVisitorRef<ResolveWithExprs>, public WithShortCircuiting, public WithStmtsToAdd {
     95                void previsit( FunctionDecl * );
     96                void previsit( WithStmt * );
     97
     98                void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts );
    9699        };
    97100
     
    302305        }
    303306
     307
     308        bool isStructOrUnion( const Alternative & alt ) {
     309                Type * t = alt.expr->result->stripReferences();
     310                return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t );
     311        }
     312
     313        void resolveWithExprs( std::list< Declaration * > & translationUnit ) {
     314                PassVisitor<ResolveWithExprs> resolver;
     315                acceptAll( translationUnit, resolver );
     316        }
     317
     318        void ResolveWithExprs::resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ) {
     319                for ( Expression *& expr : withExprs )  {
     320                        // only struct- and union-typed expressions are viable candidates
     321                        findKindExpression( expr, indexer, "with statement", isStructOrUnion );
     322
     323                        // if with expression might be impure, create a temporary so that it is evaluated once
     324                        if ( Tuples::maybeImpure( expr ) ) {
     325                                static UniqueName tmpNamer( "_with_tmp_" );
     326                                ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) );
     327                                expr = new VariableExpr( tmp );
     328                                newStmts.push_back( new DeclStmt( tmp ) );
     329                                if ( InitTweak::isConstructable( tmp->type ) ) {
     330                                        // generate ctor/dtor and resolve them
     331                                        tmp->init = InitTweak::genCtorInit( tmp );
     332                                        tmp->accept( *visitor );
     333                                }
     334                        }
     335                }
     336        }
     337
     338        void ResolveWithExprs::previsit( WithStmt * withStmt ) {
     339                resolveWithExprs( withStmt->exprs, stmtsToAddBefore );
     340        }
     341
     342        void ResolveWithExprs::previsit( FunctionDecl * functionDecl ) {
     343                {
     344                        // resolve with-exprs with parameters in scope and add any newly generated declarations to the
     345                        // front of the function body.
     346                        auto guard = makeFuncGuard( [this]() { indexer.enterScope(); }, [this](){ indexer.leaveScope(); } );
     347                        indexer.addFunctionType( functionDecl->type );
     348                        std::list< Statement * > newStmts;
     349                        resolveWithExprs( functionDecl->withExprs, newStmts );
     350                        if ( functionDecl->statements ) {
     351                                functionDecl->statements->kids.splice( functionDecl->statements->kids.begin(), newStmts );
     352                        } else {
     353                                assertf( functionDecl->withExprs.empty() && newStmts.empty(), "Function %s without a body has with-clause and/or generated with declarations.", functionDecl->name.c_str() );
     354                        }
     355                }
     356        }
     357
    304358        void Resolver::previsit( ObjectDecl *objectDecl ) {
    305                 Type *new_type = resolveTypeof( objectDecl->get_type(), indexer );
    306                 objectDecl->set_type( new_type );
    307359                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable
    308360                // initContext is changed multiple time because the LHS is analysed twice. The second analysis changes
     
    334386        }
    335387
    336         void Resolver::previsit( TypeDecl *typeDecl ) {
    337                 if ( typeDecl->get_base() ) {
    338                         Type *new_type = resolveTypeof( typeDecl->get_base(), indexer );
    339                         typeDecl->set_base( new_type );
    340                 } // if
    341         }
    342 
    343388        void Resolver::previsit( FunctionDecl *functionDecl ) {
    344389#if 0
     
    347392                std::cerr << std::endl;
    348393#endif
    349                 Type *new_type = resolveTypeof( functionDecl->type, indexer );
    350                 functionDecl->set_type( new_type );
    351394                GuardValue( functionReturn );
    352395                functionReturn = ResolvExpr::extractResultType( functionDecl->type );
    353 
    354                 {
    355                         // resolve with-exprs with parameters in scope and add any newly generated declarations to the
    356                         // front of the function body.
    357                         auto guard = makeFuncGuard( [this]() { indexer.enterScope(); }, [this](){ indexer.leaveScope(); } );
    358                         indexer.addFunctionType( functionDecl->type );
    359                         std::list< Statement * > newStmts;
    360                         resolveWithExprs( functionDecl->withExprs, newStmts );
    361                         if ( functionDecl->statements ) {
    362                                 functionDecl->statements->kids.splice( functionDecl->statements->kids.begin(), newStmts );
    363                         } else {
    364                                 assertf( functionDecl->withExprs.empty() && newStmts.empty(), "Function %s without a body has with-clause and/or generated with declarations.", functionDecl->name.c_str() );
    365                         }
    366                 }
    367396        }
    368397
     
    695724                        stmt->orelse.statement->accept( *visitor );
    696725                }
    697         }
    698 
    699         bool isStructOrUnion( const Alternative & alt ) {
    700                 Type * t = alt.expr->result->stripReferences();
    701                 return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t );
    702         }
    703 
    704         void Resolver::resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ) {
    705                 for ( Expression *& expr : withExprs )  {
    706                         // only struct- and union-typed expressions are viable candidates
    707                         findKindExpression( expr, indexer, "with statement", isStructOrUnion );
    708 
    709                         // if with expression might be impure, create a temporary so that it is evaluated once
    710                         if ( Tuples::maybeImpure( expr ) ) {
    711                                 static UniqueName tmpNamer( "_with_tmp_" );
    712                                 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) );
    713                                 expr = new VariableExpr( tmp );
    714                                 newStmts.push_back( new DeclStmt( tmp ) );
    715                                 if ( InitTweak::isConstructable( tmp->type ) ) {
    716                                         // generate ctor/dtor and resolve them
    717                                         tmp->init = InitTweak::genCtorInit( tmp );
    718                                         tmp->accept( *visitor );
    719                                 }
    720                         }
    721                 }
    722         }
    723 
    724         void Resolver::previsit( WithStmt * withStmt ) {
    725                 resolveWithExprs( withStmt->exprs, stmtsToAddBefore );
    726726        }
    727727
Note: See TracChangeset for help on using the changeset viewer.