Changes in src/ResolvExpr/Resolver.cc [c5283ba:2a6292d]
- File:
-
- 1 edited
-
src/ResolvExpr/Resolver.cc (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
rc5283ba r2a6292d 30 30 #include "RenameVars.h" // for RenameVars, global_renamer 31 31 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 32 #include "ResolveTypeof.h" // for resolveTypeof33 32 #include "Resolver.h" 34 33 #include "SymTab/Autogen.h" // for SizeType … … 57 56 void postvisit( FunctionDecl *functionDecl ); 58 57 void previsit( ObjectDecl *objectDecll ); 59 void previsit( TypeDecl *typeDecl );60 58 void previsit( EnumDecl * enumDecl ); 61 59 void previsit( StaticAssertDecl * assertDecl ); … … 77 75 void previsit( CatchStmt *catchStmt ); 78 76 void previsit( WaitForStmt * stmt ); 79 void previsit( WithStmt * withStmt );80 77 81 78 void previsit( SingleInit *singleInit ); … … 88 85 void handlePtrType( PtrType * type ); 89 86 90 void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts );91 87 void fallbackInit( ConstructorInit * ctorInit ); 92 88 … … 94 90 CurrentObject currentObject = nullptr; 95 91 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 ); 96 99 }; 97 100 … … 302 305 } 303 306 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 304 358 void Resolver::previsit( ObjectDecl *objectDecl ) { 305 Type *new_type = resolveTypeof( objectDecl->get_type(), indexer );306 objectDecl->set_type( new_type );307 359 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable 308 360 // initContext is changed multiple time because the LHS is analysed twice. The second analysis changes … … 334 386 } 335 387 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 } // if341 }342 343 388 void Resolver::previsit( FunctionDecl *functionDecl ) { 344 389 #if 0 … … 347 392 std::cerr << std::endl; 348 393 #endif 349 Type *new_type = resolveTypeof( functionDecl->type, indexer );350 functionDecl->set_type( new_type );351 394 GuardValue( functionReturn ); 352 395 functionReturn = ResolvExpr::extractResultType( functionDecl->type ); 353 354 {355 // resolve with-exprs with parameters in scope and add any newly generated declarations to the356 // 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 }367 396 } 368 397 … … 695 724 stmt->orelse.statement->accept( *visitor ); 696 725 } 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 candidates707 findKindExpression( expr, indexer, "with statement", isStructOrUnion );708 709 // if with expression might be impure, create a temporary so that it is evaluated once710 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 them717 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 );726 726 } 727 727
Note:
See TracChangeset
for help on using the changeset viewer.