Changeset e4d829b for src/ResolvExpr
- Timestamp:
- Jun 20, 2017, 1:19:53 PM (8 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:
- 579263a
- Parents:
- c6d2e93
- git-author:
- Rob Schluntz <rschlunt@…> (06/20/17 13:16:13)
- git-committer:
- Rob Schluntz <rschlunt@…> (06/20/17 13:19:53)
- Location:
- src/ResolvExpr
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rc6d2e93 re4d829b 604 604 // ) 605 605 SymTab::Indexer decls( indexer ); 606 PRINT(607 std::cerr << "============= original indexer" << std::endl;608 indexer.print( std::cerr );609 std::cerr << "============= new indexer" << std::endl;610 decls.print( std::cerr );611 )606 // PRINT( 607 // std::cerr << "============= original indexer" << std::endl; 608 // indexer.print( std::cerr ); 609 // std::cerr << "============= new indexer" << std::endl; 610 // decls.print( std::cerr ); 611 // ) 612 612 addToIndexer( have, decls ); 613 613 AssertionSet newNeed; … … 1182 1182 } 1183 1183 1184 void AlternativeFinder::visit( UntypedInitExpr *initExpr ) { 1185 AlternativeFinder finder( indexer, env ); 1186 finder.findWithAdjustment( initExpr->get_expr() ); 1187 // handle each option like a cast -- should probably push this info into AltFinder as a kind of expression, both to keep common code close and to have less 'reach-in', but more 'push-in' 1188 AltList candidates; 1189 std::cerr << "untyped init expr: " << initExpr << std::endl; 1190 // O(N^2) checks of d-types with e-types 1191 for ( Alternative & alt : finder.get_alternatives() ) { 1192 for ( InitAlternative & initAlt : initExpr->get_initAlts() ) { 1193 AssertionSet needAssertions, haveAssertions; 1194 OpenVarSet openVars; 1195 std::cerr << " " << initAlt.type << " " << initAlt.designation << std::endl; 1196 // It's possible that a cast can throw away some values in a multiply-valued expression. (An example is a 1197 // cast-to-void, which casts from one value to zero.) Figure out the prefix of the subexpression results 1198 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 1199 // to. 1200 int discardedValues = alt.expr->get_result()->size() - initAlt.type->size(); 1201 if ( discardedValues < 0 ) continue; 1202 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 1203 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1204 // unification run for side-effects 1205 unify( initAlt.type, alt.expr->get_result(), alt.env, needAssertions, haveAssertions, openVars, indexer ); 1206 1207 Cost thisCost = castCost( alt.expr->get_result(), initAlt.type, indexer, alt.env ); 1208 if ( thisCost != Cost::infinity ) { 1209 // count one safe conversion for each value that is thrown away 1210 thisCost += Cost( 0, 0, discardedValues ); 1211 candidates.push_back( Alternative( new InitExpr( alt.expr->clone(), initAlt.type->clone(), initAlt.designation->clone() ), alt.env, alt.cost, thisCost ) ); 1212 } 1213 } 1214 } 1215 1216 // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect of copying the 1217 // cvtCost member to the cost member (since the old cost is now irrelevant). Thus, calling findMinCost twice 1218 // selects first based on argument cost, then on conversion cost. 1219 AltList minArgCost; 1220 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) ); 1221 findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) ); 1222 } 1184 1223 } // namespace ResolvExpr 1185 1224 -
src/ResolvExpr/AlternativeFinder.h
rc6d2e93 re4d829b 73 73 virtual void visit( UniqueExpr *unqExpr ); 74 74 virtual void visit( StmtExpr *stmtExpr ); 75 virtual void visit( UntypedInitExpr *initExpr ); 75 76 /// Runs a new alternative finder on each element in [begin, end) 76 77 /// and writes each alternative finder to out. -
src/ResolvExpr/Resolver.cc
rc6d2e93 re4d829b 14 14 // 15 15 16 #include <iostream> 17 18 #include "Alternative.h" 19 #include "AlternativeFinder.h" 20 #include "CurrentObject.h" 21 #include "RenameVars.h" 16 22 #include "Resolver.h" 17 #include "AlternativeFinder.h"18 #include "Alternative.h"19 #include "RenameVars.h"20 23 #include "ResolveTypeof.h" 21 24 #include "typeops.h" 25 26 #include "SynTree/Expression.h" 27 #include "SynTree/Initializer.h" 22 28 #include "SynTree/Statement.h" 23 29 #include "SynTree/Type.h" 24 #include "SynTree/Expression.h" 25 #include "Sy nTree/Initializer.h"30 31 #include "SymTab/Autogen.h" 26 32 #include "SymTab/Indexer.h" 27 #include "SymTab/Autogen.h" 33 28 34 #include "Common/utility.h" 35 29 36 #include "InitTweak/InitTweak.h" 30 37 31 #include <iostream>32 38 using namespace std; 33 39 … … 39 45 if ( const Resolver * res = dynamic_cast< const Resolver * >( &other ) ) { 40 46 functionReturn = res->functionReturn; 41 initContext = res->initContext;47 currentObject = res->currentObject; 42 48 inEnumDecl = res->inEnumDecl; 43 49 } … … 79 85 80 86 Type * functionReturn = nullptr; 81 Type *initContext = nullptr;87 CurrentObject currentObject = nullptr; 82 88 bool inEnumDecl = false; 83 89 }; … … 186 192 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting 187 193 // the RHS. 188 Type *temp = initContext;189 initContext = new_type;190 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext) ) {194 ValueGuard<CurrentObject> temp( currentObject ); 195 currentObject = CurrentObject( objectDecl->get_type() ); 196 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 191 197 // enumerator initializers should not use the enum type to initialize, since 192 198 // the enum type is still incomplete at this point. Use signed int instead. 193 initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt);199 currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 194 200 } 195 201 Parent::visit( objectDecl ); 196 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext) ) {202 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 197 203 // delete newly created signed int type 198 delete initContext; 199 } 200 initContext = temp; 204 // delete currentObject.getType(); 205 } 201 206 } 202 207 … … 315 320 316 321 void Resolver::visit( SwitchStmt *switchStmt ) { 317 ValueGuard< Type * > oldInitContext( initContext );322 ValueGuard< CurrentObject > oldCurrentObject( currentObject ); 318 323 Expression *newExpr; 319 324 newExpr = findIntegralExpression( switchStmt->get_condition(), *this ); … … 321 326 switchStmt->set_condition( newExpr ); 322 327 323 initContext = newExpr->get_result();328 currentObject = CurrentObject( newExpr->get_result() ); 324 329 Parent::visit( switchStmt ); 325 330 } … … 327 332 void Resolver::visit( CaseStmt *caseStmt ) { 328 333 if ( caseStmt->get_condition() ) { 329 assert( initContext ); 330 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initContext->clone() ); 334 std::list< InitAlternative > initAlts = currentObject.getOptions(); 335 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." ); 336 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() ); 331 337 Expression * newExpr = findSingleExpression( castExpr, *this ); 332 338 castExpr = safe_dynamic_cast< CastExpr * >( newExpr ); … … 369 375 } 370 376 377 template< typename Aggr > 378 void lookupDesignation( Aggr * aggr, const std::list< Expression > & designators ) { 379 380 } 381 371 382 void Resolver::visit( SingleInit *singleInit ) { 372 if ( singleInit->get_value() ) { 373 // // find all the d's 374 // std::list<Expression *> &designators = singleInit->get_designators(); 375 // std::list<Type *> types1{ initContext }, types2; 376 // for ( Expression * expr: designators ) { 377 // cerr << expr << endl; 378 // if ( NameExpr * nexpr = dynamic_cast<NameExpr *>( expr ) ) { 379 // for ( Type * type: types1 ) { 380 // cerr << type << endl; 381 // ReferenceToType * fred = dynamic_cast<ReferenceToType *>(type); 382 // std::list<Declaration *> members; 383 // if ( fred ) { 384 // fred->lookup( nexpr->get_name(), members ); // concatenate identical field name 385 // for ( Declaration * mem: members ) { 386 // if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>(mem) ) { 387 // types2.push_back( dwt->get_type() ); 388 // } // if 389 // } // for 390 // } // if 391 // } // for 392 // types1 = types2; 393 // types2.clear(); 394 // } // if 395 // } // for 396 // // for ( Type * type: types1 ) { 397 // // cerr << type << endl; 398 // // } // for 399 400 // // O(N^2) checks of d-types with f-types 401 // // find the minimum cost 402 CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() ); 403 Expression *newExpr = findSingleExpression( castExpr, *this ); 404 delete castExpr; 405 singleInit->set_value( newExpr ); 406 407 // check if initializing type is char[] 408 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) { 409 if ( isCharType( at->get_base() ) ) { 410 // check if the resolved type is char * 411 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 412 if ( isCharType( pt->get_base() ) ) { 413 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 414 CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ); 415 singleInit->set_value( ce->get_arg() ); 416 ce->set_arg( NULL ); 417 delete ce; 418 } 419 } 420 } 421 } 422 } // if 423 } 424 425 template< typename AggrInst > 426 TypeSubstitution makeGenericSubstitutuion( AggrInst * inst ) { 427 assert( inst ); 428 assert( inst->get_baseParameters() ); 429 std::list< TypeDecl * > baseParams = *inst->get_baseParameters(); 430 std::list< Expression * > typeSubs = inst->get_parameters(); 431 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 432 return subs; 433 } 434 435 ReferenceToType * isStructOrUnion( Type * type ) { 436 if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) { 437 return sit; 438 } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) { 439 return uit; 440 } 441 return nullptr; 442 } 443 444 void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) { 445 DeclarationWithType * dt = dynamic_cast< DeclarationWithType * >( dcl ); 446 assert( dt ); 447 // need to substitute for generic types, so that casts are to concrete types 448 initContext = dt->get_type()->clone(); 449 sub.apply( initContext ); 450 451 try { 452 if ( init == initEnd ) return; // stop when there are no more initializers 453 (*init)->accept( *this ); 454 ++init; // made it past an initializer 455 } catch( SemanticError & ) { 456 // need to delve deeper, if you can 457 if ( ReferenceToType * type = isStructOrUnion( initContext ) ) { 458 resolveAggrInit( type, init, initEnd ); 459 } else { 460 // member is not an aggregate type, so can't go any deeper 461 462 // might need to rethink what is being thrown 463 throw; 464 } // if 465 } 466 } 467 468 void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) { 469 if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) { 470 TypeSubstitution sub = makeGenericSubstitutuion( sit ); 471 StructDecl * st = sit->get_baseStruct(); 472 if(st->get_members().empty()) return; 473 // want to resolve each initializer to the members of the struct, 474 // but if there are more initializers than members we should stop 475 list< Declaration * >::iterator it = st->get_members().begin(); 476 for ( ; it != st->get_members().end(); ++it) { 477 resolveSingleAggrInit( *it, init, initEnd, sub ); 478 } 479 } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) { 480 TypeSubstitution sub = makeGenericSubstitutuion( uit ); 481 UnionDecl * un = uit->get_baseUnion(); 482 if(un->get_members().empty()) return; 483 // only resolve to the first member of a union 484 resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub ); 485 } // if 486 } 383 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() ); 384 Expression * newExpr = findSingleExpression( untyped, *this ); 385 InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr ); 386 singleInit->set_value( new CastExpr( initExpr->get_expr()->clone(), initExpr->get_result()->clone() ) ); 387 currentObject.setNext( initExpr->get_designation() ); 388 currentObject.increment(); 389 delete initExpr; 390 391 // // check if initializing type is char[] 392 // if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) { 393 // if ( isCharType( at->get_base() ) ) { 394 // // check if the resolved type is char * 395 // if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 396 // if ( isCharType( pt->get_base() ) ) { 397 // // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 398 // CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ); 399 // singleInit->set_value( ce->get_arg() ); 400 // ce->set_arg( NULL ); 401 // delete ce; 402 // } 403 // } 404 // } 405 // } 406 } 407 408 // template< typename AggrInst > 409 // TypeSubstitution makeGenericSubstitution( AggrInst * inst ) { 410 // assert( inst ); 411 // assert( inst->get_baseParameters() ); 412 // std::list< TypeDecl * > baseParams = *inst->get_baseParameters(); 413 // std::list< Expression * > typeSubs = inst->get_parameters(); 414 // TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 415 // return subs; 416 // } 417 418 // ReferenceToType * isStructOrUnion( Type * type ) { 419 // if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) { 420 // return sit; 421 // } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) { 422 // return uit; 423 // } 424 // return nullptr; 425 // } 426 427 // void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) { 428 // ObjectDecl * obj = dynamic_cast< ObjectDecl * >( dcl ); 429 // assert( obj ); 430 // // need to substitute for generic types, so that casts are to concrete types 431 // currentObject = obj->clone(); // xxx - delete this 432 // sub.apply( currentObject ); 433 434 // try { 435 // if ( init == initEnd ) return; // stop when there are no more initializers 436 // (*init)->accept( *this ); 437 // ++init; // made it past an initializer 438 // } catch( SemanticError & ) { 439 // // need to delve deeper, if you can 440 // if ( ReferenceToType * type = isStructOrUnion( currentObject->get_type() ) ) { 441 // resolveAggrInit( type, init, initEnd ); 442 // } else { 443 // // member is not an aggregate type, so can't go any deeper 444 445 // // might need to rethink what is being thrown 446 // throw; 447 // } // if 448 // } 449 // } 450 451 // void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) { 452 // if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) { 453 // TypeSubstitution sub = makeGenericSubstitution( sit ); 454 // StructDecl * st = sit->get_baseStruct(); 455 // if(st->get_members().empty()) return; 456 // // want to resolve each initializer to the members of the struct, 457 // // but if there are more initializers than members we should stop 458 // list< Declaration * >::iterator it = st->get_members().begin(); 459 // for ( ; it != st->get_members().end(); ++it) { 460 // resolveSingleAggrInit( *it, init, initEnd, sub ); 461 // } 462 // } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) { 463 // TypeSubstitution sub = makeGenericSubstitution( uit ); 464 // UnionDecl * un = uit->get_baseUnion(); 465 // if(un->get_members().empty()) return; 466 // // only resolve to the first member of a union 467 // resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub ); 468 // } // if 469 // } 487 470 488 471 void Resolver::visit( ListInit * listInit ) { 489 InitIterator iter = listInit->begin(); 490 InitIterator end = listInit->end(); 491 492 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) { 493 // resolve each member to the base type of the array 494 for ( ; iter != end; ++iter ) { 495 initContext = at->get_base(); 496 (*iter)->accept( *this ); 497 } // for 498 } else if ( TupleType * tt = dynamic_cast< TupleType * > ( initContext ) ) { 499 for ( Type * t : *tt ) { 500 if ( iter == end ) break; 501 initContext = t; 502 (*iter++)->accept( *this ); 503 } 504 } else if ( ReferenceToType * type = isStructOrUnion( initContext ) ) { 505 resolveAggrInit( type, iter, end ); 506 } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) { 507 Type * base = tt->get_baseType()->get_base(); 508 if ( base ) { 509 // know the implementation type, so try using that as the initContext 510 initContext = base; 511 visit( listInit ); 512 } else { 513 // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context 514 Parent::visit( listInit ); 515 } 516 } else { 517 assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext ) 518 || dynamic_cast< ZeroType * >( initContext ) || dynamic_cast< OneType * >( initContext ) || dynamic_cast < EnumInstType * > ( initContext ) ); 519 // basic types are handled here 520 Parent::visit( listInit ); 521 } 522 523 #if 0 524 if ( ArrayType *at = dynamic_cast<ArrayType*>(initContext) ) { 525 std::list<Initializer *>::iterator iter( listInit->begin_initializers() ); 526 for ( ; iter != listInit->end_initializers(); ++iter ) { 527 initContext = at->get_base(); 528 (*iter)->accept( *this ); 529 } // for 530 } else if ( StructInstType *st = dynamic_cast<StructInstType*>(initContext) ) { 531 StructDecl *baseStruct = st->get_baseStruct(); 532 std::list<Declaration *>::iterator iter1( baseStruct->get_members().begin() ); 533 std::list<Initializer *>::iterator iter2( listInit->begin_initializers() ); 534 for ( ; iter1 != baseStruct->get_members().end() && iter2 != listInit->end_initializers(); ++iter2 ) { 535 if ( (*iter2)->get_designators().empty() ) { 536 DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *iter1 ); 537 initContext = dt->get_type(); 538 (*iter2)->accept( *this ); 539 ++iter1; 540 } else { 541 StructDecl *st = baseStruct; 542 iter1 = st->get_members().begin(); 543 std::list<Expression *>::iterator iter3( (*iter2)->get_designators().begin() ); 544 for ( ; iter3 != (*iter2)->get_designators().end(); ++iter3 ) { 545 NameExpr *key = dynamic_cast<NameExpr *>( *iter3 ); 546 assert( key ); 547 for ( ; iter1 != st->get_members().end(); ++iter1 ) { 548 if ( key->get_name() == (*iter1)->get_name() ) { 549 (*iter1)->print( cout ); 550 cout << key->get_name() << endl; 551 ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 ); 552 assert( fred ); 553 StructInstType *mary = dynamic_cast<StructInstType*>( fred->get_type() ); 554 assert( mary ); 555 st = mary->get_baseStruct(); 556 iter1 = st->get_members().begin(); 557 break; 558 } // if 559 } // for 560 } // for 561 ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 ); 562 assert( fred ); 563 initContext = fred->get_type(); 564 (*listInit->begin_initializers())->accept( *this ); 565 } // if 566 } // for 567 } else if ( UnionInstType *st = dynamic_cast<UnionInstType*>(initContext) ) { 568 DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *st->get_baseUnion()->get_members().begin() ); 569 initContext = dt->get_type(); 570 (*listInit->begin_initializers())->accept( *this ); 571 } // if 572 #endif 472 currentObject.enterListInit(); 473 // xxx - fix this so that the list isn't copied, iterator should be used to change current element 474 std::list<Designation *> newDesignations; 475 for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) { 476 Designation * des = std::get<0>(p); 477 Initializer * init = std::get<1>(p); 478 newDesignations.push_back( currentObject.findNext( des ) ); 479 init->accept( *this ); 480 } 481 listInit->get_designations() = newDesignations; // xxx - memory management 482 currentObject.exitListInit(); 483 484 // } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) { 485 // Type * base = tt->get_baseType()->get_base(); 486 // if ( base ) { 487 // // know the implementation type, so try using that as the initContext 488 // ObjectDecl tmpObj( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, base->clone(), nullptr ); 489 // currentObject = &tmpObj; 490 // visit( listInit ); 491 // } else { 492 // // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context 493 // Parent::visit( listInit ); 494 // } 495 // } else { 573 496 } 574 497 -
src/ResolvExpr/module.mk
rc6d2e93 re4d829b 6 6 ## file "LICENCE" distributed with Cforall. 7 7 ## 8 ## module.mk -- 8 ## module.mk -- 9 9 ## 10 10 ## Author : Richard C. Bilson … … 31 31 ResolvExpr/PolyCost.cc \ 32 32 ResolvExpr/Occurs.cc \ 33 ResolvExpr/TypeEnvironment.cc 33 ResolvExpr/TypeEnvironment.cc \ 34 ResolvExpr/CurrentObject.cc
Note:
See TracChangeset
for help on using the changeset viewer.