Changeset 67fa9f9 for src/ResolvExpr
- Timestamp:
- Jul 5, 2017, 10:50:22 AM (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:
- 0614d14
- Parents:
- 11dbfe1 (diff), 307a732 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src/ResolvExpr
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r11dbfe1 r67fa9f9 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; … … 809 809 } 810 810 811 Expression * restructureCast( Expression * argExpr, Type * toType ) { 812 if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) { 813 // Argument expression is a tuple and the target type is not void. Cast each member of the tuple 814 // to its corresponding target type, producing the tuple of those cast expressions. If there are 815 // more components of the tuple than components in the target type, then excess components do not 816 // come out in the result expression (but UniqueExprs ensure that side effects will still be done). 817 if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) { 818 // expressions which may contain side effects require a single unique instance of the expression. 819 argExpr = new UniqueExpr( argExpr ); 820 } 821 std::list< Expression * > componentExprs; 822 for ( unsigned int i = 0; i < toType->size(); i++ ) { 823 // cast each component 824 TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i ); 825 componentExprs.push_back( restructureCast( idx, toType->getComponent( i ) ) ); 826 } 827 delete argExpr; 828 assert( componentExprs.size() > 0 ); 829 // produce the tuple of casts 830 return new TupleExpr( componentExprs ); 831 } else { 832 // handle normally 833 return new CastExpr( argExpr, toType->clone() ); 834 } 835 } 836 811 837 void AlternativeFinder::visit( CastExpr *castExpr ) { 812 838 Type *& toType = castExpr->get_result(); … … 840 866 thisCost += Cost( 0, 0, discardedValues ); 841 867 842 Expression * argExpr = i->expr->clone(); 843 if ( argExpr->get_result()->size() > 1 && ! castExpr->get_result()->isVoid() ) { 844 // Argument expression is a tuple and the target type is not void. Cast each member of the tuple 845 // to its corresponding target type, producing the tuple of those cast expressions. If there are 846 // more components of the tuple than components in the target type, then excess components do not 847 // come out in the result expression (but UniqueExprs ensure that side effects will still be done). 848 if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) { 849 // expressions which may contain side effects require a single unique instance of the expression. 850 argExpr = new UniqueExpr( argExpr ); 851 } 852 std::list< Expression * > componentExprs; 853 for ( unsigned int i = 0; i < castExpr->get_result()->size(); i++ ) { 854 // cast each component 855 TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i ); 856 componentExprs.push_back( new CastExpr( idx, castExpr->get_result()->getComponent( i )->clone() ) ); 857 } 858 delete argExpr; 859 assert( componentExprs.size() > 0 ); 860 // produce the tuple of casts 861 candidates.push_back( Alternative( new TupleExpr( componentExprs ), i->env, i->cost, thisCost ) ); 862 } else { 863 // handle normally 864 candidates.push_back( Alternative( new CastExpr( argExpr->clone(), toType->clone() ), i->env, i->cost, thisCost ) ); 865 } 868 candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) ); 866 869 } // if 867 870 } // for … … 1182 1185 } 1183 1186 1187 void AlternativeFinder::visit( UntypedInitExpr *initExpr ) { 1188 // handle each option like a cast 1189 AltList candidates; 1190 PRINT( std::cerr << "untyped init expr: " << initExpr << std::endl; ) 1191 // O(N^2) checks of d-types with e-types 1192 for ( InitAlternative & initAlt : initExpr->get_initAlts() ) { 1193 Type * toType = resolveTypeof( initAlt.type, indexer ); 1194 SymTab::validateType( toType, &indexer ); 1195 adjustExprType( toType, env, indexer ); 1196 // Ideally the call to findWithAdjustment could be moved out of the loop, but unfortunately it currently has to occur inside or else 1197 // polymorphic return types are not properly bound to the initialization type, since return type variables are only open for the duration of resolving 1198 // the UntypedExpr. This is only actually an issue in initialization contexts that allow more than one possible initialization type, but it is still suboptimal. 1199 AlternativeFinder finder( indexer, env ); 1200 finder.targetType = toType; 1201 finder.findWithAdjustment( initExpr->get_expr() ); 1202 for ( Alternative & alt : finder.get_alternatives() ) { 1203 TypeEnvironment newEnv( alt.env ); 1204 AssertionSet needAssertions, haveAssertions; 1205 OpenVarSet openVars; // find things in env that don't have a "representative type" and claim those are open vars? 1206 PRINT( std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; ) 1207 // It's possible that a cast can throw away some values in a multiply-valued expression. (An example is a 1208 // cast-to-void, which casts from one value to zero.) Figure out the prefix of the subexpression results 1209 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 1210 // to. 1211 int discardedValues = alt.expr->get_result()->size() - toType->size(); 1212 if ( discardedValues < 0 ) continue; 1213 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 1214 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1215 // unification run for side-effects 1216 unify( toType, alt.expr->get_result(), newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type?? 1217 1218 Cost thisCost = castCost( alt.expr->get_result(), toType, indexer, newEnv ); 1219 if ( thisCost != Cost::infinity ) { 1220 // count one safe conversion for each value that is thrown away 1221 thisCost += Cost( 0, 0, discardedValues ); 1222 candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) ); 1223 } 1224 } 1225 } 1226 1227 // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect of copying the 1228 // cvtCost member to the cost member (since the old cost is now irrelevant). Thus, calling findMinCost twice 1229 // selects first based on argument cost, then on conversion cost. 1230 AltList minArgCost; 1231 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) ); 1232 findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) ); 1233 } 1184 1234 } // namespace ResolvExpr 1185 1235 -
src/ResolvExpr/AlternativeFinder.h
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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 } … … 64 70 virtual void visit( BranchStmt *branchStmt ) override; 65 71 virtual void visit( ReturnStmt *returnStmt ) override; 72 virtual void visit( ThrowStmt *throwStmt ) override; 66 73 67 74 virtual void visit( SingleInit *singleInit ) override; … … 79 86 80 87 Type * functionReturn = nullptr; 81 Type *initContext = nullptr;88 CurrentObject currentObject = nullptr; 82 89 bool inEnumDecl = false; 83 90 }; … … 186 193 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting 187 194 // the RHS. 188 Type *temp = initContext;189 initContext = new_type;190 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext) ) {195 ValueGuard<CurrentObject> temp( currentObject ); 196 currentObject = CurrentObject( objectDecl->get_type() ); 197 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 191 198 // enumerator initializers should not use the enum type to initialize, since 192 199 // the enum type is still incomplete at this point. Use signed int instead. 193 initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt);200 currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 194 201 } 195 202 Parent::visit( objectDecl ); 196 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext) ) {203 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 197 204 // delete newly created signed int type 198 delete initContext; 199 } 200 initContext = temp; 205 // delete currentObject.getType(); 206 } 201 207 } 202 208 … … 315 321 316 322 void Resolver::visit( SwitchStmt *switchStmt ) { 317 ValueGuard< Type * > oldInitContext( initContext );323 ValueGuard< CurrentObject > oldCurrentObject( currentObject ); 318 324 Expression *newExpr; 319 325 newExpr = findIntegralExpression( switchStmt->get_condition(), *this ); … … 321 327 switchStmt->set_condition( newExpr ); 322 328 323 initContext = newExpr->get_result();329 currentObject = CurrentObject( newExpr->get_result() ); 324 330 Parent::visit( switchStmt ); 325 331 } … … 327 333 void Resolver::visit( CaseStmt *caseStmt ) { 328 334 if ( caseStmt->get_condition() ) { 329 assert( initContext ); 330 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initContext->clone() ); 335 std::list< InitAlternative > initAlts = currentObject.getOptions(); 336 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." ); 337 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() ); 331 338 Expression * newExpr = findSingleExpression( castExpr, *this ); 332 339 castExpr = safe_dynamic_cast< CastExpr * >( newExpr ); … … 360 367 } 361 368 369 void Resolver::visit( ThrowStmt *throwStmt ) { 370 if ( throwStmt->get_expr() ) { 371 Expression * wrapped = new CastExpr( throwStmt->get_expr(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 372 Expression * newExpr = findSingleExpression( wrapped, *this ); 373 throwStmt->set_expr( newExpr ); 374 } 375 } 376 362 377 template< typename T > 363 378 bool isCharType( T t ) { … … 370 385 371 386 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 } 387 // resolve initialization using the possibilities as determined by the currentObject cursor 388 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() ); 389 Expression * newExpr = findSingleExpression( untyped, *this ); 390 InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr ); 391 392 // move cursor to the object that is actually initialized 393 currentObject.setNext( initExpr->get_designation() ); 394 395 // discard InitExpr wrapper and retain relevant pieces 396 newExpr = initExpr->get_expr(); 397 newExpr->set_env( initExpr->get_env() ); 398 initExpr->set_expr( nullptr ); 399 initExpr->set_env( nullptr ); 400 delete initExpr; 401 402 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions) 403 Type * initContext = currentObject.getCurrentType(); 404 405 // check if actual object's type is char[] 406 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) { 407 if ( isCharType( at->get_base() ) ) { 408 // check if the resolved type is char * 409 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 410 if ( isCharType( pt->get_base() ) ) { 411 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 412 CastExpr *ce = safe_dynamic_cast< CastExpr * >( newExpr ); 413 newExpr = ce->get_arg(); 414 ce->set_arg( nullptr ); 415 delete ce; 419 416 } 420 417 } 421 418 } 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 419 } 420 421 // set initializer expr to resolved express 422 singleInit->set_value( newExpr ); 423 424 // move cursor to next object in preparation for next initializer 425 currentObject.increment(); 486 426 } 487 427 488 428 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 429 // move cursor into brace-enclosed initializer-list 430 currentObject.enterListInit(); 431 // xxx - fix this so that the list isn't copied, iterator should be used to change current element 432 std::list<Designation *> newDesignations; 433 for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) { 434 // iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving 435 // the initializer against that object. 436 Designation * des = std::get<0>(p); 437 Initializer * init = std::get<1>(p); 438 newDesignations.push_back( currentObject.findNext( des ) ); 439 init->accept( *this ); 440 } 441 // set the set of 'resolved' designations and leave the brace-enclosed initializer-list 442 listInit->get_designations() = newDesignations; // xxx - memory management 443 currentObject.exitListInit(); 444 445 // xxx - this part has not be folded into CurrentObject yet 446 // } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) { 447 // Type * base = tt->get_baseType()->get_base(); 448 // if ( base ) { 449 // // know the implementation type, so try using that as the initContext 450 // ObjectDecl tmpObj( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, base->clone(), nullptr ); 451 // currentObject = &tmpObj; 452 // visit( listInit ); 453 // } else { 454 // // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context 455 // Parent::visit( listInit ); 456 // } 457 // } else { 573 458 } 574 459 -
src/ResolvExpr/Unify.cc
r11dbfe1 r67fa9f9 606 606 } else if ( tupleParam ) { 607 607 // bundle other parameters into tuple to match 608 TupleType* binder = new TupleType{ paramTy->get_qualifiers() };608 std::list< Type * > binderTypes; 609 609 610 610 do { 611 binder ->get_types().push_back( otherParam->get_type()->clone() );611 binderTypes.push_back( otherParam->get_type()->clone() ); 612 612 ++jt; 613 613 … … 618 618 } while (true); 619 619 620 otherParamTy = binder;620 otherParamTy = new TupleType{ paramTy->get_qualifiers(), binderTypes }; 621 621 ++it; // skip ttype parameter for break 622 622 } else if ( otherTupleParam ) { 623 623 // bundle parameters into tuple to match other 624 TupleType* binder = new TupleType{ otherParamTy->get_qualifiers() };624 std::list< Type * > binderTypes; 625 625 626 626 do { 627 binder ->get_types().push_back( param->get_type()->clone() );627 binderTypes.push_back( param->get_type()->clone() ); 628 628 ++it; 629 629 … … 634 634 } while (true); 635 635 636 paramTy = binder;636 paramTy = new TupleType{ otherParamTy->get_qualifiers(), binderTypes }; 637 637 ++jt; // skip ttype parameter for break 638 638 } … … 756 756 return function->get_returnVals().front()->get_type()->clone(); 757 757 } else { 758 TupleType * tupleType = new TupleType( Type::Qualifiers() );758 std::list< Type * > types; 759 759 for ( DeclarationWithType * decl : function->get_returnVals() ) { 760 t upleType->get_types().push_back( decl->get_type()->clone() );760 types.push_back( decl->get_type()->clone() ); 761 761 } // for 762 return tupleType;762 return new TupleType( Type::Qualifiers(), types ); 763 763 } 764 764 } -
src/ResolvExpr/module.mk
r11dbfe1 r67fa9f9 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.