Changes in src/ResolvExpr/Resolver.cc [2a6292d:c5283ba]
- File:
-
- 1 edited
-
src/ResolvExpr/Resolver.cc (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r2a6292d rc5283ba 30 30 #include "RenameVars.h" // for RenameVars, global_renamer 31 31 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 32 #include "ResolveTypeof.h" // for resolveTypeof 32 33 #include "Resolver.h" 33 34 #include "SymTab/Autogen.h" // for SizeType … … 56 57 void postvisit( FunctionDecl *functionDecl ); 57 58 void previsit( ObjectDecl *objectDecll ); 59 void previsit( TypeDecl *typeDecl ); 58 60 void previsit( EnumDecl * enumDecl ); 59 61 void previsit( StaticAssertDecl * assertDecl ); … … 75 77 void previsit( CatchStmt *catchStmt ); 76 78 void previsit( WaitForStmt * stmt ); 79 void previsit( WithStmt * withStmt ); 77 80 78 81 void previsit( SingleInit *singleInit ); … … 85 88 void handlePtrType( PtrType * type ); 86 89 90 void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ); 87 91 void fallbackInit( ConstructorInit * ctorInit ); 88 92 … … 90 94 CurrentObject currentObject = nullptr; 91 95 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 );99 96 }; 100 97 … … 305 302 } 306 303 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 343 354 { 344 355 // resolve with-exprs with parameters in scope and add any newly generated declarations to the … … 354 365 } 355 366 } 356 }357 358 void Resolver::previsit( ObjectDecl *objectDecl ) {359 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable360 // initContext is changed multiple time because the LHS is analysed twice. The second analysis changes361 // initContext because of a function type can contain object declarations in the return and parameter types. So362 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting363 // 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, since368 // 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 0390 std::cerr << "resolver visiting functiondecl ";391 functionDecl->print( std::cerr );392 std::cerr << std::endl;393 #endif394 GuardValue( functionReturn );395 functionReturn = ResolvExpr::extractResultType( functionDecl->type );396 367 } 397 368 … … 724 695 stmt->orelse.statement->accept( *visitor ); 725 696 } 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 ); 726 726 } 727 727
Note:
See TracChangeset
for help on using the changeset viewer.