Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r2a6292d rc5283ba  
    3030#include "RenameVars.h"                  // for RenameVars, global_renamer
    3131#include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment
     32#include "ResolveTypeof.h"               // for resolveTypeof
    3233#include "Resolver.h"
    3334#include "SymTab/Autogen.h"              // for SizeType
     
    5657                void postvisit( FunctionDecl *functionDecl );
    5758                void previsit( ObjectDecl *objectDecll );
     59                void previsit( TypeDecl *typeDecl );
    5860                void previsit( EnumDecl * enumDecl );
    5961                void previsit( StaticAssertDecl * assertDecl );
     
    7577                void previsit( CatchStmt *catchStmt );
    7678                void previsit( WaitForStmt * stmt );
     79                void previsit( WithStmt * withStmt );
    7780
    7881                void previsit( SingleInit *singleInit );
     
    8588                void handlePtrType( PtrType * type );
    8689
     90                void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts );
    8791                void fallbackInit( ConstructorInit * ctorInit );
    8892
     
    9094                CurrentObject currentObject = nullptr;
    9195                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 );
    9996        };
    10097
     
    305302        }
    306303
    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 ) {
     304        void Resolver::previsit( ObjectDecl *objectDecl ) {
     305                Type *new_type = resolveTypeof( objectDecl->get_type(), indexer );
     306                objectDecl->set_type( new_type );
     307                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable
     308                // initContext is changed multiple time because the LHS is analysed twice. The second analysis changes
     309                // initContext because of a function type can contain object declarations in the return and parameter types. So
     310                // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
     311                // the RHS.
     312                GuardValue( currentObject );
     313                currentObject = CurrentObject( objectDecl->get_type() );
     314                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
     315                        // enumerator initializers should not use the enum type to initialize, since
     316                        // the enum type is still incomplete at this point. Use signed int instead.
     317                        currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     318                }
     319        }
     320
     321        template< typename PtrType >
     322        void Resolver::handlePtrType( PtrType * type ) {
     323                if ( type->get_dimension() ) {
     324                        findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer );
     325                }
     326        }
     327
     328        void Resolver::previsit( ArrayType * at ) {
     329                handlePtrType( at );
     330        }
     331
     332        void Resolver::previsit( PointerType * pt ) {
     333                handlePtrType( pt );
     334        }
     335
     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
     343        void Resolver::previsit( FunctionDecl *functionDecl ) {
     344#if 0
     345                std::cerr << "resolver visiting functiondecl ";
     346                functionDecl->print( std::cerr );
     347                std::cerr << std::endl;
     348#endif
     349                Type *new_type = resolveTypeof( functionDecl->type, indexer );
     350                functionDecl->set_type( new_type );
     351                GuardValue( functionReturn );
     352                functionReturn = ResolvExpr::extractResultType( functionDecl->type );
     353
    343354                {
    344355                        // resolve with-exprs with parameters in scope and add any newly generated declarations to the
     
    354365                        }
    355366                }
    356         }
    357 
    358         void Resolver::previsit( ObjectDecl *objectDecl ) {
    359                 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable
    360                 // initContext is changed multiple time because the LHS is analysed twice. The second analysis changes
    361                 // initContext because of a function type can contain object declarations in the return and parameter types. So
    362                 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
    363                 // the RHS.
    364                 GuardValue( currentObject );
    365                 currentObject = CurrentObject( objectDecl->get_type() );
    366                 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
    367                         // enumerator initializers should not use the enum type to initialize, since
    368                         // the enum type is still incomplete at this point. Use signed int instead.
    369                         currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    370                 }
    371         }
    372 
    373         template< typename PtrType >
    374         void Resolver::handlePtrType( PtrType * type ) {
    375                 if ( type->get_dimension() ) {
    376                         findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer );
    377                 }
    378         }
    379 
    380         void Resolver::previsit( ArrayType * at ) {
    381                 handlePtrType( at );
    382         }
    383 
    384         void Resolver::previsit( PointerType * pt ) {
    385                 handlePtrType( pt );
    386         }
    387 
    388         void Resolver::previsit( FunctionDecl *functionDecl ) {
    389 #if 0
    390                 std::cerr << "resolver visiting functiondecl ";
    391                 functionDecl->print( std::cerr );
    392                 std::cerr << std::endl;
    393 #endif
    394                 GuardValue( functionReturn );
    395                 functionReturn = ResolvExpr::extractResultType( functionDecl->type );
    396367        }
    397368
     
    724695                        stmt->orelse.statement->accept( *visitor );
    725696                }
     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.