Changeset 7f6a7c9 for src/ResolvExpr/CommonType.cc
- Timestamp:
- Sep 21, 2022, 11:02:15 AM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- 95dab9e
- Parents:
- 428adbc (diff), 0bd46fd (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CommonType.cc
r428adbc r7f6a7c9 28 28 #include "Unify.h" // for unifyExact, WidenMode 29 29 #include "typeops.h" // for isFtype 30 #include "Tuples/Tuples.h" 30 31 31 32 // #define DEBUG … … 675 676 ast::TypeEnvironment & tenv; 676 677 const ast::OpenVarSet & open; 678 ast::AssertionSet & need; 679 ast::AssertionSet & have; 677 680 public: 678 681 static size_t traceId; … … 681 684 CommonType_new( 682 685 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 683 ast::TypeEnvironment & env, const ast::OpenVarSet & o ) 684 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {} 686 ast::TypeEnvironment & env, const ast::OpenVarSet & o, 687 ast::AssertionSet & need, ast::AssertionSet & have ) 688 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), need (need), have (have) ,result() {} 685 689 686 690 void previsit( const ast::Node * ) { visit_children = false; } … … 753 757 bool tryResolveWithTypedEnum( const ast::Type * type1 ) { 754 758 if (auto enumInst = dynamic_cast<const ast::EnumInstType *> (type2) ) { 755 ast::AssertionSet have, need; // unused756 759 ast::OpenVarSet newOpen{ open }; 757 760 if (enumInst->base->base … … 792 795 reset_qualifiers( t2 ); 793 796 794 ast::AssertionSet have, need;795 797 ast::OpenVarSet newOpen{ open }; 796 798 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { … … 803 805 } 804 806 } 807 else if ( isFtype (t1) && isFtype (t2) ) { 808 auto f1 = t1.as<ast::FunctionType>(); 809 if (!f1) return; 810 auto f2 = t2.strict_as<ast::FunctionType>(); 811 812 assertf(f1->returns.size() <= 1, "Function return should not be a list"); 813 assertf(f2->returns.size() <= 1, "Function return should not be a list"); 814 815 if ( 816 ( f1->params.size() != f2->params.size() || f1->returns.size() != f2->returns.size() ) 817 && ! f1->isTtype() 818 && ! f2->isTtype() 819 ) return; 820 821 auto params1 = flattenList( f1->params, tenv ); 822 auto params2 = flattenList( f2->params, tenv ); 823 824 auto crnt1 = params1.begin(); 825 auto crnt2 = params2.begin(); 826 auto end1 = params1.end(); 827 auto end2 = params2.end(); 828 829 while (crnt1 != end1 && crnt2 != end2 ) { 830 const ast::Type * arg1 = *crnt1; 831 const ast::Type * arg2 = *crnt2; 832 833 bool isTuple1 = Tuples::isTtype( t1 ); 834 bool isTuple2 = Tuples::isTtype( t2 ); 835 836 // assumes here that ttype *must* be last parameter 837 if ( isTuple1 && ! isTuple2 ) { 838 // combine remainder of list2, then unify 839 if (unifyExact( 840 arg1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open, 841 noWiden(), symtab )) { 842 break; 843 844 } 845 else return; 846 } else if ( ! isTuple1 && isTuple2 ) { 847 // combine remainder of list1, then unify 848 if (unifyExact( 849 tupleFromTypes( crnt1, end1 ), arg2, tenv, need, have, open, 850 noWiden(), symtab )) { 851 break; 852 853 } 854 else return; 855 } 856 857 // allow qualifiers of pointer and reference base to become more specific 858 if (auto ref1 = dynamic_cast<const ast::ReferenceType *> (arg1)) { 859 if (auto ref2 = dynamic_cast<const ast::ReferenceType *> (arg2)) { 860 ast::ptr<ast::Type> base1 = ref1->base; 861 ast::ptr<ast::Type> base2 = ref2->base; 862 863 // xxx - assume LHS is always the target type 864 865 if ( ! ((widen.second && ref2->qualifiers.is_mutex) 866 || (ref1->qualifiers.is_mutex == ref2->qualifiers.is_mutex ))) return; 867 868 if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) { 869 870 reset_qualifiers(base1); 871 reset_qualifiers(base2); 872 873 if ( ! unifyExact( 874 base1, base2, tenv, need, have, open, noWiden(), symtab ) 875 ) return; 876 } 877 } 878 else return; 879 } 880 else if (auto ptr1 = dynamic_cast<const ast::PointerType *> (arg1)) { 881 if (auto ptr2 = dynamic_cast<const ast::PointerType *> (arg2)) { 882 ast::ptr<ast::Type> base1 = ptr1->base; 883 ast::ptr<ast::Type> base2 = ptr2->base; 884 885 // xxx - assume LHS is always the target type 886 // a function accepting const can always be called by non-const arg 887 888 if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) { 889 890 reset_qualifiers(base1); 891 reset_qualifiers(base2); 892 893 if ( ! unifyExact( 894 base1, base2, tenv, need, have, open, noWiden(), symtab ) 895 ) return; 896 } 897 } 898 else return; 899 900 } 901 else if (! unifyExact( 902 arg1, arg2, tenv, need, have, open, noWiden(), symtab )) return; 903 904 ++crnt1; ++crnt2; 905 } 906 if ( crnt1 != end1 ) { 907 // try unifying empty tuple with ttype 908 const ast::Type * t1 = *crnt1; 909 if (! Tuples::isTtype( t1 ) ) return; 910 if (! unifyExact( 911 t1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open, 912 noWiden(), symtab )) return; 913 } else if ( crnt2 != end2 ) { 914 // try unifying empty tuple with ttype 915 const ast::Type * t2 = *crnt2; 916 if (! Tuples::isTtype( t2 ) ) return; 917 if (! unifyExact( 918 tupleFromTypes( crnt1, end1 ), t2, tenv, need, have, open, 919 noWiden(), symtab )) return; 920 } 921 if ((f1->returns.size() == 0 && f2->returns.size() == 0) 922 || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden(), symtab))) { 923 result = pointer; 924 925 for (auto & assn : f1->assertions) { 926 auto i = need.find(assn); 927 if (i != need.end()) i->second.isUsed = true; 928 auto j = have.find(assn); 929 if (j != have.end()) j->second.isUsed = true; 930 } 931 932 for (auto & assn : f2->assertions) { 933 auto i = need.find(assn); 934 if (i != need.end()) i->second.isUsed = true; 935 auto j = have.find(assn); 936 if (j != have.end()) j->second.isUsed = true; 937 } 938 939 } 940 } // if ftype 941 805 942 } 806 943 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { … … 839 976 reset_qualifiers( t2 ); 840 977 841 ast::AssertionSet have, need;842 978 ast::OpenVarSet newOpen{ open }; 843 979 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { … … 857 993 // xxx - does unifying a ref with typed enumInst makes sense? 858 994 if (!dynamic_cast<const ast::EnumInstType *>(type2)) 859 result = commonType( type2, ref, widen, symtab, tenv, open);995 result = commonType( type2, ref, tenv, need, have, open, widen, symtab ); 860 996 } 861 997 } … … 877 1013 // xxx - is this already handled by unify? 878 1014 if (!dynamic_cast<const ast::EnumInstType *>(type2)) 879 result = commonType( type2, enumInst, widen, symtab, tenv, open);1015 result = commonType( type2, enumInst, tenv, need, have, open, widen, symtab); 880 1016 } 881 1017 … … 895 1031 reset_qualifiers( t2 ); 896 1032 897 ast::AssertionSet have, need;898 1033 ast::OpenVarSet newOpen{ open }; 899 1034 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { … … 999 1134 ast::ptr< ast::Type > commonType( 1000 1135 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 1001 WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env,1002 const ast::OpenVarSet & open 1136 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1137 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab 1003 1138 ) { 1004 1139 unsigned depth1 = type1->referenceDepth(); … … 1036 1171 } 1037 1172 // otherwise both are reference types of the same depth and this is handled by the visitor 1038 ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open };1173 ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open, need, have }; 1039 1174 type1->accept( visitor ); 1040 1175 ast::ptr< ast::Type > result = visitor.core.result; … … 1047 1182 if ( type->base ) { 1048 1183 ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers; 1049 ast::AssertionSet have, need;1050 1184 ast::OpenVarSet newOpen{ open }; 1051 1185
Note:
See TracChangeset
for help on using the changeset viewer.