Changeset 4e08a54 for src/ResolvExpr
- Timestamp:
- Apr 19, 2024, 12:01:34 PM (23 months ago)
- Branches:
- master, stuck-waitfor-destruct
- Children:
- b9b6efb
- Parents:
- da87eaf (diff), 02c80cdc (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src/ResolvExpr
- Files:
-
- 9 edited
-
CandidateFinder.cpp (modified) (13 diffs)
-
CandidateFinder.hpp (modified) (2 diffs)
-
CommonType.cc (modified) (11 diffs)
-
ConversionCost.cc (modified) (12 diffs)
-
ConversionCost.h (modified) (1 diff)
-
PtrsCastable.cc (modified) (1 diff)
-
ResolveTypeof.cc (modified) (2 diffs)
-
Resolver.cc (modified) (4 diffs)
-
Unify.cc (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CandidateFinder.cpp
rda87eaf r4e08a54 284 284 const CodeLocation & location, 285 285 const ast::Type * paramType, const ast::Init * init, const ExplodedArgs & args, 286 std::vector< ArgPack > & results, std::size_t & genStart, const ast::SymbolTable & symtab,286 std::vector< ArgPack > & results, std::size_t & genStart, const ResolveContext & context, 287 287 unsigned nTuples = 0 288 288 ) { … … 294 294 // ^^^ need to handle the case where a tuple has a default argument 295 295 if ( ! instantiateArgument( location, 296 type, nullptr, args, results, genStart, symtab, nTuples ) ) return false;296 type, nullptr, args, results, genStart, context, nTuples ) ) return false; 297 297 nTuples = 0; 298 298 } … … 509 509 510 510 // attempt to unify types 511 if ( unify( paramType, argType, env, need, have, open ) ) { 511 ast::ptr<ast::Type> common; 512 if ( unify( paramType, argType, env, need, have, open, common ) ) { 512 513 // add new result 513 results.emplace_back( 514 i, expr, std::move( env ), std::move( need ), std::move( have ), std::move( open ), 515 nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 514 assert( common ); 515 results.emplace_back( 516 i, expr, std::move( env ), std::move( need ), std::move( have ), std::move( open ), 517 nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 518 //} 516 519 } 517 520 } … … 785 788 auto obj = funcDecl->params[i].strict_as<ast::ObjectDecl>(); 786 789 if ( !instantiateArgument( location, 787 funcType->params[i], obj->init, args, results, genStart, symtab)) return;790 funcType->params[i], obj->init, args, results, genStart, context)) return; 788 791 } 789 792 goto endMatch; … … 795 798 // no default args for indirect calls 796 799 if ( !instantiateArgument( location, 797 param, nullptr, args, results, genStart, symtab) ) return;800 param, nullptr, args, results, genStart, context ) ) return; 798 801 } 799 802 … … 890 893 } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) { 891 894 addAggMembers( unionInst, aggrExpr, *cand, Cost::unsafe, "" ); 892 } 893 else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) { 894 if (enumInst->base && enumInst->base->base) { 895 const CodeLocation &location = cand->expr->location; 896 897 CandidateFinder funcFinder(context, tenv); 898 auto nameExpr = new ast::NameExpr(location, "valueE"); 899 ResolveMode mode = {true, false, selfFinder.candidates.empty()}; 900 funcFinder.find( nameExpr, mode ); 901 902 // make variableExpr itself the candidate for the value Call 903 ExplodedArgs argExpansions; 904 argExpansions.emplace_back(); 905 auto &argE = argExpansions.back(); 906 907 argE.emplace_back(*cand, symtab); // Use the typed name expr as param for value 908 909 CandidateList found; 910 SemanticErrorException errors; 911 912 for (CandidateRef &func : funcFinder) { 913 try { 914 const ast::Type *funcResult = 915 func->expr->result->stripReferences(); 916 if (auto pointer = dynamic_cast<const ast::PointerType *>( 917 funcResult)) { 918 if (auto function = 919 pointer->base.as<ast::FunctionType>()) { 920 CandidateRef newFunc{new Candidate{*func}}; 921 newFunc->expr = referenceToRvalueConversion( 922 newFunc->expr, newFunc->cost); 923 makeFunctionCandidates( location, 924 newFunc, function, 925 argExpansions, found ); 926 } 927 } 928 } catch (SemanticErrorException &e) { 929 std::cerr 930 << "Resolving value function should cause an error" 931 << std::endl; 932 errors.append(e); 933 } 934 } 935 936 if (found.empty()) { 937 std::cerr << "Resolve value function should always success" 938 << std::endl; 939 } 940 941 for (CandidateRef &withFunc : found) { 942 withFunc->cost.incSafe(); 943 Cost cvtCost = 944 computeApplicationConversionCost(withFunc, symtab); 945 assert(cvtCost != Cost::infinity); 946 947 candidates.emplace_back(std::move(withFunc)); 948 } 949 } 895 } else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) { 896 if ( enumInst->base->base ) { 897 CandidateFinder finder( context, tenv ); 898 auto location = aggrExpr->location; 899 auto callExpr = new ast::UntypedExpr( 900 location, new ast::NameExpr( location, "valueE" ), {aggrExpr} 901 ); 902 finder.find( callExpr ); 903 CandidateList winners = findMinCost( finder.candidates ); 904 if (winners.size() != 1) { 905 SemanticError( callExpr, "Ambiguous expression in valueE..." ); 906 } 907 CandidateRef & choice = winners.front(); 908 choice->cost.incVar(); 909 candidates.emplace_back( std::move(choice) ); 910 } 911 950 912 } 951 913 } … … 1414 1376 ast::Expr * newExpr = data.combine( nameExpr->location, cost ); 1415 1377 1378 bool bentConversion = false; 1379 if ( auto inst = newExpr->result.as<ast::EnumInstType>() ) { 1380 if ( inst->base && inst->base->base ) { 1381 bentConversion = true; 1382 } 1383 } 1384 1416 1385 CandidateRef newCand = std::make_shared<Candidate>( 1417 newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero,1386 newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, bentConversion? Cost::safe: Cost::zero, 1418 1387 cost ); 1419 1388 … … 1448 1417 auto cand = new Candidate(variableExpr, tenv); 1449 1418 candidates.emplace_back(cand); 1450 1451 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(1452 variableExpr->var->get_type())) {1453 if (enumInst->base && enumInst->base->base) {1454 const CodeLocation &location = cand->expr->location;1455 1456 CandidateFinder funcFinder(context, tenv);1457 auto nameExpr = new ast::NameExpr(location, "valueE");1458 ResolveMode mode = {true, false, selfFinder.candidates.empty()};1459 funcFinder.find( nameExpr, mode );1460 1461 // make variableExpr itself the candidate for the value Call1462 ExplodedArgs argExpansions;1463 argExpansions.emplace_back();1464 auto &argE = argExpansions.back();1465 1466 argE.emplace_back(*cand, symtab);1467 1468 CandidateList found;1469 SemanticErrorException errors;1470 1471 for (CandidateRef &func : funcFinder) {1472 try {1473 const ast::Type *funcResult =1474 func->expr->result->stripReferences();1475 if (auto pointer = dynamic_cast<const ast::PointerType *>(1476 funcResult)) {1477 if (auto function =1478 pointer->base.as<ast::FunctionType>()) {1479 CandidateRef newFunc{new Candidate{*func}};1480 newFunc->expr = referenceToRvalueConversion(1481 newFunc->expr, newFunc->cost);1482 makeFunctionCandidates(variableExpr->location,1483 newFunc, function,1484 argExpansions, found);1485 }1486 }1487 } catch (SemanticErrorException &e) {1488 std::cerr1489 << "Resolving value function should cause an error"1490 << std::endl;1491 errors.append(e);1492 }1493 }1494 1495 if (found.empty()) {1496 std::cerr << "Resolve value function should always success"1497 << std::endl;1498 }1499 1500 for (CandidateRef &withFunc : found) {1501 withFunc->cost.incSafe();1502 Cost cvtCost =1503 computeApplicationConversionCost(withFunc, symtab);1504 assert(cvtCost != Cost::infinity);1505 1506 candidates.emplace_back(std::move(withFunc));1507 }1508 }1509 }1510 1419 } 1511 1420 … … 1839 1748 1840 1749 // unification run for side-effects 1841 bool canUnify = unify( toType, cand->expr->result, env, need, have, open ); 1750 ast::ptr<ast::Type> common; 1751 bool canUnify = unify( toType, cand->expr->result, env, need, have, open, common ); 1842 1752 (void) canUnify; 1843 1753 Cost thisCost = computeConversionCost( cand->expr->result, toType, cand->expr->get_lvalue(), … … 1864 1774 // ambiguous case, still output candidates to print in error message 1865 1775 if ( cand->cost == minExprCost && thisCost == minCastCost ) { 1866 CandidateRef newCand = std::make_shared<Candidate>( 1867 new ast::InitExpr{ 1868 initExpr->location, 1869 restructureCast( cand->expr, toType ), 1870 initAlt.designation }, 1871 std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost ); 1872 // currently assertions are always resolved immediately so this should have no effect. 1873 // if this somehow changes in the future (e.g. delayed by indeterminate return type) 1874 // we may need to revisit the logic. 1875 inferParameters( newCand, matches ); 1776 auto commonAsEnumAttr = common.as<ast::EnumAttrType>(); 1777 if ( commonAsEnumAttr && commonAsEnumAttr->attr == ast::EnumAttribute::Value ) { 1778 auto callExpr = new ast::UntypedExpr( 1779 cand->expr->location, new ast::NameExpr( cand->expr->location, "valueE"), {cand->expr} ); 1780 CandidateFinder finder( context, env ); 1781 finder.find( callExpr ); 1782 CandidateList winners = findMinCost( finder.candidates ); 1783 if (winners.size() != 1) { 1784 SemanticError( callExpr, "Ambiguous expression in valueE..." ); 1785 } 1786 CandidateRef & choice = winners.front(); 1787 // assert( valueCall->result ); 1788 CandidateRef newCand = std::make_shared<Candidate>( 1789 new ast::InitExpr{ 1790 initExpr->location, 1791 // restructureCast( cand->expr, toType ), 1792 choice->expr, 1793 initAlt.designation }, 1794 std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost ); 1795 inferParameters( newCand, matches ); 1796 } else { 1797 CandidateRef newCand = std::make_shared<Candidate>( 1798 new ast::InitExpr{ 1799 initExpr->location, 1800 restructureCast( cand->expr, toType ), 1801 initAlt.designation }, 1802 std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost ); 1803 // currently assertions are always resolved immediately so this should have no effect. 1804 // if this somehow changes in the future (e.g. delayed by indeterminate return type) 1805 // we may need to revisit the logic. 1806 inferParameters( newCand, matches ); 1807 } 1876 1808 } 1877 1809 } … … 1900 1832 std::make_shared<Candidate>( 1901 1833 newExpr, copy( tenv ), ast::OpenVarSet{}, 1902 ast::AssertionSet{}, Cost:: zero, cost1834 ast::AssertionSet{}, Cost::safe, cost 1903 1835 ); 1904 1836 … … 2200 2132 } 2201 2133 2134 // get the valueE(...) ApplicationExpr that returns the enum value 2135 const ast::Expr * getValueEnumCall( 2136 const ast::Expr * expr, 2137 const ResolvExpr::ResolveContext & context, const ast::TypeEnvironment & env ) { 2138 auto callExpr = new ast::UntypedExpr( 2139 expr->location, new ast::NameExpr( expr->location, "valueE"), {expr} ); 2140 CandidateFinder finder( context, env ); 2141 finder.find( callExpr ); 2142 CandidateList winners = findMinCost( finder.candidates ); 2143 if (winners.size() != 1) { 2144 SemanticError( callExpr, "Ambiguous expression in valueE..." ); 2145 } 2146 CandidateRef & choice = winners.front(); 2147 return choice->expr; 2148 } 2149 2202 2150 const ast::Expr * createCondExpr( const ast::Expr * expr ) { 2203 2151 assert( expr ); … … 2212 2160 } 2213 2161 ), 2214 new ast::BasicType( ast::Basic Type::SignedInt )2162 new ast::BasicType( ast::BasicKind::SignedInt ) 2215 2163 ); 2216 2164 } -
src/ResolvExpr/CandidateFinder.hpp
rda87eaf r4e08a54 30 30 struct CandidateFinder { 31 31 CandidateList candidates; ///< List of candidate resolutions 32 const ResolveContext & context; ///< Information about where the canditates are being found.32 const ResolveContext & context; ///< Information about where the canditates are being found. 33 33 const ast::TypeEnvironment & env; ///< Substitutions performed in this resolution 34 34 ast::ptr< ast::Type > targetType; ///< Target type for resolution 35 35 bool strictMode = false; ///< If set to true, requires targetType to be exact match (inside return cast) 36 36 bool allowVoid = false; ///< If set to true, allow void-returning function calls (only top level, cast to void and first in comma) 37 std::set< std::string > otypeKeys; ///different type may map to same key37 std::set< std::string > otypeKeys; ///< different type may map to same key 38 38 39 39 CandidateFinder( … … 70 70 const ast::Expr * expr, Cost & cost ); 71 71 72 /// Get the valueE application that returns the enum's value. 73 const ast::Expr * getValueEnumCall( const ast::Expr * expr, 74 const ResolveContext & context, const ast::TypeEnvironment & env ); 75 72 76 /// Wrap an expression to convert the result to a conditional result. 73 77 const ast::Expr * createCondExpr( const ast::Expr * expr ); -
src/ResolvExpr/CommonType.cc
rda87eaf r4e08a54 38 38 // GENERATED START, DO NOT EDIT 39 39 // GENERATED BY BasicTypes-gen.cc 40 #define BT ast::Basic Type::41 static const BTKind commonTypes[BT NUMBER_OF_BASIC_TYPES][BT NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor40 #define BT ast::BasicKind:: 41 static const ast::BasicKind commonTypes[BT NUMBER_OF_BASIC_TYPES][BT NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor 42 42 /* B C SC UC SI SUI 43 43 I UI LI LUI LLI LLUI … … 339 339 // GENERATED END 340 340 static_assert( 341 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == ast::Basic Type::NUMBER_OF_BASIC_TYPES * ast::BasicType::NUMBER_OF_BASIC_TYPES,341 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES, 342 342 "Each basic type kind should have a corresponding row in the combined type matrix" 343 343 ); … … 366 366 void postvisit( const ast::BasicType * basic ) { 367 367 if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) { 368 ast::Basic Type::Kind kind;368 ast::BasicKind kind; 369 369 if (basic->kind != basic2->kind && !widen.first && !widen.second) return; 370 370 else if (!widen.first) kind = basic->kind; // widen.second … … 385 385 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { 386 386 const ast::EnumDecl* enumDecl = enumInst->base; 387 if ( enumDecl->base ) { 388 result = enumDecl->base.get(); 389 } else { 390 ast::BasicType::Kind kind = commonTypes[ basic->kind ][ ast::BasicType::SignedInt ]; 387 if ( !enumDecl->base ) { 388 ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ]; 391 389 if ( 392 390 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) … … 398 396 } 399 397 } 400 } else if ( dynamic_cast< const ast::EnumPosType * >( type2 ) ) { 401 ast::BasicType::Kind kind = commonTypes[ basic->kind ][ ast::BasicType::SignedInt ]; 402 if ( 403 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 404 || widen.first ) 405 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 406 || widen.second ) 407 ) { 408 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; 409 } 398 } else if ( auto type2AsAttr = dynamic_cast< const ast::EnumAttrType * >( type2 ) ) { 399 if ( type2AsAttr->attr == ast::EnumAttribute::Posn ) { 400 ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ]; 401 if ( 402 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 403 || widen.first ) 404 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 405 || widen.second ) 406 ) { 407 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; 408 } 409 } 410 410 } 411 411 } … … 426 426 result = voidPtr; 427 427 add_qualifiers( result, oPtr->qualifiers ); 428 }429 430 // For a typed enum, we want to unify type1 with the base type of the enum431 bool tryResolveWithTypedEnum( const ast::Type * type1 ) {432 if (auto enumInst = dynamic_cast<const ast::EnumInstType *> (type2) ) {433 ast::OpenVarSet newOpen{ open };434 if (enumInst->base->base435 && unifyExact(type1, enumInst->base->base, tenv, need, have, newOpen, widen)) {436 result = type1;437 return true;438 }439 }440 return false;441 428 } 442 429 … … 607 594 result = pointer; 608 595 add_qualifiers( result, type2->qualifiers ); 609 } else { 610 tryResolveWithTypedEnum( pointer ); 611 } 612 } 613 614 void postvisit( const ast::ArrayType * arr ) { 615 // xxx - does it make sense? 616 tryResolveWithTypedEnum( arr ); 617 } 596 } 597 } 598 599 void postvisit( const ast::ArrayType * ) {} 618 600 619 601 void postvisit( const ast::ReferenceType * ref ) { … … 659 641 } 660 642 661 void postvisit( const ast::FunctionType * func) { 662 tryResolveWithTypedEnum( func ); 663 } 664 665 void postvisit( const ast::StructInstType * inst ) { 666 tryResolveWithTypedEnum( inst ); 667 } 668 669 void postvisit( const ast::UnionInstType * inst ) { 670 tryResolveWithTypedEnum( inst ); 671 } 643 void postvisit( const ast::FunctionType * ) {} 644 645 void postvisit( const ast::StructInstType * ) {} 646 647 void postvisit( const ast::UnionInstType * ) {} 672 648 673 649 void postvisit( const ast::EnumInstType * enumInst ) { 674 // if ( dynamic_cast<const ast::EnumPosType *>(enumInst) ) { 675 // result = enumInst; 676 // } else 677 if (!dynamic_cast<const ast::EnumInstType *>(type2)) { 678 result = commonType( type2, enumInst, tenv, need, have, open, widen); 679 } 680 } 681 682 void postvisit( const ast::EnumPosType * enumPos ) { 683 if ( auto type2AsPos = dynamic_cast<const ast::EnumPosType *>(type2) ) { 684 // result = commonType( type2AsPos->instance, enumPos->instance, tenv, need, have, open, widen ); 685 // result = enumPos; 686 if ( enumPos->instance->base->name == type2AsPos->instance->base->name ) { 687 result = type2; 688 } 689 } else if ( dynamic_cast<const ast::BasicType *>(type2) ) { 690 result = type2; 691 } 692 } 650 if ( enumInst->base && !enumInst->base->base ) { 651 auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt ); 652 result = commonType( basicType, type2, tenv, need, have, open, widen); 653 } 654 } 655 656 void postvisit( const ast::EnumAttrType * ) {} 693 657 694 658 void postvisit( const ast::TraitInstType * ) {} … … 696 660 void postvisit( const ast::TypeInstType * ) {} 697 661 698 void postvisit( const ast::TupleType * tuple ) { 699 tryResolveWithTypedEnum( tuple ); 700 } 662 void postvisit( const ast::TupleType * ) {} 701 663 702 664 void postvisit( const ast::VarArgsType * ) {} … … 712 674 } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) { 713 675 result = new ast::BasicType{ 714 ast::Basic Type::SignedInt, zero->qualifiers | type2->qualifiers };676 ast::BasicKind::SignedInt, zero->qualifiers | type2->qualifiers }; 715 677 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { 716 678 const ast::EnumDecl * enumDecl = enumInst->base; 717 if ( enumDecl->base ) { 718 if ( tryResolveWithTypedEnum( zero ) ) 719 add_qualifiers( result, zero->qualifiers ); 720 } else { 679 if ( !enumDecl->base ) { 721 680 if ( widen.second || zero->qualifiers <= type2->qualifiers ) { 722 681 result = type2; … … 736 695 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { 737 696 result = new ast::BasicType{ 738 ast::Basic Type::SignedInt, one->qualifiers | type2->qualifiers };697 ast::BasicKind::SignedInt, one->qualifiers | type2->qualifiers }; 739 698 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { 740 const ast::EnumDecl * enumBase = enumInst->base; 741 if ( enumBase->base ) { 742 if ( tryResolveWithTypedEnum( one )) 743 add_qualifiers( result, one->qualifiers ); 744 } else { 699 const ast::EnumDecl * enumDecl = enumInst->base; 700 if ( !enumDecl->base ) { 745 701 if ( widen.second || one->qualifiers <= type2->qualifiers ) { 746 702 result = type2; -
src/ResolvExpr/ConversionCost.cc
rda87eaf r4e08a54 59 59 // GENERATED START, DO NOT EDIT 60 60 // GENERATED BY BasicTypes-gen.cc 61 static const int costMatrix[ast::Basic Type::NUMBER_OF_BASIC_TYPES][ast::BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node61 static const int costMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // path length from root to node 62 62 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 63 63 /* B */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 16, 18, 17, }, … … 101 101 // GENERATED END 102 102 static_assert( 103 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == ast::Basic Type::NUMBER_OF_BASIC_TYPES * ast::BasicType::NUMBER_OF_BASIC_TYPES,103 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES, 104 104 "Missing row in the cost matrix" 105 105 ); … … 107 107 // GENERATED START, DO NOT EDIT 108 108 // GENERATED BY BasicTypes-gen.cc 109 static const int signMatrix[ast::Basic Type::NUMBER_OF_BASIC_TYPES][ast::BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion109 static const int signMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion 110 110 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 111 111 /* B */ { 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, … … 148 148 // GENERATED END 149 149 static_assert( 150 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == ast::Basic Type::NUMBER_OF_BASIC_TYPES * ast::BasicType::NUMBER_OF_BASIC_TYPES,150 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES, 151 151 "Missing row in the sign matrix" 152 152 ); … … 278 278 if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) { 279 279 conversionCostFromBasicToBasic( basicType, dstAsBasic ); 280 } 281 else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 282 auto enumDecl = enumInst->base; 283 if ( enumDecl->base.get() ) { 284 // cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env ); 285 // cost.incUnsafe(); 286 cost = Cost::infinity; 287 } else { 288 cost = Cost::unsafe; 289 } 290 } else if ( dynamic_cast< const ast::EnumPosType *>(dst) ) { 291 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) }; 280 } else if ( dynamic_cast< const ast::EnumAttrType *>(dst) ) { 281 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) }; 292 282 cost = costCalc( basicType, integer, srcIsLvalue, symtab, env ); 283 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 284 if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) { 285 cost = Cost::zero; 286 cost.incUnsafe(); 287 } 293 288 } 294 289 } … … 366 361 } 367 362 368 void ConversionCost::postvisit( const ast::EnumInstType * ) { 369 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) }; 363 void ConversionCost::postvisit( const ast::EnumInstType * inst ) { 364 if ( auto dstAsInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) { 365 if (inst->base && dstAsInst->base) { 366 if (inst->base->name == dstAsInst->base->name) { 367 cost = Cost::zero; 368 return; 369 } 370 } 371 return; 372 } 373 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) }; 370 374 cost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 371 375 if ( cost < Cost::unsafe ) { … … 374 378 } 375 379 376 void ConversionCost::postvisit( const ast::EnumPosType * src ) { 377 if ( dynamic_cast<const ast::EnumPosType *>( dst ) ) { 378 // cost = costCalc( src->instance, dstBase->instance, srcIsLvalue, symtab, env ); 379 // if ( cost < Cost::unsafe ) cost.incSafe(); 380 cost = Cost::zero; 381 } else if ( auto dstBase = dynamic_cast<const ast::EnumInstType *>( dst ) ) { 382 cost = costCalc( src->instance, dstBase, srcIsLvalue, symtab, env ); 383 if ( cost < Cost::unsafe ) cost.incSafe(); 384 } else { 385 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) }; 386 cost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 387 if ( cost < Cost::unsafe ) { 388 cost.incSafe(); 389 } 390 } 391 380 void ConversionCost::postvisit( const ast::EnumAttrType * src ) { 381 auto dstAsEnumAttrType = dynamic_cast<const ast::EnumAttrType *>(dst); 382 assert( src->attr != ast::EnumAttribute::Label ); 383 if ( src->attr == ast::EnumAttribute::Value ) { 384 if ( dstAsEnumAttrType && dstAsEnumAttrType->attr == ast::EnumAttribute::Value) { 385 cost = costCalc( src->instance, dstAsEnumAttrType->instance, srcIsLvalue, symtab, env ); 386 } else { 387 auto baseType = src->instance->base->base; 388 cost = costCalc( baseType, dst, srcIsLvalue, symtab, env ); 389 if ( cost < Cost::infinity ) { 390 cost.incUnsafe(); 391 } 392 } 393 } else { // ast::EnumAttribute::Posn 394 if ( auto dstBase = dynamic_cast<const ast::EnumInstType *>( dst ) ) { 395 cost = costCalc( src->instance, dstBase, srcIsLvalue, symtab, env ); 396 if ( cost < Cost::unsafe ) cost.incSafe(); 397 } else { 398 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) }; 399 cost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 400 if ( cost < Cost::unsafe ) { 401 cost.incSafe(); 402 } 403 } 404 } 392 405 } 393 406 … … 448 461 } else if ( const ast::BasicType * dstAsBasic = 449 462 dynamic_cast< const ast::BasicType * >( dst ) ) { 450 int tableResult = costMatrix[ ast::Basic Type::SignedInt ][ dstAsBasic->kind ];463 int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ]; 451 464 if ( -1 == tableResult ) { 452 465 cost = Cost::unsafe; … … 454 467 cost = Cost::zero; 455 468 cost.incSafe( tableResult + 1 ); 456 cost.incSign( signMatrix[ ast::Basic Type::SignedInt ][ dstAsBasic->kind ] );469 cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] ); 457 470 } 458 471 // this has the effect of letting any expr such as x+0, x+1 to be typed … … 466 479 cost.incSafe( maxIntCost + 2 ); 467 480 // assuming 0p is supposed to be used for pointers? 481 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 482 if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) { 483 cost = Cost::zero; 484 cost.incUnsafe(); 485 } 468 486 } 469 487 } … … 475 493 } else if ( const ast::BasicType * dstAsBasic = 476 494 dynamic_cast< const ast::BasicType * >( dst ) ) { 477 int tableResult = costMatrix[ ast::Basic Type::SignedInt ][ dstAsBasic->kind ];495 int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ]; 478 496 if ( -1 == tableResult ) { 479 497 cost = Cost::unsafe; … … 481 499 cost = Cost::zero; 482 500 cost.incSafe( tableResult + 1 ); 483 cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] ); 501 cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] ); 502 } 503 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 504 if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) { 505 cost = Cost::zero; 506 cost.incUnsafe(); 484 507 } 485 508 } -
src/ResolvExpr/ConversionCost.h
rda87eaf r4e08a54 72 72 void postvisit( const ast::ZeroType * zeroType ); 73 73 void postvisit( const ast::OneType * oneType ); 74 void postvisit( const ast::Enum PosType * posType );74 void postvisit( const ast::EnumAttrType * posType ); 75 75 private: 76 76 // refactor for code resue -
src/ResolvExpr/PtrsCastable.cc
rda87eaf r4e08a54 100 100 result = 1; 101 101 } else if ( auto bt = dynamic_cast< const ast::BasicType * >( dst ) ) { 102 if ( bt->kind == ast::Basic Type::SignedInt ) {102 if ( bt->kind == ast::BasicKind::SignedInt ) { 103 103 result = 0; 104 104 } else { -
src/ResolvExpr/ResolveTypeof.cc
rda87eaf r4e08a54 63 63 if ( newType.as< ast::EnumInstType >() ) { 64 64 newType = new ast::BasicType( 65 ast::Basic Type::SignedInt, newType->qualifiers, copy(newType->attributes) );65 ast::BasicKind::SignedInt, newType->qualifiers, copy(newType->attributes) ); 66 66 } 67 67 reset_qualifiers( … … 91 91 auto mutType = mutate(arrayType); 92 92 auto globalSizeType = context.global.sizeType; 93 ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType( ast::BasicType::LongUnsignedInt);93 ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType( ast::BasicKind::LongUnsignedInt ); 94 94 mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, context ); 95 95 -
src/ResolvExpr/Resolver.cc
rda87eaf r4e08a54 351 351 bool isCharType( const ast::Type * t ) { 352 352 if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) { 353 return bt->kind == ast::Basic Type::Char354 || bt->kind == ast::Basic Type::SignedChar355 || bt->kind == ast::Basic Type::UnsignedChar;353 return bt->kind == ast::BasicKind::Char 354 || bt->kind == ast::BasicKind::SignedChar 355 || bt->kind == ast::BasicKind::UnsignedChar; 356 356 } 357 357 return false; … … 458 458 if (attr->params.size() == 1) { 459 459 auto arg = attr->params.front(); 460 auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::Basic Type::LongLongSignedInt ), context );460 auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicKind::LongLongSignedInt ), context ); 461 461 auto result = eval(arg); 462 462 … … 624 624 objectDecl = fixObjectType( objectDecl, context ); 625 625 currentObject = ast::CurrentObject{ 626 objectDecl->location, new ast::BasicType{ ast::Basic Type::SignedInt } };626 objectDecl->location, new ast::BasicType{ ast::BasicKind::SignedInt } }; 627 627 } 628 628 } else { … … 1095 1095 // resolve the timeout as a size_t, the conditions like IfStmt, and stmts normally 1096 1096 ast::ptr< ast::Type > target = 1097 new ast::BasicType{ ast::Basic Type::LongLongUnsignedInt };1097 new ast::BasicType{ ast::BasicKind::LongLongUnsignedInt }; 1098 1098 auto timeout_time = findSingleExpression( stmt->timeout_time, target, context ); 1099 1099 auto timeout_cond = findCondExpression( stmt->timeout_cond, context ); -
src/ResolvExpr/Unify.cc
rda87eaf r4e08a54 274 274 void previsit( const ast::Node * ) { visit_children = false; } 275 275 276 void postvisit( const ast::VoidType * ) { 277 result = dynamic_cast< const ast::VoidType * >( type2 ); 276 void postvisit( const ast::VoidType * vt) { 277 result = dynamic_cast< const ast::VoidType * >( type2 ) 278 || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden()); 279 ; 278 280 } 279 281 … … 282 284 result = basic->kind == basic2->kind; 283 285 } 286 result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden()); 284 287 } 285 288 … … 290 293 noWiden()); 291 294 } 295 result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden()); 292 296 } 293 297 … … 307 311 308 312 result = unifyExact( 309 array->base, array2->base, tenv, need, have, open, noWiden()); 313 array->base, array2->base, tenv, need, have, open, noWiden()) 314 || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden()); 310 315 } 311 316 … … 399 404 } 400 405 406 bool tryToUnifyWithEnumValue( const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 407 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 408 WidenMode widen) { 409 if ( auto attrType2 = dynamic_cast<const ast::EnumAttrType *>(type2)) { 410 if (attrType2->attr == ast::EnumAttribute::Value) { 411 return unifyExact( type1, attrType2->instance->base->base, env, need, have, open, 412 widen); 413 } else if (attrType2->attr == ast::EnumAttribute::Posn) { 414 return unifyExact( type1, attrType2->instance, env, need, have, open, widen ); 415 } 416 } 417 return false; 418 } 419 401 420 public: 402 421 void postvisit( const ast::FunctionType * func ) { … … 507 526 void postvisit( const ast::StructInstType * aggrType ) { 508 527 handleGenericRefType( aggrType, type2 ); 528 result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden()); 509 529 } 510 530 511 531 void postvisit( const ast::UnionInstType * aggrType ) { 512 532 handleGenericRefType( aggrType, type2 ); 533 result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden()); 513 534 } 514 535 515 536 void postvisit( const ast::EnumInstType * aggrType ) { 516 537 handleRefType( aggrType, type2 ); 517 } 518 519 void postvisit( const ast::EnumPosType * posType ) { 538 result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden()); 539 } 540 541 void postvisit( const ast::EnumAttrType * enumAttr ) { 520 542 // Lazy approach for now 521 auto otherPos = dynamic_cast< const ast::EnumPosType *>(type2);522 if ( otherPos) {523 if ( otherPos->instance->base->name == posType->instance->base->name )524 result = otherPos;525 } 543 if ( auto otherPos = dynamic_cast< const ast::EnumAttrType *>(type2) ) { 544 if ( enumAttr->match(otherPos) ) { 545 result = otherPos; 546 } 547 } 526 548 } 527 549 528 550 void postvisit( const ast::TraitInstType * aggrType ) { 529 551 handleRefType( aggrType, type2 ); 552 result = result || tryToUnifyWithEnumValue(aggrType, type2, tenv, need, have, open, noWiden()); 530 553 } 531 554 … … 536 559 this->result = otherInst; 537 560 } 561 result = result || tryToUnifyWithEnumValue(typeInst, type2, tenv, need, have, open, noWiden()); 538 562 } 539 563 … … 610 634 auto types2 = flatten( flat2 ); 611 635 612 result = unifyList( types, types2, tenv, need, have, open ); 613 } 614 615 void postvisit( const ast::VarArgsType * ) { 616 result = dynamic_cast< const ast::VarArgsType * >( type2 ); 617 } 618 619 void postvisit( const ast::ZeroType * ) { 620 result = dynamic_cast< const ast::ZeroType * >( type2 ); 621 } 622 623 void postvisit( const ast::OneType * ) { 624 result = dynamic_cast< const ast::OneType * >( type2 ); 636 result = unifyList( types, types2, tenv, need, have, open ) 637 || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden()); 638 } 639 640 void postvisit( const ast::VarArgsType * vat) { 641 result = dynamic_cast< const ast::VarArgsType * >( type2 ) 642 || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden()); 643 } 644 645 void postvisit( const ast::ZeroType * zt) { 646 result = dynamic_cast< const ast::ZeroType * >( type2 ) 647 || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden()); 648 } 649 650 void postvisit( const ast::OneType * ot) { 651 result = dynamic_cast< const ast::OneType * >( type2 ) 652 || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden()); 625 653 } 626 654 };
Note:
See TracChangeset
for help on using the changeset viewer.