Changes in src/SymTab/Validate.cc [b128d3e:2bf9c37]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
rb128d3e r2bf9c37 127 127 public: 128 128 LinkReferenceToTypes( bool doDebug, const Indexer *indexer ); 129 using Parent::visit; 129 using Parent::visit; 130 void visit( TypeInstType *typeInst ) final; 131 130 132 void visit( EnumInstType *enumInst ) final; 131 133 void visit( StructInstType *structInst ) final; 132 134 void visit( UnionInstType *unionInst ) final; 133 void visit( TraitInstType *contextInst ) final; 135 void visit( TraitInstType *traitInst ) final; 136 134 137 void visit( EnumDecl *enumDecl ) final; 135 138 void visit( StructDecl *structDecl ) final; 136 139 void visit( UnionDecl *unionDecl ) final; 137 void visit( TypeInstType *typeInst ) final; 140 void visit( TraitDecl * traitDecl ) final; 141 138 142 private: 139 143 const Indexer *indexer; … … 287 291 288 292 HoistStruct::HoistStruct() : inStruct( false ) { 289 }290 291 void filter( std::list< Declaration * > &declList, bool (*pred)( Declaration * ), bool doDelete ) {292 std::list< Declaration * >::iterator i = declList.begin();293 while ( i != declList.end() ) {294 std::list< Declaration * >::iterator next = i;295 ++next;296 if ( pred( *i ) ) {297 if ( doDelete ) {298 delete *i;299 } // if300 declList.erase( i );301 } // if302 i = next;303 } // while304 293 } 305 294 … … 453 442 } 454 443 455 void LinkReferenceToTypes::visit( TraitInstType *traitInst ) { 444 template< typename Decl > 445 void normalizeAssertions( std::list< Decl * > & assertions ) { 446 // ensure no duplicate trait members after the clone 447 auto pred = [](Decl * d1, Decl * d2) { 448 // only care if they're equal 449 DeclarationWithType * dwt1 = dynamic_cast<DeclarationWithType *>( d1 ); 450 DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 ); 451 if ( dwt1 && dwt2 ) { 452 if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) { 453 // std::cerr << "=========== equal:" << std::endl; 454 // std::cerr << "d1: " << d1 << std::endl; 455 // std::cerr << "d2: " << d2 << std::endl; 456 return false; 457 } 458 } 459 return d1 < d2; 460 }; 461 std::set<Decl *, decltype(pred)> unique_members( assertions.begin(), assertions.end(), pred ); 462 // if ( unique_members.size() != assertions.size() ) { 463 // std::cerr << "============different" << std::endl; 464 // std::cerr << unique_members.size() << " " << assertions.size() << std::endl; 465 // } 466 467 std::list< Decl * > order; 468 order.splice( order.end(), assertions ); 469 std::copy_if( order.begin(), order.end(), back_inserter( assertions ), [&]( Decl * decl ) { 470 return unique_members.count( decl ); 471 }); 472 } 473 474 // expand assertions from trait instance, performing the appropriate type variable substitutions 475 template< typename Iterator > 476 void expandAssertions( TraitInstType * inst, Iterator out ) { 477 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() ); 478 std::list< DeclarationWithType * > asserts; 479 for ( Declaration * decl : inst->baseTrait->members ) { 480 asserts.push_back( safe_dynamic_cast<DeclarationWithType *>( decl->clone() ) ); 481 } 482 // substitute trait decl parameters for instance parameters 483 applySubstitution( inst->baseTrait->parameters.begin(), inst->baseTrait->parameters.end(), inst->parameters.begin(), asserts.begin(), asserts.end(), out ); 484 } 485 486 void LinkReferenceToTypes::visit( TraitDecl * traitDecl ) { 487 Parent::visit( traitDecl ); 488 489 if ( traitDecl->name == "sized" ) { 490 // "sized" is a special trait - flick the sized status on for the type variable 491 assertf( traitDecl->parameters.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", traitDecl->parameters.size() ); 492 TypeDecl * td = traitDecl->parameters.front(); 493 td->set_sized( true ); 494 } 495 496 // move assertions from type parameters into the body of the trait 497 for ( TypeDecl * td : traitDecl->parameters ) { 498 for ( DeclarationWithType * assert : td->assertions ) { 499 if ( TraitInstType * inst = dynamic_cast< TraitInstType * >( assert->get_type() ) ) { 500 expandAssertions( inst, back_inserter( traitDecl->members ) ); 501 } else { 502 traitDecl->members.push_back( assert->clone() ); 503 } 504 } 505 deleteAll( td->assertions ); 506 td->assertions.clear(); 507 } // for 508 } 509 510 void LinkReferenceToTypes::visit( TraitInstType * traitInst ) { 456 511 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 variable459 if ( traitInst->get_parameters().size() != 1 ) {460 throw SemanticError( "incorrect number of trait parameters: ", traitInst );461 }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 apply467 return;468 }469 470 512 // handle other traits 471 TraitDecl *traitDecl = indexer->lookupTrait( traitInst-> get_name());513 TraitDecl *traitDecl = indexer->lookupTrait( traitInst->name ); 472 514 if ( ! traitDecl ) { 473 throw SemanticError( "use of undeclared trait " + traitInst-> get_name());515 throw SemanticError( "use of undeclared trait " + traitInst->name ); 474 516 } // if 475 517 if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) { 476 518 throw SemanticError( "incorrect number of trait parameters: ", traitInst ); 477 519 } // if 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() ) ); 520 traitInst->baseTrait = traitDecl; 490 521 491 522 // need to carry over the 'sized' status of each decl in the instance … … 498 529 } 499 530 } 531 // normalizeAssertions( traitInst->members ); 500 532 } 501 533 … … 561 593 void forallFixer( Type * func ) { 562 594 for ( TypeDecl * type : func->get_forall() ) { 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 595 std::list< DeclarationWithType * > asserts; 596 asserts.splice( asserts.end(), type->assertions ); 597 // expand trait instances into their members 598 for ( DeclarationWithType * assertion : asserts ) { 599 if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 600 // expand trait instance into all of its members 601 expandAssertions( traitInst, back_inserter( type->assertions ) ); 602 delete traitInst; 603 } else { 604 // pass other assertions through 605 type->assertions.push_back( assertion ); 606 } // if 607 } // for 608 // apply FixFunction to every assertion to check for invalid void type 609 for ( DeclarationWithType *& assertion : type->assertions ) { 610 FixFunction fixer; 611 assertion = assertion->acceptMutator( fixer ); 612 if ( fixer.get_isVoid() ) { 613 throw SemanticError( "invalid type void in assertion of function ", func ); 614 } // if 615 } // for 616 // normalizeAssertions( type->assertions ); 587 617 } // for 588 618 } … … 752 782 CompoundStmt *ret = Mutator::mutate( compoundStmt ); 753 783 scopeLevel -= 1; 754 std::list< Statement * >::iterator i = compoundStmt->get_kids().begin(); 755 while ( i != compoundStmt->get_kids().end() ) { 756 std::list< Statement * >::iterator next = i+1; 757 if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( *i ) ) { 784 // remove and delete decl stmts 785 filter( compoundStmt->kids, [](Statement * stmt) { 786 if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { 758 787 if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) { 759 delete *i; 760 compoundStmt->get_kids().erase( i ); 788 return true; 761 789 } // if 762 790 } // if 763 i = next;764 } // while791 return false; 792 }, true); 765 793 typedefNames.endScope(); 766 794 return ret; … … 771 799 template<typename AggDecl> 772 800 AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) { 773 std::list<Declaration *>::iterator it = aggDecl->get_members().begin(); 774 for ( ; it != aggDecl->get_members().end(); ) { 775 std::list< Declaration * >::iterator next = it+1; 776 if ( dynamic_cast< TypedefDecl * >( *it ) ) { 777 delete *it; 778 aggDecl->get_members().erase( it ); 779 } // if 780 it = next; 781 } 801 filter( aggDecl->members, isTypedef, true ); 782 802 return aggDecl; 783 803 }
Note: See TracChangeset
for help on using the changeset viewer.