Changeset a4ca48c
- Timestamp:
- Sep 15, 2017, 1:52:35 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 9a707e4e
- Parents:
- aa685db
- git-author:
- Rob Schluntz <rschlunt@…> (09/15/17 12:19:17)
- git-committer:
- Rob Schluntz <rschlunt@…> (09/15/17 13:52:35)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
raa685db ra4ca48c 21 21 #include "Alternative.h" // for Alternative, AltList 22 22 #include "AlternativeFinder.h" // for AlternativeFinder, resolveIn... 23 #include "Common/PassVisitor.h" // for PassVisitor 23 24 #include "Common/SemanticError.h" // for SemanticError 24 25 #include "Common/utility.h" // for ValueGuard, group_iterate … … 43 44 44 45 namespace 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 ); 82 77 private: 83 78 typedef std::list< Initializer * >::iterator InitIterator; … … 96 91 97 92 void resolve( std::list< Declaration * > translationUnit ) { 98 Resolverresolver;93 PassVisitor<Resolver> resolver; 99 94 acceptAll( translationUnit, resolver ); 100 95 } 101 96 97 // used in resolveTypeof 102 98 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) { 103 99 TypeEnvironment env; 104 100 return resolveInVoidContext( expr, indexer, env ); 105 101 } 106 107 102 108 103 namespace { … … 190 185 } 191 186 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 ); 194 189 objectDecl->set_type( new_type ); 195 190 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable … … 198 193 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting 199 194 // the RHS. 200 ValueGuard<CurrentObject> temp( currentObject );195 GuardValue( currentObject ); 201 196 currentObject = CurrentObject( objectDecl->get_type() ); 202 197 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { … … 205 200 currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 206 201 } 207 Parent::visit( objectDecl );208 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {209 // delete newly created signed int type210 // delete currentObject.getType();211 }212 202 } 213 203 … … 216 206 if ( type->get_dimension() ) { 217 207 CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() ); 218 Expression *newExpr = findSingleExpression( castExpr, *this);208 Expression *newExpr = findSingleExpression( castExpr, indexer ); 219 209 delete type->get_dimension(); 220 210 type->set_dimension( newExpr ); … … 222 212 } 223 213 224 void Resolver:: visit( ArrayType * at ) {214 void Resolver::previsit( ArrayType * at ) { 225 215 handlePtrType( at ); 226 Parent::visit( at ); 227 } 228 229 void Resolver::visit( PointerType * pt ) { 216 } 217 218 void Resolver::previsit( PointerType * pt ) { 230 219 handlePtrType( pt ); 231 Parent::visit( pt ); 232 } 233 234 void Resolver::visit( TypeDecl *typeDecl ) { 220 } 221 222 void Resolver::previsit( TypeDecl *typeDecl ) { 235 223 if ( typeDecl->get_base() ) { 236 Type *new_type = resolveTypeof( typeDecl->get_base(), *this);224 Type *new_type = resolveTypeof( typeDecl->get_base(), indexer ); 237 225 typeDecl->set_base( new_type ); 238 226 } // if 239 Parent::visit( typeDecl ); 240 } 241 242 void Resolver::visit( FunctionDecl *functionDecl ) { 227 } 228 229 void Resolver::previsit( FunctionDecl *functionDecl ) { 243 230 #if 0 244 std::c out<< "resolver visiting functiondecl ";245 functionDecl->print( std::c out);246 std::c out<< std::endl;231 std::cerr << "resolver visiting functiondecl "; 232 functionDecl->print( std::cerr ); 233 std::cerr << std::endl; 247 234 #endif 248 Type *new_type = resolveTypeof( functionDecl->get_type(), *this);235 Type *new_type = resolveTypeof( functionDecl->get_type(), indexer ); 249 236 functionDecl->set_type( new_type ); 250 ValueGuard< Type * > oldFunctionReturn( functionReturn );237 GuardValue( functionReturn ); 251 238 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() ); 252 Parent::visit( functionDecl ); 253 239 } 240 241 242 void Resolver::postvisit( FunctionDecl *functionDecl ) { 254 243 // default value expressions have an environment which shouldn't be there and trips up later passes. 255 244 // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently … … 265 254 } 266 255 267 void Resolver:: visit( EnumDecl * enumDecl) {256 void Resolver::previsit( EnumDecl * ) { 268 257 // in case we decide to allow nested enums 269 ValueGuard< bool > oldInEnumDecl( inEnumDecl );258 GuardValue( inEnumDecl ); 270 259 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; 275 264 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 ); 277 266 delete exprStmt->get_expr(); 278 267 exprStmt->set_expr( newExpr ); 279 268 } 280 269 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 ); 283 273 delete asmExpr->get_operand(); 284 274 asmExpr->set_operand( newExpr ); 285 275 if ( asmExpr->get_inout() ) { 286 newExpr = findVoidExpression( asmExpr->get_inout(), *this);276 newExpr = findVoidExpression( asmExpr->get_inout(), indexer ); 287 277 delete asmExpr->get_inout(); 288 278 asmExpr->set_inout( newExpr ); … … 290 280 } 291 281 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 ); 299 290 delete ifStmt->get_condition(); 300 291 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 ); 306 296 delete whileStmt->get_condition(); 307 297 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 ) { 314 301 if ( forStmt->get_condition() ) { 315 Expression * newExpr = findSingleExpression( forStmt->get_condition(), *this);302 Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer ); 316 303 delete forStmt->get_condition(); 317 304 forStmt->set_condition( newExpr ); … … 319 306 320 307 if ( forStmt->get_increment() ) { 321 Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this);308 Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer ); 322 309 delete forStmt->get_increment(); 323 310 forStmt->set_increment( newExpr ); … … 325 312 } 326 313 327 void Resolver:: visit( SwitchStmt *switchStmt ) {328 ValueGuard< CurrentObject > oldCurrentObject( currentObject );314 void Resolver::previsit( SwitchStmt *switchStmt ) { 315 GuardValue( currentObject ); 329 316 Expression *newExpr; 330 newExpr = findIntegralExpression( switchStmt->get_condition(), *this);317 newExpr = findIntegralExpression( switchStmt->get_condition(), indexer ); 331 318 delete switchStmt->get_condition(); 332 319 switchStmt->set_condition( newExpr ); 333 320 334 321 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 ) { 339 325 if ( caseStmt->get_condition() ) { 340 326 std::list< InitAlternative > initAlts = currentObject.getOptions(); 341 327 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." ); 342 328 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() ); 343 Expression * newExpr = findSingleExpression( castExpr, *this);329 Expression * newExpr = findSingleExpression( castExpr, indexer ); 344 330 castExpr = strict_dynamic_cast< CastExpr * >( newExpr ); 345 331 caseStmt->set_condition( castExpr->get_arg() ); … … 347 333 delete castExpr; 348 334 } 349 Parent::visit( caseStmt );350 } 351 352 void Resolver::visit( BranchStmt *branchStmt ) {335 } 336 337 void Resolver::previsit( BranchStmt *branchStmt ) { 338 visit_children = false; 353 339 // must resolve the argument for a computed goto 354 340 if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement … … 357 343 PointerType pt( Type::Qualifiers(), v.clone() ); 358 344 CastExpr * castExpr = new CastExpr( arg, pt.clone() ); 359 Expression * newExpr = findSingleExpression( castExpr, *this); // find best expression345 Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression 360 346 branchStmt->set_target( newExpr ); 361 347 } // if … … 363 349 } 364 350 365 void Resolver::visit( ReturnStmt *returnStmt ) { 351 void Resolver::previsit( ReturnStmt *returnStmt ) { 352 visit_children = false; 366 353 if ( returnStmt->get_expr() ) { 367 354 CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() ); 368 Expression *newExpr = findSingleExpression( castExpr, *this);355 Expression *newExpr = findSingleExpression( castExpr, indexer ); 369 356 delete castExpr; 370 357 returnStmt->set_expr( newExpr ); … … 372 359 } 373 360 374 void Resolver::visit( ThrowStmt *throwStmt ) { 361 void Resolver::previsit( ThrowStmt *throwStmt ) { 362 visit_children = false; 375 363 // TODO: Replace *exception type with &exception type. 376 364 if ( throwStmt->get_expr() ) { 377 365 StructDecl * exception_decl = 378 lookupStruct( "__cfaehm__base_exception_t" );366 indexer.lookupStruct( "__cfaehm__base_exception_t" ); 379 367 assert( exception_decl ); 380 368 Expression * wrapped = new CastExpr( … … 388 376 ) 389 377 ); 390 Expression * newExpr = findSingleExpression( wrapped, *this);378 Expression * newExpr = findSingleExpression( wrapped, indexer ); 391 379 throwStmt->set_expr( newExpr ); 392 380 } 393 381 } 394 382 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 ) { 401 384 if ( catchStmt->get_cond() ) { 402 385 Expression * wrapped = new CastExpr( … … 404 387 new BasicType( noQualifiers, BasicType::Bool ) 405 388 ); 406 catchStmt->set_cond( findSingleExpression( wrapped, *this ) ); 407 } 408 409 Parent::leaveScope(); 389 catchStmt->set_cond( findSingleExpression( wrapped, indexer ) ); 390 } 410 391 } 411 392 … … 419 400 } 420 401 421 void Resolver::visit( SingleInit *singleInit ) { 402 void Resolver::previsit( SingleInit *singleInit ) { 403 visit_children = false; 422 404 // resolve initialization using the possibilities as determined by the currentObject cursor 423 405 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() ); 424 Expression * newExpr = findSingleExpression( untyped, *this);406 Expression * newExpr = findSingleExpression( untyped, indexer ); 425 407 InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr ); 426 408 … … 461 443 } 462 444 463 void Resolver::visit( ListInit * listInit ) { 445 void Resolver::previsit( ListInit * listInit ) { 446 visit_children = false; 464 447 // move cursor into brace-enclosed initializer-list 465 448 currentObject.enterListInit(); … … 472 455 Initializer * init = std::get<1>(p); 473 456 newDesignations.push_back( currentObject.findNext( des ) ); 474 init->accept( * this);457 init->accept( *visitor ); 475 458 } 476 459 // set the set of 'resolved' designations and leave the brace-enclosed initializer-list … … 501 484 delete ctorInit->get_dtor(); 502 485 ctorInit->set_dtor( NULL ); 503 maybeAccept( ctorInit->get_init(), * this);486 maybeAccept( ctorInit->get_init(), *visitor ); 504 487 } 505 488 … … 507 490 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ) { 508 491 assert( ctorInit ); 509 Resolverresolver( indexer );492 PassVisitor<Resolver> resolver( indexer ); 510 493 ctorInit->accept( resolver ); 511 494 } … … 513 496 void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ) { 514 497 assert( stmtExpr ); 515 Resolverresolver( indexer );498 PassVisitor<Resolver> resolver( indexer ); 516 499 stmtExpr->accept( resolver ); 517 500 } 518 501 519 void Resolver::visit( ConstructorInit *ctorInit ) { 502 void Resolver::previsit( ConstructorInit *ctorInit ) { 503 visit_children = false; 520 504 // 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 ); 523 507 524 508 // found a constructor - can get rid of C-style initializer
Note: See TracChangeset
for help on using the changeset viewer.