Changeset fc134a48
- Timestamp:
- Jun 2, 2022, 4:12:53 AM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- 1df492a, 90a8125, e5d9274
- Parents:
- 01f6a06
- Files:
-
- 2 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/CodeTools/ResolvProtoDump.cc ¶
r01f6a06 rfc134a48 304 304 305 305 // replace enums with int 306 void previsit( EnumInstType* ) { ss << (int)BasicType::SignedInt; } 306 void previsit( EnumInstType* ) { 307 // TODO: add the meaningful representation of typed int 308 ss << (int)BasicType::SignedInt; 309 } 307 310 308 311 void previsit( TypeInstType* vt ) { -
TabularUnified src/Common/ResolvProtoDump.cpp ¶
r01f6a06 rfc134a48 227 227 } 228 228 229 void previsit( const ast::EnumInstType * ) { 229 void previsit( const ast::EnumInstType * enumInst) { 230 // TODO: Add the meaningful text representation of typed enum 230 231 ss << (int)ast::BasicType::SignedInt; 231 232 } -
TabularUnified src/InitTweak/GenInit.cc ¶
r01f6a06 rfc134a48 368 368 369 369 struct ReturnFixer_New final : 370 public ast::WithStmtsToAdd<>, ast::WithGuards {370 public ast::WithStmtsToAdd<>, ast::WithGuards, ast::WithShortCircuiting { 371 371 void previsit( const ast::FunctionDecl * decl ); 372 372 const ast::ReturnStmt * previsit( const ast::ReturnStmt * stmt ); … … 376 376 377 377 void ReturnFixer_New::previsit( const ast::FunctionDecl * decl ) { 378 if (decl->linkage == ast::Linkage::Intrinsic) visit_children = false; 378 379 GuardValue( funcDecl ) = decl; 379 380 } -
TabularUnified src/ResolvExpr/CandidateFinder.cpp ¶
r01f6a06 rfc134a48 899 899 900 900 if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer); 901 else if (const ast::EnumInstType * enumInst = argType.as<ast::EnumInstType>()) { 902 const ast::EnumDecl * enumDecl = enumInst->base; 903 if ( const ast::Type* enumType = enumDecl->base ) { 904 // instance of enum (T) is a instance of type (T) 905 funcFinder.otypeKeys.insert(Mangle::mangle(enumType, Mangle::NoGenericParams | Mangle::Type)); 906 } else { 907 // instance of an untyped enum is techically int 908 funcFinder.otypeKeys.insert(Mangle::mangle(enumDecl, Mangle::NoGenericParams | Mangle::Type)); 909 } 910 } 901 911 else funcFinder.otypeKeys.insert(Mangle::mangle(argType, Mangle::NoGenericParams | Mangle::Type)); 902 912 } … … 918 928 919 929 // find function operators 920 ast::ptr< ast::Expr > opExpr = new ast::NameExpr{ untypedExpr->location, "?()" }; 930 ast::ptr< ast::Expr > opExpr = new ast::NameExpr{ untypedExpr->location, "?()" }; // ??? why not ?{} 921 931 CandidateFinder opFinder( context, tenv ); 922 932 // okay if there aren't any function operations -
TabularUnified src/ResolvExpr/CommonType.cc ¶
r01f6a06 rfc134a48 497 497 result = new BasicType( basicType->tq | otherBasic->tq, newType ); 498 498 } // if 499 } else if ( dynamic_cast< EnumInstType * > ( type2 ) ||dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {499 } else if ( dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) { 500 500 // use signed int in lieu of the enum/zero/one type 501 501 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ]; … … 503 503 result = new BasicType( basicType->tq | type2->tq, newType ); 504 504 } // if 505 } // if 505 } else if ( const EnumInstType * enumInst = dynamic_cast< const EnumInstType * > ( type2 ) ) { 506 const EnumDecl* enumDecl = enumInst->baseEnum; 507 if ( const Type* baseType = enumDecl->base ) { 508 result = baseType->clone(); 509 } else { 510 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ]; 511 if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) { 512 result = new BasicType( basicType->tq | type2->tq, newType ); 513 } // if 514 } 515 } 506 516 } 507 517 … … 691 701 } 692 702 } else if ( 693 dynamic_cast< const ast::EnumInstType * >( type2 ) 694 || dynamic_cast< const ast::ZeroType * >( type2 ) 703 dynamic_cast< const ast::ZeroType * >( type2 ) 695 704 || dynamic_cast< const ast::OneType * >( type2 ) 696 705 ) { … … 705 714 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; 706 715 } 716 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { 717 #warning remove casts when `commonTypes` moved to new AST 718 const ast::EnumDecl* enumDecl = enumInst->base; 719 if ( enumDecl->base ) { 720 result = enumDecl->base.get(); 721 } else { 722 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ]; 723 if ( 724 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 725 || widen.first ) 726 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 727 || widen.second ) 728 ) { 729 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; 730 } 731 } 707 732 } 708 733 } … … 723 748 result = voidPtr; 724 749 add_qualifiers( result, oPtr->qualifiers ); 750 } 751 752 // For a typed enum, we want to unify type1 with the base type of the enum 753 bool tryResolveWithTypedEnum( const ast::Type * type1 ) { 754 if (auto enumInst = dynamic_cast<const ast::EnumInstType *> (type2) ) { 755 ast::AssertionSet have, need; // unused 756 ast::OpenVarSet newOpen{ open }; 757 if (enumInst->base->base 758 && unifyExact(type1, enumInst->base->base, tenv, need, have, newOpen, widen, symtab)) { 759 result = type1; 760 return true; 761 } 762 } 763 return false; 725 764 } 726 765 … … 768 807 result = pointer; 769 808 add_qualifiers( result, type2->qualifiers ); 770 } 771 } 772 773 void postvisit( const ast::ArrayType * ) {} 809 } else { 810 tryResolveWithTypedEnum( pointer ); 811 } 812 } 813 814 void postvisit( const ast::ArrayType * arr ) { 815 // xxx - does it make sense? 816 tryResolveWithTypedEnum( arr ); 817 } 774 818 775 819 void postvisit( const ast::ReferenceType * ref ) { … … 810 854 result = ref; 811 855 add_qualifiers( result, type2->qualifiers ); 812 } 813 } 814 815 void postvisit( const ast::FunctionType * ) {} 816 817 void postvisit( const ast::StructInstType * ) {} 818 819 void postvisit( const ast::UnionInstType * ) {} 856 } else { 857 // xxx - does unifying a ref with typed enumInst makes sense? 858 if (!dynamic_cast<const ast::EnumInstType *>(type2)) 859 result = commonType( type2, ref, widen, symtab, tenv, open ); 860 } 861 } 862 863 void postvisit( const ast::FunctionType * func) { 864 tryResolveWithTypedEnum( func ); 865 } 866 867 void postvisit( const ast::StructInstType * inst ) { 868 tryResolveWithTypedEnum( inst ); 869 } 870 871 void postvisit( const ast::UnionInstType * inst ) { 872 tryResolveWithTypedEnum( inst ); 873 } 820 874 821 875 void postvisit( const ast::EnumInstType * enumInst ) { 822 if ( 823 dynamic_cast< const ast::BasicType * >( type2 ) 824 || dynamic_cast< const ast::ZeroType * >( type2 ) 825 || dynamic_cast< const ast::OneType * >( type2 ) 826 ) { 827 // reuse BasicType/EnumInstType common type by swapping 876 // reuse BasicType/EnumInstType common type by swapping 877 // xxx - is this already handled by unify? 878 if (!dynamic_cast<const ast::EnumInstType *>(type2)) 828 879 result = commonType( type2, enumInst, widen, symtab, tenv, open ); 829 }830 880 } 831 881 … … 850 900 result = type2; 851 901 reset_qualifiers( result, q1 | q2 ); 902 } else { 903 tryResolveWithTypedEnum( t1 ); 852 904 } 853 905 } … … 855 907 } 856 908 857 void postvisit( const ast::TupleType * ) {} 909 void postvisit( const ast::TupleType * tuple) { 910 tryResolveWithTypedEnum( tuple ); 911 } 858 912 859 913 void postvisit( const ast::VarArgsType * ) {} … … 861 915 void postvisit( const ast::ZeroType * zero ) { 862 916 if ( ! widen.first ) return; 863 if ( 864 dynamic_cast< const ast::BasicType * >( type2 ) 865 || dynamic_cast< const ast::PointerType * >( type2 ) 866 || dynamic_cast< const ast::EnumInstType * >( type2 ) 867 ) { 917 if ( dynamic_cast< const ast::BasicType * >( type2 ) 918 || dynamic_cast< const ast::PointerType * >( type2 ) ) { 868 919 if ( widen.second || zero->qualifiers <= type2->qualifiers ) { 869 920 result = type2; … … 873 924 result = new ast::BasicType{ 874 925 ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers }; 926 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { 927 const ast::EnumDecl * enumDecl = enumInst->base; 928 if ( enumDecl->base ) { 929 if ( tryResolveWithTypedEnum( zero ) ) 930 add_qualifiers( result, zero->qualifiers ); 931 } else { 932 if ( widen.second || zero->qualifiers <= type2->qualifiers ) { 933 result = type2; 934 add_qualifiers( result, zero->qualifiers ); 935 } 936 } 875 937 } 876 938 } … … 878 940 void postvisit( const ast::OneType * one ) { 879 941 if ( ! widen.first ) return; 880 if ( 881 dynamic_cast< const ast::BasicType * >( type2 ) 882 || dynamic_cast< const ast::EnumInstType * >( type2 ) 883 ) { 942 if ( dynamic_cast< const ast::BasicType * >( type2 ) ) { 884 943 if ( widen.second || one->qualifiers <= type2->qualifiers ) { 885 944 result = type2; … … 889 948 result = new ast::BasicType{ 890 949 ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers }; 950 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { 951 const ast::EnumDecl * enumBase = enumInst->base; 952 if ( enumBase->base ) { 953 if ( tryResolveWithTypedEnum( one )) 954 add_qualifiers( result, one->qualifiers ); 955 } else { 956 if ( widen.second || one->qualifiers <= type2->qualifiers ) { 957 result = type2; 958 add_qualifiers( result, one->qualifiers ); 959 } 960 } 891 961 } 892 962 } -
TabularUnified src/ResolvExpr/ConversionCost.cc ¶
r01f6a06 rfc134a48 321 321 } 322 322 323 // refactor for code resue 324 void ConversionCost::conversionCostFromBasicToBasic(const BasicType * src, const BasicType * dest) { 325 int tableResult = costMatrix[ src->kind ][ dest->kind ]; 326 if ( tableResult == -1 ) { 327 cost = Cost::unsafe; 328 } else { 329 cost = Cost::zero; 330 cost.incSafe( tableResult ); 331 cost.incSign( signMatrix[ src->kind ][ dest->kind ] ); 332 } // if 333 } // ConversionCost::conversionCostFromBasicToBasic 334 323 335 void ConversionCost::postvisit(const BasicType * basicType) { 324 336 if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 325 int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ]; 326 if ( tableResult == -1 ) { 327 cost = Cost::unsafe; 328 } else { 329 cost = Cost::zero; 330 cost.incSafe( tableResult ); 331 cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] ); 332 } // if 333 } else if ( dynamic_cast< const EnumInstType * >( dest ) ) { 334 // xxx - not positive this is correct, but appears to allow casting int => enum 335 // TODO 336 EnumDecl * decl = dynamic_cast< const EnumInstType * >( dest )->baseEnum; 337 if ( decl->base ) { 338 cost = Cost::infinity; 337 conversionCostFromBasicToBasic(basicType, destAsBasic); 338 } else if ( const EnumInstType * enumInst = dynamic_cast< const EnumInstType * >( dest ) ) { 339 const EnumDecl * base_enum = enumInst->baseEnum; 340 if ( const Type * base = base_enum->base ) { // if the base enum has a base (if it is typed) 341 if ( const BasicType * enumBaseAstBasic = dynamic_cast< const BasicType *> (base) ) { 342 conversionCostFromBasicToBasic(basicType, enumBaseAstBasic); 343 } else { 344 cost = Cost::infinity; 345 } // if 339 346 } else { 340 347 cost = Cost::unsafe; … … 398 405 void ConversionCost::postvisit( const FunctionType * ) {} 399 406 400 void ConversionCost::postvisit( const EnumInstType * ) { 401 static Type::Qualifiers q; 402 static BasicType integer( q, BasicType::SignedInt ); 403 cost = costFunc( &integer, dest, srcIsLvalue, indexer, env ); // safe if dest >= int 407 void ConversionCost::postvisit( const EnumInstType * enumInst) { 408 const EnumDecl * enumDecl = enumInst -> baseEnum; 409 if ( const Type * enumType = enumDecl -> base ) { // if it is a typed enum 410 cost = costFunc( enumType, dest, srcIsLvalue, indexer, env ); 411 } else { 412 static Type::Qualifiers q; 413 static BasicType integer( q, BasicType::SignedInt ); 414 cost = costFunc( &integer, dest, srcIsLvalue, indexer, env ); // safe if dest >= int 415 } // if 404 416 if ( cost < Cost::unsafe ) { 405 cost.incSafe();417 cost.incSafe(); 406 418 } // if 407 419 } … … 604 616 } 605 617 618 void ConversionCost_new::conversionCostFromBasicToBasic( const ast::BasicType * src, const ast::BasicType* dest ) { 619 int tableResult = costMatrix[ src->kind ][ dest->kind ]; 620 if ( tableResult == -1 ) { 621 cost = Cost::unsafe; 622 } else { 623 cost = Cost::zero; 624 cost.incSafe( tableResult ); 625 cost.incSign( signMatrix[ src->kind ][ dest->kind ] ); 626 } 627 } 628 606 629 void ConversionCost_new::postvisit( const ast::BasicType * basicType ) { 607 630 if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) { 608 int tableResult = costMatrix[ basicType->kind ][ dstAsBasic->kind ]; 609 if ( tableResult == -1 ) { 610 cost = Cost::unsafe; 611 } else { 612 cost = Cost::zero; 613 cost.incSafe( tableResult ); 614 cost.incSign( signMatrix[ basicType->kind ][ dstAsBasic->kind ] ); 615 } 616 } else if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) { 617 // xxx - not positive this is correct, but appears to allow casting int => enum 618 const ast::EnumDecl * decl = (dynamic_cast< const ast::EnumInstType * >( dst ))->base.get(); 619 if ( decl->base ) { 620 cost = Cost::infinity; 621 } else { 622 cost = Cost::unsafe; 623 } // if 631 conversionCostFromBasicToBasic( basicType, dstAsBasic ); 632 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 633 const ast::EnumDecl * enumDecl = enumInst->base.get(); 634 if ( const ast::Type * enumType = enumDecl->base.get() ) { 635 if ( const ast::BasicType * enumTypeAsBasic = dynamic_cast<const ast::BasicType *>(enumType) ) { 636 conversionCostFromBasicToBasic( basicType, enumTypeAsBasic ); 637 } else { 638 cost = Cost::infinity; 639 } 640 } else { 641 cost = Cost::unsafe; 642 } 624 643 } 625 644 } … … 673 692 674 693 void ConversionCost_new::postvisit( const ast::EnumInstType * enumInstType ) { 675 (void)enumInstType; 676 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) }; 677 cost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 694 const ast::EnumDecl * baseEnum = enumInstType->base; 695 if ( const ast::Type * baseType = baseEnum->base ) { 696 cost = costCalc( baseType, dst, srcIsLvalue, symtab, env ); 697 } else { 698 (void)enumInstType; 699 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) }; 700 cost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 701 } 678 702 if ( cost < Cost::unsafe ) { 679 703 cost.incSafe(); -
TabularUnified src/ResolvExpr/ConversionCost.h ¶
r01f6a06 rfc134a48 65 65 const TypeEnvironment &env; 66 66 CostFunction costFunc; 67 private: 68 // refactor for code resue 69 void conversionCostFromBasicToBasic( const BasicType * src, const BasicType* dest ); 67 70 }; 68 71 … … 111 114 void postvisit( const ast::ZeroType * zeroType ); 112 115 void postvisit( const ast::OneType * oneType ); 116 private: 117 // refactor for code resue 118 void conversionCostFromBasicToBasic( const ast::BasicType * src, const ast::BasicType* dest ); 113 119 }; 114 120 -
TabularUnified src/Validate/Autogen.cpp ¶
r01f6a06 rfc134a48 402 402 auto retval = srcParam(); 403 403 retval->name = "_ret"; 404 // xxx - Adding this unused attribute can slience unused variable warning 405 // However, some code might not be compiled as expected 406 // Temporarily disabled 407 // retval->attributes.push_back(new ast::Attribute("unused")); 404 408 return genProto( "?=?", { dstParam(), srcParam() }, { retval } ); 405 409 } -
TabularUnified tests/.expect/attributes.nast.x64.txt ¶
r01f6a06 rfc134a48 1339 1339 } 1340 1340 1341 { 1342 ((void)(_X4_retM12__anonymous4_2=(*_X4_dstM12__anonymous4_2)) /* ?{} */); 1343 } 1344 1345 return _X4_retM12__anonymous4_2; 1341 return (*_X4_dstM12__anonymous4_2); 1346 1342 } 1347 1343 { -
TabularUnified tests/.expect/attributes.nast.x86.txt ¶
r01f6a06 rfc134a48 1339 1339 } 1340 1340 1341 { 1342 ((void)(_X4_retM12__anonymous4_2=(*_X4_dstM12__anonymous4_2)) /* ?{} */); 1343 } 1344 1345 return _X4_retM12__anonymous4_2; 1341 return (*_X4_dstM12__anonymous4_2); 1346 1342 } 1347 1343 { -
TabularUnified tests/.expect/attributes.oast.x64.txt ¶
r01f6a06 rfc134a48 1339 1339 } 1340 1340 1341 { 1342 ((void)(_X4_retM12__anonymous4_2=(*_X4_dstM12__anonymous4_2)) /* ?{} */); 1343 } 1344 1345 return _X4_retM12__anonymous4_2; 1341 return (*_X4_dstM12__anonymous4_2); 1346 1342 } 1347 1343 { -
TabularUnified tests/.expect/attributes.oast.x86.txt ¶
r01f6a06 rfc134a48 1339 1339 } 1340 1340 1341 {1342 ((void)(_X4_retM12__anonymous4_2=(*_X4_dstM12__anonymous4_2)) /* ?{} */);1343 }1344 1345 1341 return _X4_retM12__anonymous4_2; 1346 1342 }
Note: See TracChangeset
for help on using the changeset viewer.