Changes in / [fbcb354:2ad507b8]
- Location:
- src
- Files:
-
- 2 deleted
- 12 edited
-
ResolvExpr/AlternativeFinder.cc (modified) (2 diffs)
-
ResolvExpr/RenameVars.cc (modified) (1 diff)
-
ResolvExpr/TypeEnvironment.cc (modified) (1 diff)
-
ResolvExpr/TypeEnvironment.h (modified) (1 diff)
-
SymTab/Indexer.cc (modified) (1 diff)
-
SymTab/Validate.cc (modified) (4 diffs)
-
SynTree/Mutator.cc (modified) (1 diff)
-
SynTree/ReferenceToType.cc (modified) (1 diff)
-
SynTree/Type.h (modified) (1 diff)
-
SynTree/TypeSubstitution.h (modified) (1 diff)
-
SynTree/Visitor.cc (modified) (1 diff)
-
prelude/prelude.cf (modified) (1 diff)
-
tests/.expect/function-operator.txt (deleted)
-
tests/function-operator.c (deleted)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rfbcb354 r2ad507b8 749 749 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) { 750 750 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 751 Alternative newFunc( *func ); 752 referenceToRvalueConversion( newFunc.expr ); 751 referenceToRvalueConversion( func->expr ); 753 752 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 754 753 // XXX 755 754 //Designators::check_alternative( function, *actualAlt ); 756 makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) );755 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 757 756 } 758 757 } 759 758 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) 759 referenceToRvalueConversion( func->expr ); 760 760 EqvClass eqvClass; 761 761 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) { 762 762 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 763 Alternative newFunc( *func );764 referenceToRvalueConversion( newFunc.expr );765 763 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 766 makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) );764 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 767 765 } // for 768 766 } // if … … 775 773 if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) { 776 774 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 777 Alternative newFunc( *funcOp ); 778 referenceToRvalueConversion( newFunc.expr ); 775 referenceToRvalueConversion( funcOp->expr ); 779 776 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 780 777 AltList currentAlt; 781 778 currentAlt.push_back( *func ); 782 779 currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() ); 783 makeFunctionAlternatives( newFunc, function, currentAlt, std::back_inserter( candidates ) );780 makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) ); 784 781 } // for 785 782 } // if -
src/ResolvExpr/RenameVars.cc
rfbcb354 r2ad507b8 88 88 typeBefore( aggregateUseType ); 89 89 acceptAll( aggregateUseType->get_parameters(), *this ); 90 acceptAll( aggregateUseType->get_members(), *this ); 90 91 typeAfter( aggregateUseType ); 91 92 } -
src/ResolvExpr/TypeEnvironment.cc
rfbcb354 r2ad507b8 25 25 26 26 namespace ResolvExpr { 27 // adding this comparison operator significantly improves assertion resolution run time for 28 // some cases. The current resolution algorithm's speed partially depends on the order of 29 // assertions. Assertions which have fewer possible matches should appear before 30 // assertions which have more possible matches. This seems to imply that this could 31 // be further improved by providing an indexer as an additional argument and ordering based 32 // on the number of matches of the same kind (object, function) for the names of the 33 // declarations. 34 // 35 // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator. 36 bool AssertCompare::operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const { 37 // Objects are always less than functions 38 if ( ObjectDecl * objectDecl1 = dynamic_cast< ObjectDecl * >( d1 ) ) { 39 if ( ObjectDecl * objectDecl2 = dynamic_cast< ObjectDecl * >( d2 ) ) { 40 // objects are ordered by name then type pointer, in that order 41 int cmp = objectDecl1->get_name().compare( objectDecl2->get_name() ); 42 return cmp < 0 || 43 ( cmp == 0 && objectDecl1->get_type() < objectDecl2->get_type() ); 44 } else { 45 return true; 46 } 47 } else if ( FunctionDecl * funcDecl1 = dynamic_cast< FunctionDecl * >( d1 ) ) { 48 if ( FunctionDecl * funcDecl2 = dynamic_cast< FunctionDecl * >( d2 ) ) { 49 // functions are ordered by name, # parameters, # returnVals, type pointer in that order 50 FunctionType * ftype1 = funcDecl1->get_functionType(); 51 FunctionType * ftype2 = funcDecl2->get_functionType(); 52 int numThings1 = ftype1->get_parameters().size() + ftype1->get_returnVals().size(); 53 int numThings2 = ftype2->get_parameters().size() + ftype2->get_returnVals().size(); 54 if ( numThings1 < numThings2 ) return true; 55 if ( numThings1 > numThings2 ) return false; 56 57 // if ( ftype1->get_parameters().size() < ftype2->get_parameters().size() ) return true; 58 // else if ( ftype1->get_parameters().size() > ftype2->get_parameters().size() ) return false; 59 // // same number of parameters 60 // if ( ftype1->get_returnVals().size() < ftype2->get_returnVals().size() ) return true; 61 // else if ( ftype1->get_returnVals().size() > ftype2->get_returnVals().size() ) return false; 62 // same number of return vals 63 // int cmp = funcDecl1->get_name().compare( funcDecl2->get_name() ); 64 // if ( cmp < 0 ) return true; 65 // else if ( cmp > 0 ) return false; 66 // // same name 67 return ftype1 < ftype2; 68 } else { 69 return false; 70 } 71 } else { 72 assert( false ); 73 } 74 } 75 27 76 void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) { 28 77 for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) { -
src/ResolvExpr/TypeEnvironment.h
rfbcb354 r2ad507b8 28 28 29 29 namespace ResolvExpr { 30 // adding this comparison operator significantly improves assertion resolution run time for31 // some cases. The current resolution algorithm's speed partially depends on the order of32 // assertions. Assertions which have fewer possible matches should appear before33 // assertions which have more possible matches. This seems to imply that this could34 // be further improved by providing an indexer as an additional argument and ordering based35 // on the number of matches of the same kind (object, function) for the names of the36 // declarations.37 //38 // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.39 30 struct AssertCompare { 40 bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const { 41 int cmp = d1->get_name().compare( d2->get_name() ); 42 return cmp < 0 || 43 ( cmp == 0 && d1->get_type() < d2->get_type() ); 44 } 31 bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const; 45 32 }; 46 33 struct AssertionSetValue { -
src/SymTab/Indexer.cc
rfbcb354 r2ad507b8 554 554 555 555 556 void Indexer::visit( TraitInstType *traitInst ) { 557 acceptAll( traitInst->get_parameters(), *this ); 556 void Indexer::visit( TraitInstType *contextInst ) { 557 acceptAll( contextInst->get_parameters(), *this ); 558 acceptAll( contextInst->get_members(), *this ); 558 559 } 559 560 -
src/SymTab/Validate.cc
rfbcb354 r2ad507b8 127 127 public: 128 128 LinkReferenceToTypes( bool doDebug, const Indexer *indexer ); 129 using Parent::visit; 130 void visit( TypeInstType *typeInst ) final; 131 129 using Parent::visit; 132 130 void visit( EnumInstType *enumInst ) final; 133 131 void visit( StructInstType *structInst ) final; 134 132 void visit( UnionInstType *unionInst ) final; 135 void visit( TraitInstType *traitInst ) final; 136 133 void visit( TraitInstType *contextInst ) final; 137 134 void visit( EnumDecl *enumDecl ) final; 138 135 void visit( StructDecl *structDecl ) final; 139 136 void visit( UnionDecl *unionDecl ) final; 140 void visit( TraitDecl * traitDecl ) final; 141 137 void visit( TypeInstType *typeInst ) final; 142 138 private: 143 139 const Indexer *indexer; … … 457 453 } 458 454 459 template< typename Decl > 460 void normalizeAssertions( std::list< Decl * > & assertions ) { 461 // ensure no duplicate trait members after the clone 462 auto pred = [](Decl * d1, Decl * d2) { 463 // only care if they're equal 464 DeclarationWithType * dwt1 = dynamic_cast<DeclarationWithType *>( d1 ); 465 DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 ); 466 if ( dwt1 && dwt2 ) { 467 if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) { 468 // std::cerr << "=========== equal:" << std::endl; 469 // std::cerr << "d1: " << d1 << std::endl; 470 // std::cerr << "d2: " << d2 << std::endl; 471 return false; 472 } 455 void LinkReferenceToTypes::visit( TraitInstType *traitInst ) { 456 Parent::visit( traitInst ); 457 if ( traitInst->get_name() == "sized" ) { 458 // "sized" is a special trait with no members - just flick the sized status on for the type variable 459 if ( traitInst->get_parameters().size() != 1 ) { 460 throw SemanticError( "incorrect number of trait parameters: ", traitInst ); 473 461 } 474 return d1 < d2; 475 }; 476 std::set<Decl *, decltype(pred)> unique_members( assertions.begin(), assertions.end(), pred ); 477 // if ( unique_members.size() != assertions.size() ) { 478 // std::cerr << "============different" << std::endl; 479 // std::cerr << unique_members.size() << " " << assertions.size() << std::endl; 480 // } 481 482 std::list< Decl * > order; 483 order.splice( order.end(), assertions ); 484 std::copy_if( order.begin(), order.end(), back_inserter( assertions ), [&]( Decl * decl ) { 485 return unique_members.count( decl ); 486 }); 487 } 488 489 // expand assertions from trait instance, performing the appropriate type variable substitutions 490 template< typename Iterator > 491 void expandAssertions( TraitInstType * inst, Iterator out ) { 492 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() ); 493 std::list< DeclarationWithType * > asserts; 494 for ( Declaration * decl : inst->baseTrait->members ) { 495 asserts.push_back( safe_dynamic_cast<DeclarationWithType *>( decl->clone() ) ); 496 } 497 // substitute trait decl parameters for instance parameters 498 applySubstitution( inst->baseTrait->parameters.begin(), inst->baseTrait->parameters.end(), inst->parameters.begin(), asserts.begin(), asserts.end(), out ); 499 } 500 501 void LinkReferenceToTypes::visit( TraitDecl * traitDecl ) { 502 Parent::visit( traitDecl ); 503 504 if ( traitDecl->name == "sized" ) { 505 // "sized" is a special trait - flick the sized status on for the type variable 506 assertf( traitDecl->parameters.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", traitDecl->parameters.size() ); 507 TypeDecl * td = traitDecl->parameters.front(); 508 td->set_sized( true ); 509 } 510 511 // move assertions from type parameters into the body of the trait 512 for ( TypeDecl * td : traitDecl->parameters ) { 513 for ( DeclarationWithType * assert : td->assertions ) { 514 if ( TraitInstType * inst = dynamic_cast< TraitInstType * >( assert->get_type() ) ) { 515 expandAssertions( inst, back_inserter( traitDecl->members ) ); 516 } else { 517 traitDecl->members.push_back( assert->clone() ); 518 } 519 } 520 deleteAll( td->assertions ); 521 td->assertions.clear(); 522 } // for 523 } 524 525 void LinkReferenceToTypes::visit( TraitInstType * traitInst ) { 526 Parent::visit( traitInst ); 462 TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() ); 463 TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() ); 464 TypeDecl * decl = inst->get_baseType(); 465 decl->set_sized( true ); 466 // since "sized" is special, the next few steps don't apply 467 return; 468 } 469 527 470 // handle other traits 528 TraitDecl *traitDecl = indexer->lookupTrait( traitInst-> name);471 TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() ); 529 472 if ( ! traitDecl ) { 530 throw SemanticError( "use of undeclared trait " + traitInst-> name);473 throw SemanticError( "use of undeclared trait " + traitInst->get_name() ); 531 474 } // if 532 475 if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) { 533 476 throw SemanticError( "incorrect number of trait parameters: ", traitInst ); 534 477 } // if 535 traitInst->baseTrait = traitDecl; 478 479 for ( TypeDecl * td : traitDecl->get_parameters() ) { 480 for ( DeclarationWithType * assert : td->get_assertions() ) { 481 traitInst->get_members().push_back( assert->clone() ); 482 } // for 483 } // for 484 485 // need to clone members of the trait for ownership purposes 486 std::list< Declaration * > members; 487 std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } ); 488 489 applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) ); 536 490 537 491 // need to carry over the 'sized' status of each decl in the instance … … 544 498 } 545 499 } 546 // normalizeAssertions( traitInst->members );547 500 } 548 501 … … 608 561 void forallFixer( Type * func ) { 609 562 for ( TypeDecl * type : func->get_forall() ) { 610 std::list< DeclarationWithType * > asserts; 611 asserts.splice( asserts.end(), type->assertions ); 612 // expand trait instances into their members 613 for ( DeclarationWithType * assertion : asserts ) { 614 if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 615 // expand trait instance into all of its members 616 expandAssertions( traitInst, back_inserter( type->assertions ) ); 617 delete traitInst; 618 } else { 619 // pass other assertions through 620 type->assertions.push_back( assertion ); 621 } // if 622 } // for 623 // apply FixFunction to every assertion to check for invalid void type 624 for ( DeclarationWithType *& assertion : type->assertions ) { 625 FixFunction fixer; 626 assertion = assertion->acceptMutator( fixer ); 627 if ( fixer.get_isVoid() ) { 628 throw SemanticError( "invalid type void in assertion of function ", func ); 629 } // if 630 } // for 631 // normalizeAssertions( type->assertions ); 563 std::list< DeclarationWithType * > toBeDone, nextRound; 564 toBeDone.splice( toBeDone.end(), type->get_assertions() ); 565 while ( ! toBeDone.empty() ) { 566 for ( DeclarationWithType * assertion : toBeDone ) { 567 if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 568 // expand trait instance into all of its members 569 for ( Declaration * member : traitInst->get_members() ) { 570 DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member ); 571 nextRound.push_back( dwt->clone() ); 572 } 573 delete traitInst; 574 } else { 575 // pass assertion through 576 FixFunction fixer; 577 assertion = assertion->acceptMutator( fixer ); 578 if ( fixer.get_isVoid() ) { 579 throw SemanticError( "invalid type void in assertion of function ", func ); 580 } 581 type->get_assertions().push_back( assertion ); 582 } // if 583 } // for 584 toBeDone.clear(); 585 toBeDone.splice( toBeDone.end(), nextRound ); 586 } // while 632 587 } // for 633 588 } -
src/SynTree/Mutator.cc
rfbcb354 r2ad507b8 538 538 Type * Mutator::mutate( TraitInstType *aggregateUseType ) { 539 539 handleReferenceToType( aggregateUseType ); 540 mutateAll( aggregateUseType->get_members(), *this ); 540 541 return aggregateUseType; 541 542 } -
src/SynTree/ReferenceToType.cc
rfbcb354 r2ad507b8 132 132 std::string TraitInstType::typeString() const { return "trait"; } 133 133 134 TraitInstType::TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes ) : Parent( tq, baseTrait->name, attributes ), baseTrait( baseTrait ) {} 135 136 TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ), baseTrait( other.baseTrait ) { 134 TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ) { 135 cloneAll( other.members, members ); 137 136 } 138 137 139 138 TraitInstType::~TraitInstType() { 139 deleteAll( members ); 140 140 } 141 141 -
src/SynTree/Type.h
rfbcb354 r2ad507b8 471 471 typedef ReferenceToType Parent; 472 472 public: 473 // this decl is not "owned" by the trait inst; it is merely a pointer to elsewhere in the tree, 474 // where the trait used in this type is actually defined 475 TraitDecl * baseTrait = nullptr; 476 477 TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ) {} 478 TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 473 // this member is filled in by the validate pass, which instantiates the members of the correponding 474 // aggregate with the actual type parameters specified for this use of the context 475 std::list< Declaration* > members; 476 477 TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ) {} 479 478 TraitInstType( const TraitInstType & other ); 480 479 ~TraitInstType(); 480 481 std::list< Declaration* >& get_members() { return members; } 481 482 482 483 virtual bool isComplete() const; -
src/SynTree/TypeSubstitution.h
rfbcb354 r2ad507b8 177 177 void applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out ) { 178 178 TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual ); 179 for ( autoi = memberBegin; i != memberEnd; ++i ) {179 for ( std::list< Declaration* >::iterator i = memberBegin; i != memberEnd; ++i ) { 180 180 sub.apply( *i ); 181 181 *out++ = *i; -
src/SynTree/Visitor.cc
rfbcb354 r2ad507b8 429 429 void Visitor::visit( TraitInstType *aggregateUseType ) { 430 430 handleReferenceToType( static_cast< ReferenceToType * >( aggregateUseType ) ); 431 acceptAll( aggregateUseType->get_members(), *this ); 431 432 } 432 433 -
src/prelude/prelude.cf
rfbcb354 r2ad507b8 14 14 15 15 // Section numbers from: http://plg.uwaterloo.ca/~cforall/refrat.pdf 16 17 // ------------------------------------------------------------18 //19 // Section 6.7.11 Trait Declarations20 // Note: the sized trait is used in declarations later in this21 // file, so it must be out of order.22 //23 // ------------------------------------------------------------24 25 trait sized(dtype T) {};26 16 27 17 // ------------------------------------------------------------
Note:
See TracChangeset
for help on using the changeset viewer.