Changes in / [1ba5803:4d5e57b]
- Location:
- src
- Files:
-
- 2 added
- 22 edited
-
GenPoly/InstantiateGeneric.cc (modified) (4 diffs)
-
InitTweak/FixInit.cc (modified) (3 diffs)
-
Parser/DeclarationNode.cc (modified) (3 diffs)
-
Parser/parser.yy (modified) (8 diffs)
-
ResolvExpr/Alternative.cc (modified) (2 diffs)
-
ResolvExpr/Alternative.h (modified) (3 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (21 diffs)
-
ResolvExpr/AlternativeFinder.h (modified) (4 diffs)
-
ResolvExpr/Resolver.cc (modified) (2 diffs)
-
ResolvExpr/TypeEnvironment.cc (modified) (1 diff)
-
ResolvExpr/TypeEnvironment.h (modified) (2 diffs)
-
ResolvExpr/typeops.h (modified) (3 diffs)
-
SymTab/Autogen.cc (modified) (5 diffs)
-
SymTab/Autogen.h (modified) (6 diffs)
-
SymTab/Indexer.cc (modified) (1 diff)
-
SymTab/Indexer.h (modified) (1 diff)
-
SymTab/Validate.cc (modified) (9 diffs)
-
SynTree/Expression.cc (modified) (1 diff)
-
Tuples/TupleAssignment.cc (modified) (1 diff)
-
benchmark/Makefile.am (modified) (2 diffs)
-
benchmark/Makefile.in (modified) (2 diffs)
-
benchmark/bench.c (added)
-
benchmark/csv-data.c (added)
-
tests/.expect/castError.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
r1ba5803 r4d5e57b 27 27 #include "Common/utility.h" // for deleteAll, cloneAll 28 28 #include "GenPoly.h" // for isPolyType, typesPolyCompatible 29 #include "ResolvExpr/typeops.h"30 29 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 31 30 #include "ScrubTyVars.h" // for ScrubTyVars … … 152 151 return gt; 153 152 } 154 155 /// Add cast to dtype-static member expressions so that type information is not lost in GenericInstantiator156 struct FixDtypeStatic final {157 Expression * postmutate( MemberExpr * memberExpr );158 159 template<typename AggrInst>160 Expression * fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr );161 };162 153 163 154 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately … … 207 198 208 199 void instantiateGeneric( std::list< Declaration* > &translationUnit ) { 209 PassVisitor<FixDtypeStatic> fixer;210 200 PassVisitor<GenericInstantiator> instantiator; 211 212 mutateAll( translationUnit, fixer );213 201 mutateAll( translationUnit, instantiator ); 214 }215 216 bool isDtypeStatic( const std::list< TypeDecl* >& baseParams ) {217 return std::all_of( baseParams.begin(), baseParams.end(), []( TypeDecl * td ) { return ! td->isComplete(); } );218 202 } 219 203 … … 495 479 } 496 480 497 template< typename AggrInst >498 Expression * FixDtypeStatic::fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr ) {499 // need to cast dtype-static member expressions to their actual type before that type is erased.500 auto & baseParams = *inst->get_baseParameters();501 if ( isDtypeStatic( baseParams ) ) {502 if ( ! ResolvExpr::typesCompatible( memberExpr->result, memberExpr->member->get_type(), SymTab::Indexer() ) ) {503 // type of member and type of expression differ, so add cast to actual type504 return new CastExpr( memberExpr, memberExpr->result->clone() );505 }506 }507 return memberExpr;508 }509 510 Expression * FixDtypeStatic::postmutate( MemberExpr * memberExpr ) {511 Type * aggrType = memberExpr->aggregate->result;512 if ( isGenericType( aggrType ) ) {513 if ( StructInstType * inst = dynamic_cast< StructInstType * >( aggrType ) ) {514 return fixMemberExpr( inst, memberExpr );515 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( aggrType ) ) {516 return fixMemberExpr( inst, memberExpr );517 }518 }519 return memberExpr;520 }521 522 481 } // namespace GenPoly 523 482 -
src/InitTweak/FixInit.cc
r1ba5803 r4d5e57b 937 937 } 938 938 939 void addIds( SymTab::Indexer & indexer, const std::list< DeclarationWithType * > & decls ) { 940 for ( auto d : decls ) { 941 indexer.addId( d ); 942 } 943 } 944 945 void addTypes( SymTab::Indexer & indexer, const std::list< TypeDecl * > & tds ) { 946 for ( auto td : tds ) { 947 indexer.addType( td ); 948 addIds( indexer, td->assertions ); 949 } 950 } 951 939 952 void GenStructMemberCalls::previsit( FunctionDecl * funcDecl ) { 940 953 GuardValue( function ); … … 993 1006 // need to explicitly re-add function parameters to the indexer in order to resolve copy constructors 994 1007 auto guard = makeFuncGuard( [this]() { indexer.enterScope(); }, [this]() { indexer.leaveScope(); } ); 995 indexer.addFunctionType( function->type ); 1008 addTypes( indexer, function->type->forall ); 1009 addIds( indexer, function->type->returnVals ); 1010 addIds( indexer, function->type->parameters ); 996 1011 997 1012 // need to iterate through members in reverse in order for … … 1008 1023 // insert and resolve default/copy constructor call for each field that's unhandled 1009 1024 std::list< Statement * > stmt; 1010 Expression * arg2 = nullptr;1025 Expression * arg2 = 0; 1011 1026 if ( isCopyConstructor( function ) ) { 1012 1027 // if copy ctor, need to pass second-param-of-this-function.field -
src/Parser/DeclarationNode.cc
r1ba5803 r4d5e57b 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Nov 20 09:21:52201713 // Update Count : 10 3112 // Last Modified On : Sat Sep 23 18:16:48 2017 13 // Update Count : 1024 14 14 // 15 15 … … 509 509 510 510 DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode * q ) { 511 if ( ! q ) { delete q; return this; } // empty qualifier511 if ( ! q ) { delete q; return this; } 512 512 513 513 checkSpecifiers( q ); 514 514 copySpecifiers( q ); 515 515 516 if ( ! q->type ) { delete q; return this; } 516 if ( ! q->type ) { 517 delete q; 518 return this; 519 } // if 517 520 518 521 if ( ! type ) { 519 type = q->type; // reuse structure522 type = q->type; // reuse this structure 520 523 q->type = nullptr; 521 524 delete q; … … 523 526 } // if 524 527 525 if ( q->type->forall ) { // forall qualifier ?526 if ( type->forall ) { // polymorphic routine ?527 type->forall->appendList( q->type->forall ); // augment forall qualifier528 if ( q->type->forall ) { 529 if ( type->forall ) { 530 type->forall->appendList( q->type->forall ); 528 531 } else { 529 if ( type->kind == TypeData::Aggregate ) { // struct/union ? 530 if ( type->aggregate.params ) { // polymorphic ? 531 type->aggregate.params->appendList( q->type->forall ); // augment forall qualifier 532 } else { // not polymorphic 533 type->aggregate.params = q->type->forall; // make polymorphic type 534 // change implicit typedef from TYPEDEFname to TYPEGENname 535 typedefTable.changeKind( *type->aggregate.name, TypedefTable::TG ); 536 } // if 537 } else { // not polymorphic 538 type->forall = q->type->forall; // make polymorphic routine 532 if ( type->kind == TypeData::Aggregate ) { 533 type->aggregate.params = q->type->forall; 534 // change implicit typedef from TYPEDEFname to TYPEGENname 535 typedefTable.changeKind( *type->aggregate.name, TypedefTable::TG ); 536 } else { 537 type->forall = q->type->forall; 539 538 } // if 540 539 } // if 541 q->type->forall = nullptr; // forall qualifier moved540 q->type->forall = nullptr; 542 541 } // if 543 542 -
src/Parser/parser.yy
r1ba5803 r4d5e57b 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Nov 20 09:45:36201713 // Update Count : 2 94512 // Last Modified On : Wed Oct 25 12:28:54 2017 13 // Update Count : 2893 14 14 // 15 15 … … 114 114 } // for 115 115 } // distExt 116 117 // There is an ambiguity for inline generic-routine return-types and generic routines.118 // forall( otype T ) struct S { int i; } bar( T ) {}119 // Does the forall bind to the struct or the routine, and how would it be possible to explicitly specify the binding.120 // forall( otype T ) struct S { int T; } forall( otype W ) bar( W ) {}121 122 void rebindForall( DeclarationNode * declSpec, DeclarationNode * funcDecl ) {123 if ( declSpec->type->kind == TypeData::Aggregate ) { // return is aggregate definition124 funcDecl->type->forall = declSpec->type->aggregate.params; // move forall from aggregate to function type125 declSpec->type->aggregate.params = nullptr;126 } // if127 } // rebindForall128 116 129 117 bool forall = false; // aggregate have one or more forall qualifiers ? … … 360 348 361 349 362 // Handle shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string is ambiguous: 363 // .---------. matches IF '(' comma_expression ')' statement . (reduce) 364 // if ( C ) S1 else S2 365 // `-----------------' matches IF '(' comma_expression ')' statement . (shift) ELSE statement */ 350 // Handle single shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string 351 // is ambiguous: 352 // .---------. matches IF '(' comma_expression ')' statement . (reduce) 353 // if ( C ) S1 else S2 354 // `-----------------' matches IF '(' comma_expression ')' statement . (shift) ELSE statement */ 366 355 // Similar issues exit with the waitfor statement. 367 356 … … 372 361 %precedence TIMEOUT // token precedence for start of TIMEOUT in WAITFOR statement 373 362 %precedence ELSE // token precedence for start of else clause in IF/WAITFOR statement 374 375 // Handle shift/reduce conflict for generic type by shifting the '(' token. For example, this string is ambiguous:376 // forall( otype T ) struct Foo { T v; };377 // .-----. matches pointer to function returning a generic (which is impossible without a type)378 // Foo ( *fp )( int );379 // `---' matches start of TYPEGENname '('380 // Must be:381 // Foo( int ) ( *fp )( int );382 383 // Order of these lines matters (low-to-high precedence).384 %precedence TYPEGENname385 %precedence '('386 363 387 364 %locations // support location tracking for error messages … … 1788 1765 1789 1766 typegen_name: // CFA 1790 TYPEGENname 1791 { $$ = DeclarationNode::newFromTypeGen( $1, nullptr ); } 1792 | TYPEGENname '(' ')' 1767 TYPEGENname '(' ')' 1793 1768 { $$ = DeclarationNode::newFromTypeGen( $1, nullptr ); } 1794 1769 | TYPEGENname '(' type_list ')' … … 1834 1809 } 1835 1810 | aggregate_key attribute_list_opt typegen_name // CFA 1836 { 1837 // Create new generic declaration with same name as previous forward declaration, where the IDENTIFIER is 1838 // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and 1839 // delete newFromTypeGen. 1840 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 ); 1841 $3->type->symbolic.name = nullptr; 1842 $3->type->symbolic.actuals = nullptr; 1843 delete $3; 1844 } 1811 { $$ = $3->addQualifiers( $2 ); } 1845 1812 ; 1846 1813 … … 2413 2380 | declaration_specifier function_declarator with_clause_opt compound_statement 2414 2381 { 2415 rebindForall( $1, $2 );2416 2382 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2417 2383 typedefTable.leaveScope(); … … 2440 2406 | declaration_specifier KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement 2441 2407 { 2442 rebindForall( $1, $2 );2443 2408 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2444 2409 typedefTable.leaveScope(); -
src/ResolvExpr/Alternative.cc
r1ba5803 r4d5e57b 18 18 #include <ostream> // for operator<<, ostream, basic_o... 19 19 #include <string> // for operator<<, char_traits, string 20 #include <utility> // for move21 20 22 21 #include "Common/utility.h" // for maybeClone … … 82 81 os << std::endl; 83 82 } 84 85 void splice( AltList& dst, AltList& src ) {86 dst.reserve( dst.size() + src.size() );87 for ( Alternative& alt : src ) {88 dst.push_back( std::move(alt) );89 }90 src.clear();91 }92 93 void spliceBegin( AltList& dst, AltList& src ) {94 splice( src, dst );95 dst.swap( src );96 }97 98 83 } // namespace ResolvExpr 99 84 -
src/ResolvExpr/Alternative.h
r1ba5803 r4d5e57b 17 17 18 18 #include <iosfwd> // for ostream 19 #include < vector> // for vector19 #include <list> // for list 20 20 21 21 #include "Cost.h" // for Cost … … 25 25 26 26 namespace ResolvExpr { 27 struct Alternative; 28 29 typedef std::list< Alternative > AltList; 30 27 31 struct Alternative { 28 32 Alternative(); … … 42 46 TypeEnvironment env; 43 47 }; 44 45 typedef std::vector< Alternative > AltList;46 47 /// Moves all elements from src to the end of dst48 void splice( AltList& dst, AltList& src );49 50 /// Moves all elements from src to the beginning of dst51 void spliceBegin( AltList& dst, AltList& src );52 48 } // namespace ResolvExpr 53 49 -
src/ResolvExpr/AlternativeFinder.cc
r1ba5803 r4d5e57b 16 16 #include <algorithm> // for copy 17 17 #include <cassert> // for strict_dynamic_cast, assert, assertf 18 #include <cstddef> // for size_t19 18 #include <iostream> // for operator<<, cerr, ostream, endl 20 19 #include <iterator> // for back_insert_iterator, back_inserter 21 20 #include <list> // for _List_iterator, list, _List_const_... 22 21 #include <map> // for _Rb_tree_iterator, map, _Rb_tree_c... 23 #include <memory> // for allocator_traits<>::value_type , unique_ptr22 #include <memory> // for allocator_traits<>::value_type 24 23 #include <utility> // for pair 25 24 #include <vector> // for vector … … 52 51 //#define DEBUG_COST 53 52 54 using std::move;55 56 /// copies any copyable type57 template<typename T>58 T copy(const T& x) { return x; }59 60 53 namespace ResolvExpr { 61 54 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ) { … … 186 179 expr->accept( *this ); 187 180 if ( failFast && alternatives.empty() ) { 188 PRINT(189 std::cerr << "No reasonable alternatives for expression " << expr << std::endl;190 )191 181 throw SemanticError( "No reasonable alternatives for expression ", expr ); 192 182 } … … 197 187 printAlts( alternatives, std::cerr ); 198 188 ) 199 AltList pruned;200 pruneAlternatives( alternatives.begin(), alternatives.end(), back_inserter( pruned) );201 if ( failFast && pruned.empty()) {189 AltList::iterator oldBegin = alternatives.begin(); 190 pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ) ); 191 if ( failFast && alternatives.begin() == oldBegin ) { 202 192 std::ostringstream stream; 203 193 AltList winners; … … 209 199 throw SemanticError( stream.str() ); 210 200 } 211 alternatives = move(pruned);201 alternatives.erase( oldBegin, alternatives.end() ); 212 202 PRINT( 213 203 std::cerr << "there are " << oldsize << " alternatives before elimination" << std::endl; … … 581 571 /// State to iteratively build a match of parameter expressions to arguments 582 572 struct ArgPack { 583 std::size_t parent; ///< Index of parent pack 584 std::unique_ptr<Expression> expr; ///< The argument stored here 585 Cost cost; ///< The cost of this argument 586 TypeEnvironment env; ///< Environment for this pack 587 AssertionSet need; ///< Assertions outstanding for this pack 588 AssertionSet have; ///< Assertions found for this pack 589 OpenVarSet openVars; ///< Open variables for this pack 590 unsigned nextArg; ///< Index of next argument in arguments list 591 unsigned tupleStart; ///< Number of tuples that start at this index 592 // TODO fix this somehow 593 std::vector<Alternative> expls; ///< Exploded actuals left over from last match 594 595 ArgPack() 596 : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 597 tupleStart(0), expls() {} 573 AltList actuals; ///< Arguments included in this pack 574 TypeEnvironment env; ///< Environment for this pack 575 AssertionSet need; ///< Assertions outstanding for this pack 576 AssertionSet have; ///< Assertions found for this pack 577 OpenVarSet openVars; ///< Open variables for this pack 578 unsigned nextArg; ///< Index of next argument in arguments list 579 std::vector<Alternative> expls; ///< Exploded actuals left over from last match 580 unsigned nextExpl; ///< Index of next exploded alternative to use 581 std::vector<unsigned> tupleEls; /// Number of elements in current tuple element(s) 598 582 599 583 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 600 584 const OpenVarSet& openVars) 601 : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have), 602 openVars(openVars), nextArg(0), tupleStart(0), expls() {} 603 604 ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need, 605 AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg, 606 unsigned tupleStart = 0, Cost cost = Cost::zero, 607 std::vector<Alternative>&& expls = std::vector<Alternative>{} ) 608 : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)), 609 have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart), 610 expls(move(expls)) {} 611 612 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 613 OpenVarSet&& openVars, unsigned nextArg, Cost added ) 614 : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 615 env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)), 616 nextArg(nextArg), tupleStart(o.tupleStart), expls() {} 617 618 619 // ArgPack(const ArgPack& o) 620 // : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), env(o.env), 621 // need(o.need), have(o.have), openVars(o.openVars), nextArg(o.nextArg), 622 // tupleStart(o.tupleStart), expls(o.expls) {} 623 624 // ArgPack(ArgPack&&) = default; 585 : actuals(), env(env), need(need), have(have), openVars(openVars), nextArg(0), 586 expls(), nextExpl(0), tupleEls() {} 587 588 /// Starts a new tuple expression 589 void beginTuple() { 590 if ( ! tupleEls.empty() ) ++tupleEls.back(); 591 tupleEls.push_back(0); 592 } 625 593 626 594 /// Ends a tuple expression, consolidating the appropriate actuals 627 void endTuple( const std::vector<ArgPack>& packs) {628 // add all expressions in tuple to list, summing cost595 void endTuple() { 596 // set up new Tuple alternative 629 597 std::list<Expression*> exprs; 630 const ArgPack* pack = this; 631 if ( expr ) { exprs.push_front( expr.release() ); } 632 while ( pack->tupleStart == 0 ) { 633 pack = &packs[pack->parent]; 634 exprs.push_front( pack->expr->clone() ); 635 cost += pack->cost; 636 } 637 // reset pack to appropriate tuple 638 expr.reset( new TupleExpr( exprs ) ); 639 tupleStart = pack->tupleStart - 1; 640 parent = pack->parent; 598 Cost cost = Cost::zero; 599 600 // transfer elements into alternative 601 for (unsigned i = 0; i < tupleEls.back(); ++i) { 602 exprs.push_front( actuals.back().expr ); 603 actuals.back().expr = nullptr; 604 cost += actuals.back().cost; 605 actuals.pop_back(); 606 } 607 tupleEls.pop_back(); 608 609 // build new alternative 610 actuals.emplace_back( new TupleExpr( exprs ), this->env, cost ); 611 } 612 613 /// Clones and adds an actual, returns this 614 ArgPack& withArg( Expression* expr, Cost cost = Cost::zero ) { 615 actuals.emplace_back( expr->clone(), this->env, cost ); 616 if ( ! tupleEls.empty() ) ++tupleEls.back(); 617 return *this; 641 618 } 642 619 }; … … 644 621 /// Instantiates an argument to match a formal, returns false if no results left 645 622 bool instantiateArgument( Type* formalType, Initializer* initializer, 646 const std::vector< AlternativeFinder >& args, std::vector<ArgPack>& results, 647 std::size_t& genStart, const SymTab::Indexer& indexer, unsigned nTuples = 0 ) { 623 const std::vector< AlternativeFinder >& args, 624 std::vector<ArgPack>& results, std::vector<ArgPack>& nextResults, 625 const SymTab::Indexer& indexer ) { 648 626 if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) { 649 627 // formalType is a TupleType - group actuals into a TupleExpr 650 ++nTuples;628 for ( ArgPack& result : results ) { result.beginTuple(); } 651 629 for ( Type* type : *tupleType ) { 652 630 // xxx - dropping initializer changes behaviour from previous, but seems correct 653 if ( ! instantiateArgument( 654 type, nullptr, args, results, genStart, indexer, nTuples ) ) 631 if ( ! instantiateArgument( type, nullptr, args, results, nextResults, indexer ) ) 655 632 return false; 656 nTuples = 0; 657 } 658 // re-consititute tuples for final generation 659 for ( auto i = genStart; i < results.size(); ++i ) { 660 results[i].endTuple( results ); 661 } 633 } 634 for ( ArgPack& result : results ) { result.endTuple(); } 662 635 return true; 663 636 } else if ( TypeInstType* ttype = Tuples::isTtype( formalType ) ) { 664 637 // formalType is a ttype, consumes all remaining arguments 665 638 // xxx - mixing default arguments with variadic?? 666 667 // completed tuples; will be spliced to end of results to finish 668 std::vector<ArgPack> finalResults{}; 669 639 std::vector<ArgPack> finalResults{}; /// list of completed tuples 640 // start tuples 641 for ( ArgPack& result : results ) { 642 result.beginTuple(); 643 644 // use rest of exploded tuple if present 645 while ( result.nextExpl < result.expls.size() ) { 646 const Alternative& actual = result.expls[result.nextExpl]; 647 result.env.addActual( actual.env, result.openVars ); 648 result.withArg( actual.expr ); 649 ++result.nextExpl; 650 } 651 } 670 652 // iterate until all results completed 671 std::size_t genEnd; 672 ++nTuples; 673 do { 674 genEnd = results.size(); 675 653 while ( ! results.empty() ) { 676 654 // add another argument to results 677 for ( std::size_t i = genStart; i < genEnd; ++i ) { 678 // use remainder of exploded tuple if present 679 if ( ! results[i].expls.empty() ) { 680 const Alternative& actual = results[i].expls.front(); 681 682 TypeEnvironment env = results[i].env; 683 OpenVarSet openVars = results[i].openVars; 684 685 env.addActual( actual.env, openVars ); 686 687 std::vector<Alternative> newExpls( 688 std::next( results[i].expls.begin() ), results[i].expls.end() ); 689 results.emplace_back( 690 i, actual.expr, move(env), copy(results[i].need), 691 copy(results[i].have), move(openVars), results[i].nextArg, nTuples, 692 Cost::zero, move(newExpls) ); 693 655 for ( ArgPack& result : results ) { 656 // finish result when out of arguments 657 if ( result.nextArg >= args.size() ) { 658 Type* argType = result.actuals.back().expr->get_result(); 659 if ( result.tupleEls.back() == 1 && Tuples::isTtype( argType ) ) { 660 // the case where a ttype value is passed directly is special, e.g. for 661 // argument forwarding purposes 662 // xxx - what if passing multiple arguments, last of which is ttype? 663 // xxx - what would happen if unify was changed so that unifying tuple 664 // types flattened both before unifying lists? then pass in TupleType 665 // (ttype) below. 666 result.tupleEls.pop_back(); 667 } else { 668 // collapse leftover arguments into tuple 669 result.endTuple(); 670 argType = result.actuals.back().expr->get_result(); 671 } 672 // check unification for ttype before adding to final 673 if ( unify( ttype, argType, result.env, result.need, result.have, 674 result.openVars, indexer ) ) { 675 finalResults.push_back( std::move(result) ); 676 } 694 677 continue; 695 678 } 696 679 697 // finish result when out of arguments698 if ( results[i].nextArg >= args.size() ) {699 ArgPack newResult{700 results[i].env, results[i].need, results[i].have,701 results[i].openVars };702 newResult.nextArg = results[i].nextArg;703 Type* argType;704 705 if ( nTuples > 0 ) {706 // first iteration, push empty tuple expression707 newResult.parent = i;708 std::list<Expression*> emptyList;709 newResult.expr.reset( new TupleExpr( emptyList ) );710 argType = newResult.expr->get_result();711 } else {712 // clone result to collect tuple713 newResult.parent = results[i].parent;714 newResult.cost = results[i].cost;715 newResult.tupleStart = results[i].tupleStart;716 newResult.expr.reset( results[i].expr->clone() );717 argType = newResult.expr->get_result();718 719 if ( results[i].tupleStart > 0 && Tuples::isTtype( argType ) ) {720 // the case where a ttype value is passed directly is special,721 // e.g. for argument forwarding purposes722 // xxx - what if passing multiple arguments, last of which is723 // ttype?724 // xxx - what would happen if unify was changed so that unifying725 // tuple726 // types flattened both before unifying lists? then pass in727 // TupleType (ttype) below.728 --newResult.tupleStart;729 } else {730 // collapse leftover arguments into tuple731 newResult.endTuple( results );732 argType = newResult.expr->get_result();733 }734 }735 736 // check unification for ttype before adding to final737 if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have,738 newResult.openVars, indexer ) ) {739 finalResults.push_back( move(newResult) );740 }741 742 continue;743 }744 745 680 // add each possible next argument 746 auto j = results[i].nextArg; 747 for ( const Alternative& actual : args[j] ) { 748 // fresh copies of parent parameters for this iteration 749 TypeEnvironment env = results[i].env; 750 OpenVarSet openVars = results[i].openVars; 751 752 env.addActual( actual.env, openVars ); 681 for ( const Alternative& actual : args[result.nextArg] ) { 682 ArgPack aResult = result; // copy to clone everything 683 // add details of actual to result 684 aResult.env.addActual( actual.env, aResult.openVars ); 685 Cost cost = actual.cost; 753 686 754 687 // explode argument 755 688 std::vector<Alternative> exploded; 756 689 Tuples::explode( actual, indexer, back_inserter( exploded ) ); 757 if ( exploded.empty() ) { 758 // skip empty tuple arguments by (near-)cloning parent into next gen 759 results.emplace_back( 760 results[i], move(env), copy(results[i].need), 761 copy(results[i].have), move(openVars), j + 1, actual.cost ); 762 763 continue; 690 691 // add exploded argument to tuple 692 for ( Alternative& aActual : exploded ) { 693 aResult.withArg( aActual.expr, cost ); 694 cost = Cost::zero; 764 695 } 765 766 // trim first element from exploded 767 std::vector<Alternative> newExpls; 768 newExpls.reserve( exploded.size() - 1 ); 769 for ( std::size_t i = 1; i < exploded.size(); ++i ) { 770 newExpls.push_back( move(exploded[i]) ); 771 } 772 // add new result 773 results.emplace_back( 774 i, exploded.front().expr, move(env), copy(results[i].need), 775 copy(results[i].have), move(openVars), results[i].nextArg + 1, 776 nTuples, actual.cost, move(newExpls) ); 696 ++aResult.nextArg; 697 nextResults.push_back( std::move(aResult) ); 777 698 } 778 699 } 779 700 780 701 // reset for next round 781 genStart = genEnd; 782 nTuples = 0; 783 } while ( genEnd != results.size() ); 784 785 // splice final results onto results 786 for ( std::size_t i = 0; i < finalResults.size(); ++i ) { 787 results.push_back( move(finalResults[i]) ); 788 } 789 return ! finalResults.empty(); 702 results.swap( nextResults ); 703 nextResults.clear(); 704 } 705 results.swap( finalResults ); 706 return ! results.empty(); 790 707 } 791 708 792 709 // iterate each current subresult 793 std::size_t genEnd = results.size(); 794 for ( std::size_t i = genStart; i < genEnd; ++i ) { 795 // use remainder of exploded tuple if present 796 if ( ! results[i].expls.empty() ) { 797 const Alternative& actual = results[i].expls.front(); 798 799 TypeEnvironment env = results[i].env; 800 AssertionSet need = results[i].need, have = results[i].have; 801 OpenVarSet openVars = results[i].openVars; 802 803 env.addActual( actual.env, openVars ); 710 for ( unsigned iResult = 0; iResult < results.size(); ++iResult ) { 711 ArgPack& result = results[iResult]; 712 713 if ( result.nextExpl < result.expls.size() ) { 714 // use remainder of exploded tuple if present 715 const Alternative& actual = result.expls[result.nextExpl]; 716 result.env.addActual( actual.env, result.openVars ); 804 717 Type* actualType = actual.expr->get_result(); 805 718 … … 812 725 ) 813 726 814 if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) { 815 std::vector<Alternative> newExpls( 816 std::next( results[i].expls.begin() ), results[i].expls.end() ); 817 results.emplace_back( 818 i, actual.expr, move(env), move(need), move(have), move(openVars), 819 results[i].nextArg, nTuples, Cost::zero, move(newExpls) );; 727 if ( unify( formalType, actualType, result.env, result.need, result.have, 728 result.openVars, indexer ) ) { 729 ++result.nextExpl; 730 nextResults.push_back( std::move(result.withArg( actual.expr )) ); 820 731 } 821 732 822 733 continue; 823 } 824 825 // use default initializers if out of arguments 826 if ( results[i].nextArg >= args.size() ) { 734 } else if ( result.nextArg >= args.size() ) { 735 // use default initializers if out of arguments 827 736 if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) { 828 737 if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) { 829 TypeEnvironment env = results[i].env; 830 AssertionSet need = results[i].need, have = results[i].have; 831 OpenVarSet openVars = results[i].openVars; 832 833 if ( unify( formalType, cnst->get_type(), env, need, have, openVars, 834 indexer ) ) { 835 results.emplace_back( 836 i, cnstExpr, move(env), move(need), move(have), 837 move(openVars), results[i].nextArg, nTuples ); 738 if ( unify( formalType, cnst->get_type(), result.env, result.need, 739 result.have, result.openVars, indexer ) ) { 740 nextResults.push_back( std::move(result.withArg( cnstExpr )) ); 838 741 } 839 742 } 840 743 } 841 842 744 continue; 843 745 } 844 746 845 747 // Check each possible next argument 846 auto j = results[i].nextArg; 847 for ( const Alternative& actual : args[j] ) { 848 // fresh copies of parent parameters for this iteration 849 TypeEnvironment env = results[i].env; 850 AssertionSet need = results[i].need, have = results[i].have; 851 OpenVarSet openVars = results[i].openVars; 852 853 env.addActual( actual.env, openVars ); 748 for ( const Alternative& actual : args[result.nextArg] ) { 749 ArgPack aResult = result; // copy to clone everything 750 // add details of actual to result 751 aResult.env.addActual( actual.env, aResult.openVars ); 854 752 855 753 // explode argument … … 857 755 Tuples::explode( actual, indexer, back_inserter( exploded ) ); 858 756 if ( exploded.empty() ) { 859 // skip empty tuple arguments by (near-)cloning parent into next gen 860 results.emplace_back( 861 results[i], move(env), move(need), move(have), move(openVars), j + 1, 862 actual.cost ); 863 757 // skip empty tuple arguments 758 ++aResult.nextArg; 759 results.push_back( std::move(aResult) ); 864 760 continue; 865 761 } … … 878 774 879 775 // attempt to unify types 880 if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) { 881 // trim first element from exploded 882 std::vector<Alternative> newExpls; 883 newExpls.reserve( exploded.size() - 1 ); 884 for ( std::size_t i = 1; i < exploded.size(); ++i ) { 885 newExpls.push_back( move(exploded[i]) ); 776 if ( unify( formalType, actualType, aResult.env, aResult.need, aResult.have, aResult.openVars, indexer ) ) { 777 // add argument 778 aResult.withArg( aActual.expr, actual.cost ); 779 ++aResult.nextArg; 780 if ( exploded.size() > 1 ) { 781 // other parts of tuple left over 782 aResult.expls = std::move( exploded ); 783 aResult.nextExpl = 1; 886 784 } 887 // add new result 888 results.emplace_back( 889 i, aActual.expr, move(env), move(need), move(have), move(openVars), 890 j + 1, nTuples, actual.cost, move(newExpls) ); 785 nextResults.push_back( std::move(aResult) ); 891 786 } 892 787 } … … 894 789 895 790 // reset for next parameter 896 genStart = genEnd; 897 898 return genEnd != results.size(); 899 } 900 901 template<typename OutputIterator> 902 void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 903 const std::vector<ArgPack>& results, OutputIterator out ) { 904 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 905 // sum cost and accumulate actuals 906 std::list<Expression*>& args = appExpr->get_args(); 907 Cost cost = Cost::zero; 908 const ArgPack* pack = &result; 909 while ( pack->expr ) { 910 args.push_front( pack->expr->clone() ); 911 cost += pack->cost; 912 pack = &results[pack->parent]; 913 } 914 // build and validate new alternative 915 Alternative newAlt( appExpr, result.env, cost ); 916 PRINT( 917 std::cerr << "instantiate function success: " << appExpr << std::endl; 918 std::cerr << "need assertions:" << std::endl; 919 printAssertionSet( result.need, std::cerr, 8 ); 920 ) 921 inferParameters( result.need, result.have, newAlt, result.openVars, out ); 791 results.swap( nextResults ); 792 nextResults.clear(); 793 794 return ! results.empty(); 922 795 } 923 796 … … 945 818 946 819 // iteratively build matches, one parameter at a time 947 std::vector<ArgPack> results; 948 results.push_back( ArgPack{ funcEnv, funcNeed, funcHave, funcOpenVars } ); 949 std::size_t genStart = 0; 950 820 std::vector<ArgPack> results{ ArgPack{ funcEnv, funcNeed, funcHave, funcOpenVars } }; 821 std::vector<ArgPack> nextResults{}; 951 822 for ( DeclarationWithType* formal : funcType->get_parameters() ) { 952 823 ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal ); 953 824 if ( ! instantiateArgument( 954 obj->get_type(), obj->get_init(), args, results, genStart, indexer ) )825 obj->get_type(), obj->get_init(), args, results, nextResults, indexer ) ) 955 826 return; 956 827 } 957 828 829 // filter out results that don't use all the arguments, and aren't variadic 830 std::vector<ArgPack> finalResults{}; 958 831 if ( funcType->get_isVarArgs() ) { 959 // append any unused arguments to vararg pack 960 std::size_t genEnd; 961 do { 962 genEnd = results.size(); 963 964 // iterate results 965 for ( std::size_t i = genStart; i < genEnd; ++i ) { 966 // use remainder of exploded tuple if present 967 if ( ! results[i].expls.empty() ) { 968 const Alternative& actual = results[i].expls.front(); 969 970 TypeEnvironment env = results[i].env; 971 OpenVarSet openVars = results[i].openVars; 972 973 env.addActual( actual.env, openVars ); 974 975 std::vector<Alternative> newExpls( 976 std::next( results[i].expls.begin() ), results[i].expls.end() ); 977 results.emplace_back( 978 i, actual.expr, move(env), copy(results[i].need), 979 copy(results[i].have), move(openVars), results[i].nextArg, 0, 980 Cost::zero, move(newExpls) ); 981 832 for ( ArgPack& result : results ) { 833 // use rest of exploded tuple if present 834 while ( result.nextExpl < result.expls.size() ) { 835 const Alternative& actual = result.expls[result.nextExpl]; 836 result.env.addActual( actual.env, result.openVars ); 837 result.withArg( actual.expr ); 838 ++result.nextExpl; 839 } 840 } 841 842 while ( ! results.empty() ) { 843 // build combinations for all remaining arguments 844 for ( ArgPack& result : results ) { 845 // keep if used all arguments 846 if ( result.nextArg >= args.size() ) { 847 finalResults.push_back( std::move(result) ); 982 848 continue; 983 849 } 984 850 985 // finish result when out of arguments986 if ( results[i].nextArg >= args.size() ) {987 validateFunctionAlternative( func, results[i], results, out );988 989 continue;990 }991 992 851 // add each possible next argument 993 auto j = results[i].nextArg; 994 for ( const Alternative& actual : args[j] ) { 995 // fresh copies of parent parameters for this iteration 996 TypeEnvironment env = results[i].env; 997 OpenVarSet openVars = results[i].openVars; 998 999 env.addActual( actual.env, openVars ); 852 for ( const Alternative& actual : args[result.nextArg] ) { 853 ArgPack aResult = result; // copy to clone everything 854 // add details of actual to result 855 aResult.env.addActual( actual.env, aResult.openVars ); 856 Cost cost = actual.cost; 1000 857 1001 858 // explode argument 1002 859 std::vector<Alternative> exploded; 1003 860 Tuples::explode( actual, indexer, back_inserter( exploded ) ); 1004 if ( exploded.empty() ) { 1005 // skip empty tuple arguments by (near-)cloning parent into next gen 1006 results.emplace_back( 1007 results[i], move(env), copy(results[i].need), 1008 copy(results[i].have), move(openVars), j + 1, actual.cost ); 1009 continue; 861 862 // add exploded argument to arg list 863 for ( Alternative& aActual : exploded ) { 864 aResult.withArg( aActual.expr, cost ); 865 cost = Cost::zero; 1010 866 } 1011 1012 // trim first element from exploded 1013 std::vector<Alternative> newExpls; 1014 newExpls.reserve( exploded.size() - 1 ); 1015 for ( std::size_t i = 1; i < exploded.size(); ++i ) { 1016 newExpls.push_back( move(exploded[i]) ); 1017 } 1018 // add new result 1019 results.emplace_back( 1020 i, exploded.front().expr, move(env), copy(results[i].need), 1021 copy(results[i].have), move(openVars), j + 1, 0, 1022 actual.cost, move(newExpls) ); 867 ++aResult.nextArg; 868 nextResults.push_back( std::move(aResult) ); 1023 869 } 1024 870 } 1025 871 1026 genStart = genEnd; 1027 } while ( genEnd != results.size() ); 872 // reset for next round 873 results.swap( nextResults ); 874 nextResults.clear(); 875 } 1028 876 } else { 1029 877 // filter out results that don't use all the arguments 1030 for ( std::size_t i = genStart; i < results.size(); ++i ) { 1031 ArgPack& result = results[i]; 1032 if ( result.expls.empty() && result.nextArg >= args.size() ) { 1033 validateFunctionAlternative( func, result, results, out ); 1034 } 1035 } 878 for ( ArgPack& result : results ) { 879 if ( result.nextExpl >= result.expls.size() && result.nextArg >= args.size() ) { 880 finalResults.push_back( std::move(result) ); 881 } 882 } 883 } 884 885 // validate matching combos, add to final result list 886 for ( ArgPack& result : finalResults ) { 887 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 888 Alternative newAlt( appExpr, result.env, sumCost( result.actuals ) ); 889 makeExprList( result.actuals, appExpr->get_args() ); 890 PRINT( 891 std::cerr << "instantiate function success: " << appExpr << std::endl; 892 std::cerr << "need assertions:" << std::endl; 893 printAssertionSet( result.need, std::cerr, 8 ); 894 ) 895 inferParameters( result.need, result.have, newAlt, result.openVars, out ); 1036 896 } 1037 897 } … … 1096 956 if ( ! funcOpFinder.alternatives.empty() ) { 1097 957 // add function alternatives to front of argument list 1098 argAlternatives.insert( argAlternatives.begin(), move(funcFinder) );958 argAlternatives.insert( argAlternatives.begin(), std::move(funcFinder) ); 1099 959 1100 960 for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); … … 1122 982 1123 983 // compute conversionsion costs 1124 for ( Alt ernative& withFunc : candidates) {1125 Cost cvtCost = computeApplicationConversionCost( withFunc, indexer );984 for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) { 985 Cost cvtCost = computeApplicationConversionCost( *withFunc, indexer ); 1126 986 1127 987 PRINT( 1128 ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc .expr );988 ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc->expr ); 1129 989 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 1130 990 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->get_base() ); … … 1135 995 printAll( appExpr->get_args(), std::cerr, 8 ); 1136 996 std::cerr << "bindings are:" << std::endl; 1137 withFunc .env.print( std::cerr, 8 );997 withFunc->env.print( std::cerr, 8 ); 1138 998 std::cerr << "cost of conversion is:" << cvtCost << std::endl; 1139 999 ) 1140 1000 if ( cvtCost != Cost::infinity ) { 1141 withFunc .cvtCost = cvtCost;1142 alternatives.push_back( withFunc );1001 withFunc->cvtCost = cvtCost; 1002 alternatives.push_back( *withFunc ); 1143 1003 } // if 1144 1004 } // for 1145 1005 1146 candidates = move(alternatives); 1006 candidates.clear(); 1007 candidates.splice( candidates.end(), alternatives ); 1147 1008 1148 1009 // use a new list so that alternatives are not examined by addAnonConversions twice. … … 1150 1011 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( winners ) ); 1151 1012 1152 // function may return struct or union value, in which case we need to add alternatives 1153 // for implicitconversions to each of the anonymous members, must happen after findMinCost1154 // since anon conversionsare never the cheapest expression1013 // function may return struct or union value, in which case we need to add alternatives for implicit 1014 // conversions to each of the anonymous members, must happen after findMinCost since anon conversions 1015 // are never the cheapest expression 1155 1016 for ( const Alternative & alt : winners ) { 1156 1017 addAnonConversions( alt ); 1157 1018 } 1158 spliceBegin( alternatives, winners );1019 alternatives.splice( alternatives.begin(), winners ); 1159 1020 1160 1021 if ( alternatives.empty() && targetType && ! targetType->isVoid() ) { … … 1180 1041 AlternativeFinder finder( indexer, env ); 1181 1042 finder.find( addressExpr->get_arg() ); 1182 for ( Alternative& alt : finder.alternatives ) { 1183 if ( isLvalue( alt.expr ) ) { 1184 alternatives.push_back( 1185 Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } ); 1043 for ( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) { 1044 if ( isLvalue( i->expr ) ) { 1045 alternatives.push_back( Alternative( new AddressExpr( i->expr->clone() ), i->env, i->cost ) ); 1186 1046 } // if 1187 1047 } // for … … 1189 1049 1190 1050 void AlternativeFinder::visit( LabelAddressExpr * expr ) { 1191 alternatives.push_back( Alternative { expr->clone(), env, Cost::zero });1051 alternatives.push_back( Alternative( expr->clone(), env, Cost::zero) ); 1192 1052 } 1193 1053 … … 1231 1091 1232 1092 AltList candidates; 1233 for ( Alternative & alt : finder.alternatives) {1093 for ( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) { 1234 1094 AssertionSet needAssertions, haveAssertions; 1235 1095 OpenVarSet openVars; … … 1239 1099 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 1240 1100 // to. 1241 int discardedValues = alt.expr->get_result()->size() - castExpr->get_result()->size();1101 int discardedValues = i->expr->get_result()->size() - castExpr->get_result()->size(); 1242 1102 if ( discardedValues < 0 ) continue; 1243 1103 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 1244 1104 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1245 1105 // unification run for side-effects 1246 unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions, 1247 haveAssertions, openVars, indexer ); 1248 Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer, 1249 alt.env ); 1250 PRINT( 1251 std::cerr << "working on cast with result: " << castExpr->result << std::endl; 1252 std::cerr << "and expr type: " << alt.expr->result << std::endl; 1253 std::cerr << "env: " << alt.env << std::endl; 1254 ) 1106 unify( castExpr->get_result(), i->expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer ); 1107 Cost thisCost = castCost( i->expr->get_result(), castExpr->get_result(), indexer, i->env ); 1255 1108 if ( thisCost != Cost::infinity ) { 1256 PRINT(1257 std::cerr << "has finite cost." << std::endl;1258 )1259 1109 // count one safe conversion for each value that is thrown away 1260 1110 thisCost.incSafe( discardedValues ); 1261 Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env, 1262 alt.cost, thisCost ); 1263 inferParameters( needAssertions, haveAssertions, newAlt, openVars, 1264 back_inserter( candidates ) ); 1111 Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ); 1112 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) ); 1265 1113 } // if 1266 1114 } // for … … 1549 1397 1550 1398 void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) { 1551 std::vector< AlternativeFinder > subExprAlternatives; 1552 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 1553 back_inserter( subExprAlternatives ) ); 1554 std::vector< AltList > possibilities; 1555 combos( subExprAlternatives.begin(), subExprAlternatives.end(), 1556 back_inserter( possibilities ) ); 1557 for ( const AltList& alts : possibilities ) { 1399 std::list< AlternativeFinder > subExprAlternatives; 1400 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) ); 1401 std::list< AltList > possibilities; 1402 combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) ); 1403 for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) { 1558 1404 std::list< Expression * > exprs; 1559 makeExprList( alts, exprs );1405 makeExprList( *i, exprs ); 1560 1406 1561 1407 TypeEnvironment compositeEnv; 1562 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv ); 1563 alternatives.push_back( 1564 Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } ); 1408 simpleCombineEnvironments( i->begin(), i->end(), compositeEnv ); 1409 alternatives.push_back( Alternative( new TupleExpr( exprs ) , compositeEnv, sumCost( *i ) ) ); 1565 1410 } // for 1566 1411 } -
src/ResolvExpr/AlternativeFinder.h
r1ba5803 r4d5e57b 31 31 32 32 namespace ResolvExpr { 33 struct ArgPack;34 35 33 class AlternativeFinder : public Visitor { 36 34 public: … … 38 36 39 37 AlternativeFinder( const AlternativeFinder& o ) 40 : indexer(o.indexer), alternatives(o.alternatives), env(o.env), 38 : indexer(o.indexer), alternatives(o.alternatives), env(o.env), 41 39 targetType(o.targetType) {} 42 40 43 41 AlternativeFinder( AlternativeFinder&& o ) 44 : indexer(o.indexer), alternatives(std::move(o.alternatives)), env(o.env), 42 : indexer(o.indexer), alternatives(std::move(o.alternatives)), env(o.env), 45 43 targetType(o.targetType) {} 46 44 47 45 AlternativeFinder& operator= ( const AlternativeFinder& o ) { 48 46 if (&o == this) return *this; 49 47 50 48 // horrific nasty hack to rebind references... 51 49 alternatives.~AltList(); … … 56 54 AlternativeFinder& operator= ( AlternativeFinder&& o ) { 57 55 if (&o == this) return *this; 58 56 59 57 // horrific nasty hack to rebind references... 60 58 alternatives.~AltList(); … … 128 126 /// Adds alternatives for offsetof expressions, given the base type and name of the member 129 127 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); 130 /// Takes a final result and checks if its assertions can be satisfied131 template<typename OutputIterator>132 void validateFunctionAlternative( const Alternative &func, ArgPack& result, const std::vector<ArgPack>& results, OutputIterator out );133 /// Finds matching alternatives for a function, given a set of arguments134 128 template<typename OutputIterator> 135 129 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const std::vector< AlternativeFinder >& args, OutputIterator out ); 136 /// Checks if assertion parameters match for a new alternative137 130 template< typename OutputIterator > 138 131 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); -
src/ResolvExpr/Resolver.cc
r1ba5803 r4d5e57b 18 18 #include <memory> // for allocator, allocator_traits<... 19 19 #include <tuple> // for get 20 #include <vector>21 20 22 21 #include "Alternative.h" // for Alternative, AltList … … 412 411 413 412 // Find all alternatives for all arguments in canonical form 414 std:: vector< AlternativeFinder > argAlternatives;413 std::list< AlternativeFinder > argAlternatives; 415 414 funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) ); 416 415 417 416 // List all combinations of arguments 418 std:: vector< AltList > possibilities;417 std::list< AltList > possibilities; 419 418 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) ); 420 419 -
src/ResolvExpr/TypeEnvironment.cc
r1ba5803 r4d5e57b 212 212 } 213 213 214 std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env ) {215 env.print( out );216 return out;217 }218 214 } // namespace ResolvExpr 219 215 -
src/ResolvExpr/TypeEnvironment.h
r1ba5803 r4d5e57b 86 86 TypeEnvironment *clone() const { return new TypeEnvironment( *this ); } 87 87 88 /// Iteratively adds the environment of a new actual (with allowWidening = false), 88 /// Iteratively adds the environment of a new actual (with allowWidening = false), 89 89 /// and extracts open variables. 90 90 void addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars ); … … 114 114 return sub.applyFree( type ); 115 115 } 116 117 std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env );118 116 } // namespace ResolvExpr 119 117 -
src/ResolvExpr/typeops.h
r1ba5803 r4d5e57b 16 16 #pragma once 17 17 18 #include <vector>19 20 18 #include "SynTree/SynTree.h" 21 19 #include "SynTree/Type.h" … … 30 28 void combos( InputIterator begin, InputIterator end, OutputIterator out ) { 31 29 typedef typename InputIterator::value_type SetType; 32 typedef typename std:: vector< typename SetType::value_type > ListType;30 typedef typename std::list< typename SetType::value_type > ListType; 33 31 34 32 if ( begin == end ) { … … 40 38 begin++; 41 39 42 std:: vector< ListType > recursiveResult;40 std::list< ListType > recursiveResult; 43 41 combos( begin, end, back_inserter( recursiveResult ) ); 44 42 45 for ( const auto& i : recursiveResult ) for ( const auto& j : *current ) { 46 ListType result; 47 std::back_insert_iterator< ListType > inserter = back_inserter( result ); 48 *inserter++ = j; 49 std::copy( i.begin(), i.end(), inserter ); 50 *out++ = result; 51 } 43 for ( typename std::list< ListType >::const_iterator i = recursiveResult.begin(); i != recursiveResult.end(); ++i ) { 44 for ( typename ListType::const_iterator j = current->begin(); j != current->end(); ++j ) { 45 ListType result; 46 std::back_insert_iterator< ListType > inserter = back_inserter( result ); 47 *inserter++ = *j; 48 std::copy( i->begin(), i->end(), inserter ); 49 *out++ = result; 50 } // for 51 } // for 52 52 } 53 53 -
src/SymTab/Autogen.cc
r1ba5803 r4d5e57b 62 62 void previsit( FunctionDecl * functionDecl ); 63 63 64 void previsit( FunctionType * ftype ); 65 void previsit( PointerType * ptype ); 66 64 67 void previsit( CompoundStmt * compoundStmt ); 65 68 … … 69 72 unsigned int functionNesting = 0; // current level of nested functions 70 73 74 InitTweak::ManagedTypes managedTypes; 71 75 std::vector< FuncData > data; 72 76 }; … … 618 622 // generate ctor/dtors/assign for typedecls, e.g., otype T = int *; 619 623 void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) { 624 visit_children = false; 620 625 if ( ! typeDecl->base ) return; 621 626 … … 623 628 TypeFuncGenerator gen( typeDecl, &refType, data, functionNesting, indexer ); 624 629 generateFunctions( gen, declsToAddAfter ); 625 630 } 631 632 void AutogenerateRoutines::previsit( FunctionType *) { 633 // ensure that we don't add assignment ops for types defined as part of the function 634 visit_children = false; 635 } 636 637 void AutogenerateRoutines::previsit( PointerType *) { 638 // ensure that we don't add assignment ops for types defined as part of the pointer 639 visit_children = false; 626 640 } 627 641 … … 631 645 } 632 646 633 void AutogenerateRoutines::previsit( FunctionDecl * ) { 634 // Track whether we're currently in a function. 635 // Can ignore function type idiosyncrasies, because function type can never 636 // declare a new type. 647 void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) { 648 visit_children = false; 649 // record the existence of this function as appropriate 650 managedTypes.handleDWT( functionDecl ); 651 652 maybeAccept( functionDecl->type, *visitor ); 637 653 functionNesting += 1; 638 GuardAction( [this]() { functionNesting -= 1; } ); 654 maybeAccept( functionDecl->statements, *visitor ); 655 functionNesting -= 1; 639 656 } 640 657 641 658 void AutogenerateRoutines::previsit( CompoundStmt * ) { 659 GuardScope( managedTypes ); 642 660 GuardScope( structsDone ); 643 661 } -
src/SymTab/Autogen.h
r1ba5803 r4d5e57b 56 56 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 57 57 template< typename OutputIterator > 58 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );58 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true ); 59 59 60 60 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 61 61 /// optionally returns a statement which must be inserted prior to the containing loop, if there is one 62 62 template< typename OutputIterator > 63 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr) {63 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, bool addCast = false ) { 64 64 bool isReferenceCtorDtor = false; 65 65 if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { … … 68 68 fname = "?=?"; 69 69 dstParam = new AddressExpr( dstParam ); 70 addCast = nullptr;70 addCast = false; 71 71 isReferenceCtorDtor = true; 72 72 } … … 83 83 // remove lvalue as a qualifier, this can change to 84 84 // type->get_qualifiers() = Type::Qualifiers(); 85 Type * castType = addCast->clone(); 85 assert( type ); 86 Type * castType = type->clone(); 86 87 castType->get_qualifiers() -= Type::Qualifiers( Type::Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 87 88 // castType->set_lvalue( true ); // xxx - might not need this … … 114 115 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 115 116 template< typename OutputIterator > 116 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {117 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) { 117 118 static UniqueName indexName( "_index" ); 118 119 119 120 // for a flexible array member nothing is done -- user must define own assignment 120 if ( ! array->get_dimension() ) return; 121 122 if ( addCast ) { 123 // peel off array layer from cast 124 ArrayType * at = strict_dynamic_cast< ArrayType * >( addCast ); 125 addCast = at->base; 126 } 121 if ( ! array->get_dimension() ) return ; 127 122 128 123 Expression * begin, * end, * update, * cmp; … … 176 171 177 172 template< typename OutputIterator > 178 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type *addCast, bool forward ) {173 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) { 179 174 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 180 175 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); … … 196 191 if ( isUnnamedBitfield( obj ) ) return; 197 192 198 Type * addCast = nullptr; 199 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) ) ) { 200 assert( dstParam->result ); 201 addCast = dstParam->result; 202 } 193 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) ); 203 194 std::list< Statement * > stmts; 204 195 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->type, addCast, forward ); -
src/SymTab/Indexer.cc
r1ba5803 r4d5e57b 567 567 } 568 568 569 void Indexer::addIds( const std::list< DeclarationWithType * > & decls ) {570 for ( auto d : decls ) {571 addId( d );572 }573 }574 575 void Indexer::addTypes( const std::list< TypeDecl * > & tds ) {576 for ( auto td : tds ) {577 addType( td );578 addIds( td->assertions );579 }580 }581 582 void Indexer::addFunctionType( FunctionType * ftype ) {583 addTypes( ftype->forall );584 addIds( ftype->returnVals );585 addIds( ftype->parameters );586 }587 588 569 void Indexer::enterScope() { 589 570 ++scope; -
src/SymTab/Indexer.h
r1ba5803 r4d5e57b 76 76 void addTrait( TraitDecl *decl ); 77 77 78 /// convenience function for adding a list of Ids to the indexer79 void addIds( const std::list< DeclarationWithType * > & decls );80 81 /// convenience function for adding a list of forall parameters to the indexer82 void addTypes( const std::list< TypeDecl * > & tds );83 84 /// convenience function for adding all of the declarations in a function type to the indexer85 void addFunctionType( FunctionType * ftype );86 87 78 bool doDebug = false; ///< Display debugging trace? 88 79 private: -
src/SymTab/Validate.cc
r1ba5803 r4d5e57b 124 124 125 125 /// Associates forward declarations of aggregates with their definitions 126 struct LinkReferenceToTypes final : public WithIndexer , public WithGuards{126 struct LinkReferenceToTypes final : public WithIndexer { 127 127 LinkReferenceToTypes( const Indexer *indexer ); 128 128 void postvisit( TypeInstType *typeInst ); … … 137 137 void postvisit( UnionDecl *unionDecl ); 138 138 void postvisit( TraitDecl * traitDecl ); 139 140 void previsit( StructDecl *structDecl );141 void previsit( UnionDecl *unionDecl );142 143 void renameGenericParams( std::list< TypeDecl * > & params );144 139 145 140 private: … … 152 147 ForwardStructsType forwardStructs; 153 148 ForwardUnionsType forwardUnions; 154 /// true if currently in a generic type body, so that type parameter instances can be renamed appropriately155 bool inGeneric = false;156 149 }; 157 150 … … 430 423 } 431 424 432 void checkGenericParameters( ReferenceToType * inst ) {433 for ( Expression * param : inst->parameters ) {434 if ( ! dynamic_cast< TypeExpr * >( param ) ) {435 throw SemanticError( "Expression parameters for generic types are currently unsupported: ", inst );436 }437 }438 }439 440 425 void LinkReferenceToTypes::postvisit( StructInstType *structInst ) { 441 426 StructDecl *st = local_indexer->lookupStruct( structInst->get_name() ); … … 449 434 forwardStructs[ structInst->get_name() ].push_back( structInst ); 450 435 } // if 451 checkGenericParameters( structInst );452 436 } 453 437 … … 462 446 forwardUnions[ unionInst->get_name() ].push_back( unionInst ); 463 447 } // if 464 checkGenericParameters( unionInst );465 448 } 466 449 … … 542 525 // need to carry over the 'sized' status of each decl in the instance 543 526 for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) { 544 TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) ); 545 if ( ! expr ) { 546 throw SemanticError( "Expression parameters for trait instances are currently unsupported: ", std::get<1>(p) ); 547 } 527 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( std::get<1>(p) ); 548 528 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) { 549 529 TypeDecl * formalDecl = std::get<0>(p); … … 566 546 } // if 567 547 } // if 568 }569 570 void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) {571 // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g.572 // forall(otype T)573 // struct Box {574 // T x;575 // };576 // forall(otype T)577 // void f(Box(T) b) {578 // ...579 // }580 // The T in Box and the T in f are different, so internally the naming must reflect that.581 GuardValue( inGeneric );582 inGeneric = ! params.empty();583 for ( TypeDecl * td : params ) {584 td->name = "__" + td->name + "_generic_";585 }586 }587 588 void LinkReferenceToTypes::previsit( StructDecl * structDecl ) {589 renameGenericParams( structDecl->parameters );590 }591 592 void LinkReferenceToTypes::previsit( UnionDecl * unionDecl ) {593 renameGenericParams( unionDecl->parameters );594 548 } 595 549 … … 621 575 622 576 void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) { 623 // ensure generic parameter instances are renamed like the base type624 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;625 577 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) { 626 578 if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) { -
src/SynTree/Expression.cc
r1ba5803 r4d5e57b 324 324 return makeSub( refType->get_base() ); 325 325 } else if ( StructInstType * aggInst = dynamic_cast< StructInstType * >( t ) ) { 326 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst-> parameters.begin() );326 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->get_parameters().begin() ); 327 327 } else if ( UnionInstType * aggInst = dynamic_cast< UnionInstType * >( t ) ) { 328 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst-> parameters.begin() );328 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->get_parameters().begin() ); 329 329 } else { 330 330 assertf( false, "makeSub expects struct or union type for aggregate, but got: %s", toString( t ).c_str() ); -
src/Tuples/TupleAssignment.cc
r1ba5803 r4d5e57b 251 251 // combine assignment environments into combined expression environment 252 252 simpleCombineEnvironments( current.begin(), current.end(), matcher->compositeEnv ); 253 // xxx -- was push_front 254 currentFinder.get_alternatives().push_back( ResolvExpr::Alternative( 253 currentFinder.get_alternatives().push_front( ResolvExpr::Alternative( 255 254 new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, 256 255 ResolvExpr::sumCost( current ) + matcher->baseCost ) ); -
src/benchmark/Makefile.am
r1ba5803 r4d5e57b 24 24 repeats = 30 25 25 TIME_FORMAT = "%E" 26 PRINT_FORMAT = %20s: #Comments needed for spacing26 PRINT_FORMAT = '%20s\t' 27 27 28 28 .NOTPARALLEL: … … 217 217 218 218 compile-array$(EXEEXT): 219 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/array.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}219 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/array.c 220 220 221 221 compile-attributes$(EXEEXT): 222 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/attributes.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}222 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/attributes.c 223 223 224 224 compile-empty$(EXEEXT): 225 @${CC} -nodebug -quiet -fsyntax-only -w compile/empty.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}225 @${CC} -nodebug -quiet -fsyntax-only -w compile/empty.c 226 226 227 227 compile-expression$(EXEEXT): 228 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/expression.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}228 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/expression.c 229 229 230 230 compile-io$(EXEEXT): 231 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/io.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}231 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/io.c 232 232 233 233 compile-monitor$(EXEEXT): 234 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/monitor.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}234 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/monitor.c 235 235 236 236 compile-operators$(EXEEXT): 237 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/operators.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}237 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/operators.c 238 238 239 239 compile-thread$(EXEEXT): 240 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/thread.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}240 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/thread.c 241 241 242 242 compile-typeof$(EXEEXT): 243 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/typeof.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}244 243 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/typeof.c 244 -
src/benchmark/Makefile.in
r1ba5803 r4d5e57b 254 254 repeats = 30 255 255 TIME_FORMAT = "%E" 256 PRINT_FORMAT = %20s: #Comments needed for spacing256 PRINT_FORMAT = '%20s\t' 257 257 all: all-am 258 258 … … 623 623 624 624 compile-array$(EXEEXT): 625 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/array.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}625 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/array.c 626 626 627 627 compile-attributes$(EXEEXT): 628 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/attributes.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}628 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/attributes.c 629 629 630 630 compile-empty$(EXEEXT): 631 @${CC} -nodebug -quiet -fsyntax-only -w compile/empty.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}631 @${CC} -nodebug -quiet -fsyntax-only -w compile/empty.c 632 632 633 633 compile-expression$(EXEEXT): 634 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/expression.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}634 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/expression.c 635 635 636 636 compile-io$(EXEEXT): 637 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/io.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}637 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/io.c 638 638 639 639 compile-monitor$(EXEEXT): 640 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/monitor.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}640 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/monitor.c 641 641 642 642 compile-operators$(EXEEXT): 643 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/operators.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}643 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/operators.c 644 644 645 645 compile-thread$(EXEEXT): 646 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/thread.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}646 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/thread.c 647 647 648 648 compile-typeof$(EXEEXT): 649 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/typeof.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}649 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/typeof.c 650 650 651 651 # Tell versions [3.59,3.63) of GNU make to not export all variables. -
src/tests/.expect/castError.txt
r1ba5803 r4d5e57b 5 5 charAlternatives are: 6 6 Cost ( 1, 0, 0, 0 ): Cast of: 7 Variable Expression: f: function 8 accepting unspecified arguments 9 ... returning nothing 10 7 Variable Expression: f: signed int 11 8 ... to: 12 9 char … … 26 23 27 24 Cost ( 1, 0, 0, 0 ): Cast of: 28 Variable Expression: f: signed int 25 Variable Expression: f: function 26 accepting unspecified arguments 27 ... returning nothing 28 29 29 ... to: 30 30 char
Note:
See TracChangeset
for help on using the changeset viewer.