Changes in src/ResolvExpr/Resolver.cc [8b11840:0a22cda]
- File:
-
- 1 edited
-
src/ResolvExpr/Resolver.cc (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r8b11840 r0a22cda 40 40 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 41 41 #include "typeops.h" // for extractResultType 42 #include "Unify.h" // for unify 42 43 43 44 using namespace std; … … 52 53 void previsit( FunctionDecl *functionDecl ); 53 54 void postvisit( FunctionDecl *functionDecl ); 54 void previsit( ObjectDecl * functionDecl );55 void previsit( ObjectDecl *objectDecll ); 55 56 void previsit( TypeDecl *typeDecl ); 56 57 void previsit( EnumDecl * enumDecl ); … … 71 72 void previsit( ThrowStmt *throwStmt ); 72 73 void previsit( CatchStmt *catchStmt ); 74 void previsit( WaitForStmt * stmt ); 73 75 74 76 void previsit( SingleInit *singleInit ); … … 107 109 108 110 namespace { 109 void finishExpr( Expression *expr, const TypeEnvironment &env ) {110 expr-> set_env( new TypeSubstitution );111 void finishExpr( Expression *expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) { 112 expr->env = oldenv ? oldenv->clone() : new TypeSubstitution; 111 113 env.makeSubstitution( *expr->get_env() ); 112 114 } 115 116 void removeExtraneousCast( Expression *& expr, const SymTab::Indexer & indexer ) { 117 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 118 if ( ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) { 119 // cast is to the same type as its argument, so it's unnecessary -- remove it 120 expr = castExpr->arg; 121 castExpr->arg = nullptr; 122 std::swap( expr->env, castExpr->env ); 123 delete castExpr; 124 } 125 } 126 } 113 127 } // namespace 114 128 115 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {129 void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) { 116 130 global_renamer.reset(); 117 131 TypeEnvironment env; 118 132 Expression *newExpr = resolveInVoidContext( untyped, indexer, env ); 119 finishExpr( newExpr, env ); 120 return newExpr; 133 finishExpr( newExpr, env, untyped->env ); 134 delete untyped; 135 untyped = newExpr; 136 } 137 138 void findSingleExpression( Expression *&untyped, const SymTab::Indexer &indexer ) { 139 if ( ! untyped ) return; 140 TypeEnvironment env; 141 AlternativeFinder finder( indexer, env ); 142 finder.find( untyped ); 143 #if 0 144 if ( finder.get_alternatives().size() != 1 ) { 145 std::cerr << "untyped expr is "; 146 untyped->print( std::cerr ); 147 std::cerr << std::endl << "alternatives are:"; 148 for ( const Alternative & alt : finder.get_alternatives() ) { 149 alt.print( std::cerr ); 150 } // for 151 } // if 152 #endif 153 assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." ); 154 Alternative &choice = finder.get_alternatives().front(); 155 Expression *newExpr = choice.expr->clone(); 156 finishExpr( newExpr, choice.env, untyped->env ); 157 delete untyped; 158 untyped = newExpr; 159 } 160 161 void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer ) { 162 assert( untyped && type ); 163 untyped = new CastExpr( untyped, type ); 164 findSingleExpression( untyped, indexer ); 165 removeExtraneousCast( untyped, indexer ); 121 166 } 122 167 123 168 namespace { 124 Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {125 TypeEnvironment env;126 AlternativeFinder finder( indexer, env );127 finder.find( untyped );128 #if 0129 if ( finder.get_alternatives().size() != 1 ) {130 std::cout << "untyped expr is ";131 untyped->print( std::cout );132 std::cout << std::endl << "alternatives are:";133 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {134 i->print( std::cout );135 } // for136 } // if137 #endif138 assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );139 Alternative &choice = finder.get_alternatives().front();140 Expression *newExpr = choice.expr->clone();141 finishExpr( newExpr, choice.env );142 return newExpr;143 }144 145 169 bool isIntegralType( Type *type ) { 146 170 if ( dynamic_cast< EnumInstType * >( type ) ) { … … 155 179 } 156 180 157 Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {181 void findIntegralExpression( Expression *& untyped, const SymTab::Indexer &indexer ) { 158 182 TypeEnvironment env; 159 183 AlternativeFinder finder( indexer, env ); … … 184 208 throw SemanticError( "No interpretations for case control expression", untyped ); 185 209 } // if 186 finishExpr( newExpr, *newEnv ); 187 return newExpr; 210 finishExpr( newExpr, *newEnv, untyped->env ); 211 delete untyped; 212 untyped = newExpr; 188 213 } 189 214 … … 210 235 void Resolver::handlePtrType( PtrType * type ) { 211 236 if ( type->get_dimension() ) { 212 CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() ); 213 Expression *newExpr = findSingleExpression( castExpr, indexer ); 214 delete type->get_dimension(); 215 type->set_dimension( newExpr ); 237 findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer ); 216 238 } 217 239 } … … 243 265 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() ); 244 266 } 245 246 267 247 268 void Resolver::postvisit( FunctionDecl *functionDecl ) { … … 267 288 void Resolver::previsit( ExprStmt *exprStmt ) { 268 289 visit_children = false; 269 assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" ); 270 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer ); 271 delete exprStmt->get_expr(); 272 exprStmt->set_expr( newExpr ); 290 assertf( exprStmt->expr, "ExprStmt has null Expression in resolver" ); 291 findVoidExpression( exprStmt->expr, indexer ); 273 292 } 274 293 275 294 void Resolver::previsit( AsmExpr *asmExpr ) { 276 295 visit_children = false; 277 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer ); 278 delete asmExpr->get_operand(); 279 asmExpr->set_operand( newExpr ); 296 findVoidExpression( asmExpr->operand, indexer ); 280 297 if ( asmExpr->get_inout() ) { 281 newExpr = findVoidExpression( asmExpr->get_inout(), indexer ); 282 delete asmExpr->get_inout(); 283 asmExpr->set_inout( newExpr ); 298 findVoidExpression( asmExpr->inout, indexer ); 284 299 } // if 285 300 } … … 292 307 293 308 void Resolver::previsit( IfStmt *ifStmt ) { 294 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), indexer ); 295 delete ifStmt->get_condition(); 296 ifStmt->set_condition( newExpr ); 309 findSingleExpression( ifStmt->condition, indexer ); 297 310 } 298 311 299 312 void Resolver::previsit( WhileStmt *whileStmt ) { 300 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer ); 301 delete whileStmt->get_condition(); 302 whileStmt->set_condition( newExpr ); 313 findSingleExpression( whileStmt->condition, indexer ); 303 314 } 304 315 305 316 void Resolver::previsit( ForStmt *forStmt ) { 306 if ( forStmt->get_condition() ) { 307 Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer ); 308 delete forStmt->get_condition(); 309 forStmt->set_condition( newExpr ); 317 if ( forStmt->condition ) { 318 findSingleExpression( forStmt->condition, indexer ); 310 319 } // if 311 320 312 if ( forStmt->get_increment() ) { 313 Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer ); 314 delete forStmt->get_increment(); 315 forStmt->set_increment( newExpr ); 321 if ( forStmt->increment ) { 322 findVoidExpression( forStmt->increment, indexer ); 316 323 } // if 317 324 } … … 319 326 void Resolver::previsit( SwitchStmt *switchStmt ) { 320 327 GuardValue( currentObject ); 321 Expression *newExpr; 322 newExpr = findIntegralExpression( switchStmt->get_condition(), indexer ); 323 delete switchStmt->get_condition(); 324 switchStmt->set_condition( newExpr ); 325 326 currentObject = CurrentObject( newExpr->get_result() ); 328 findIntegralExpression( switchStmt->condition, indexer ); 329 330 currentObject = CurrentObject( switchStmt->condition->result ); 327 331 } 328 332 … … 331 335 std::list< InitAlternative > initAlts = currentObject.getOptions(); 332 336 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." ); 333 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() ); 334 Expression * newExpr = findSingleExpression( castExpr, indexer ); 335 castExpr = strict_dynamic_cast< CastExpr * >( newExpr ); 336 caseStmt->set_condition( castExpr->get_arg() ); 337 castExpr->set_arg( nullptr ); 337 // must remove cast from case statement because RangeExpr cannot be cast. 338 Expression * newExpr = new CastExpr( caseStmt->condition, initAlts.front().type->clone() ); 339 findSingleExpression( newExpr, indexer ); 340 CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( newExpr ); 341 caseStmt->condition = castExpr->arg; 342 castExpr->arg = nullptr; 338 343 delete castExpr; 339 344 } … … 344 349 // must resolve the argument for a computed goto 345 350 if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement 346 if ( Expression * arg = branchStmt->get_computedTarget() ) { 347 VoidType v = Type::Qualifiers(); // cast to void * for the alternative finder 348 PointerType pt( Type::Qualifiers(), v.clone() ); 349 CastExpr * castExpr = new CastExpr( arg, pt.clone() ); 350 Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression 351 branchStmt->set_target( newExpr ); 351 if ( branchStmt->computedTarget ) { 352 // computed goto argument is void * 353 findSingleExpression( branchStmt->computedTarget, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), indexer ); 352 354 } // if 353 355 } // if … … 356 358 void Resolver::previsit( ReturnStmt *returnStmt ) { 357 359 visit_children = false; 358 if ( returnStmt->get_expr() ) { 359 CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() ); 360 Expression *newExpr = findSingleExpression( castExpr, indexer ); 361 delete castExpr; 362 returnStmt->set_expr( newExpr ); 360 if ( returnStmt->expr ) { 361 findSingleExpression( returnStmt->expr, functionReturn->clone(), indexer ); 363 362 } // if 364 363 } … … 371 370 indexer.lookupStruct( "__cfaehm__base_exception_t" ); 372 371 assert( exception_decl ); 373 Expression * wrapped = new CastExpr( 374 throwStmt->get_expr(), 375 new PointerType( 376 noQualifiers, 377 new StructInstType( 378 noQualifiers, 379 exception_decl 380 ) 381 ) 382 ); 383 Expression * newExpr = findSingleExpression( wrapped, indexer ); 384 throwStmt->set_expr( newExpr ); 372 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) ); 373 findSingleExpression( throwStmt->expr, exceptType, indexer ); 385 374 } 386 375 } 387 376 388 377 void Resolver::previsit( CatchStmt *catchStmt ) { 389 if ( catchStmt->get_cond() ) { 390 Expression * wrapped = new CastExpr( 391 catchStmt->get_cond(), 392 new BasicType( noQualifiers, BasicType::Bool ) 393 ); 394 catchStmt->set_cond( findSingleExpression( wrapped, indexer ) ); 378 if ( catchStmt->cond ) { 379 findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer ); 380 } 381 } 382 383 template< typename iterator_t > 384 inline bool advance_to_mutex( iterator_t & it, const iterator_t & end ) { 385 while( it != end && !(*it)->get_type()->get_mutex() ) { 386 it++; 387 } 388 389 return it != end; 390 } 391 392 void Resolver::previsit( WaitForStmt * stmt ) { 393 visit_children = false; 394 395 // Resolve all clauses first 396 for( auto& clause : stmt->clauses ) { 397 398 TypeEnvironment env; 399 AlternativeFinder funcFinder( indexer, env ); 400 401 // Find all alternatives for a function in canonical form 402 funcFinder.findWithAdjustment( clause.target.function ); 403 404 if ( funcFinder.get_alternatives().empty() ) { 405 stringstream ss; 406 ss << "Use of undeclared indentifier '"; 407 ss << strict_dynamic_cast<NameExpr*>( clause.target.function )->name; 408 ss << "' in call to waitfor"; 409 throw SemanticError( ss.str() ); 410 } 411 412 // Find all alternatives for all arguments in canonical form 413 std::list< AlternativeFinder > argAlternatives; 414 funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) ); 415 416 // List all combinations of arguments 417 std::list< AltList > possibilities; 418 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) ); 419 420 AltList func_candidates; 421 std::vector< AltList > args_candidates; 422 423 // For every possible function : 424 // try matching the arguments to the parameters 425 // not the other way around because we have more arguments than parameters 426 SemanticError errors; 427 for ( Alternative & func : funcFinder.get_alternatives() ) { 428 try { 429 PointerType * pointer = dynamic_cast< PointerType* >( func.expr->get_result()->stripReferences() ); 430 if( !pointer ) { 431 throw SemanticError( "candidate not viable: not a pointer type\n", func.expr->get_result() ); 432 } 433 434 FunctionType * function = dynamic_cast< FunctionType* >( pointer->get_base() ); 435 if( !function ) { 436 throw SemanticError( "candidate not viable: not a function type\n", pointer->get_base() ); 437 } 438 439 440 { 441 auto param = function->parameters.begin(); 442 auto param_end = function->parameters.end(); 443 444 if( !advance_to_mutex( param, param_end ) ) { 445 throw SemanticError("candidate function not viable: no mutex parameters\n", function); 446 } 447 } 448 449 Alternative newFunc( func ); 450 // Strip reference from function 451 referenceToRvalueConversion( newFunc.expr ); 452 453 // For all the set of arguments we have try to match it with the parameter of the current function alternative 454 for ( auto & argsList : possibilities ) { 455 456 try { 457 // Declare data structures need for resolution 458 OpenVarSet openVars; 459 AssertionSet resultNeed, resultHave; 460 TypeEnvironment resultEnv; 461 462 // Load type variables from arguemnts into one shared space 463 simpleCombineEnvironments( argsList.begin(), argsList.end(), resultEnv ); 464 465 // Make sure we don't widen any existing bindings 466 for ( auto & i : resultEnv ) { 467 i.allowWidening = false; 468 } 469 470 // Find any unbound type variables 471 resultEnv.extractOpenVars( openVars ); 472 473 auto param = function->parameters.begin(); 474 auto param_end = function->parameters.end(); 475 476 // For every arguments of its set, check if it matches one of the parameter 477 // The order is important 478 for( auto & arg : argsList ) { 479 480 // Ignore non-mutex arguments 481 if( !advance_to_mutex( param, param_end ) ) { 482 // We ran out of parameters but still have arguments 483 // this function doesn't match 484 throw SemanticError("candidate function not viable: too many mutex arguments\n", function); 485 } 486 487 // Check if the argument matches the parameter type in the current scope 488 if( ! unify( (*param)->get_type(), arg.expr->get_result(), resultEnv, resultNeed, resultHave, openVars, this->indexer ) ) { 489 // Type doesn't match 490 stringstream ss; 491 ss << "candidate function not viable: no known convertion from '"; 492 arg.expr->get_result()->print( ss ); 493 ss << "' to '"; 494 (*param)->get_type()->print( ss ); 495 ss << "'\n"; 496 throw SemanticError(ss.str(), function); 497 } 498 499 param++; 500 } 501 502 // All arguments match ! 503 504 // Check if parameters are missing 505 if( advance_to_mutex( param, param_end ) ) { 506 // We ran out of arguments but still have parameters left 507 // this function doesn't match 508 throw SemanticError("candidate function not viable: too few mutex arguments\n", function); 509 } 510 511 // All parameters match ! 512 513 // Finish the expressions to tie in the proper environments 514 finishExpr( newFunc.expr, resultEnv ); 515 for( Alternative & alt : argsList ) { 516 finishExpr( alt.expr, resultEnv ); 517 } 518 519 // This is a match store it and save it for later 520 func_candidates.push_back( newFunc ); 521 args_candidates.push_back( argsList ); 522 523 } 524 catch( SemanticError &e ) { 525 errors.append( e ); 526 } 527 } 528 } 529 catch( SemanticError &e ) { 530 errors.append( e ); 531 } 532 } 533 534 // Make sure we got the right number of arguments 535 if( func_candidates.empty() ) { SemanticError top( "No alternatives for function in call to waitfor" ); top.append( errors ); throw top; } 536 if( args_candidates.empty() ) { SemanticError top( "No alternatives for arguments in call to waitfor" ); top.append( errors ); throw top; } 537 if( func_candidates.size() > 1 ) { SemanticError top( "Ambiguous function in call to waitfor" ); top.append( errors ); throw top; } 538 if( args_candidates.size() > 1 ) { SemanticError top( "Ambiguous arguments in call to waitfor" ); top.append( errors ); throw top; } 539 540 541 // Swap the results from the alternative with the unresolved values. 542 // Alternatives will handle deletion on destruction 543 std::swap( clause.target.function, func_candidates.front().expr ); 544 for( auto arg_pair : group_iterate( clause.target.arguments, args_candidates.front() ) ) { 545 std::swap ( std::get<0>( arg_pair), std::get<1>( arg_pair).expr ); 546 } 547 548 // Resolve the conditions as if it were an IfStmt 549 // Resolve the statments normally 550 findSingleExpression( clause.condition, this->indexer ); 551 clause.statement->accept( *visitor ); 552 } 553 554 555 if( stmt->timeout.statement ) { 556 // Resolve the timeout as an size_t for now 557 // Resolve the conditions as if it were an IfStmt 558 // Resolve the statments normally 559 findSingleExpression( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer ); 560 findSingleExpression( stmt->timeout.condition, this->indexer ); 561 stmt->timeout.statement->accept( *visitor ); 562 } 563 564 if( stmt->orelse.statement ) { 565 // Resolve the conditions as if it were an IfStmt 566 // Resolve the statments normally 567 findSingleExpression( stmt->orelse.condition, this->indexer ); 568 stmt->orelse.statement->accept( *visitor ); 395 569 } 396 570 } … … 408 582 visit_children = false; 409 583 // resolve initialization using the possibilities as determined by the currentObject cursor 410 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );411 Expression * newExpr = findSingleExpression( untyped, indexer );584 Expression * newExpr = new UntypedInitExpr( singleInit->value, currentObject.getOptions() ); 585 findSingleExpression( newExpr, indexer ); 412 586 InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr ); 413 587 … … 416 590 417 591 // discard InitExpr wrapper and retain relevant pieces 418 newExpr = initExpr->get_expr(); 419 newExpr->set_env( initExpr->get_env() ); 420 initExpr->set_expr( nullptr ); 421 initExpr->set_env( nullptr ); 592 newExpr = initExpr->expr; 593 initExpr->expr = nullptr; 594 std::swap( initExpr->env, newExpr->env ); 422 595 delete initExpr; 423 596 424 597 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions) 425 598 Type * initContext = currentObject.getCurrentType(); 599 600 removeExtraneousCast( newExpr, indexer ); 426 601 427 602 // check if actual object's type is char[] … … 431 606 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 432 607 if ( isCharType( pt->get_base() ) ) { 433 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 434 CastExpr *ce = strict_dynamic_cast< CastExpr * >( newExpr ); 435 newExpr = ce->get_arg(); 436 ce->set_arg( nullptr ); 437 delete ce; 608 if ( CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ) ) { 609 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 610 newExpr = ce->get_arg(); 611 ce->set_arg( nullptr ); 612 std::swap( ce->env, newExpr->env ); 613 delete ce; 614 } 438 615 } 439 616 } … … 442 619 443 620 // set initializer expr to resolved express 444 singleInit-> set_value( newExpr );621 singleInit->value = newExpr; 445 622 446 623 // move cursor to next object in preparation for next initializer
Note:
See TracChangeset
for help on using the changeset viewer.