Changes in src/ResolvExpr/Unify.cc [251ce80:46da46b]
- File:
-
- 1 edited
-
src/ResolvExpr/Unify.cc (modified) (34 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r251ce80 r46da46b 33 33 #include "AST/TypeEnvironment.hpp" 34 34 #include "Common/PassVisitor.h" // for PassVisitor 35 #include "CommonType.hpp" // for commonType36 35 #include "FindOpenVars.h" // for findOpenVars 37 #include "SpecCost.hpp" // for SpecCost38 36 #include "SynTree/LinkageSpec.h" // for C 39 37 #include "SynTree/Constant.h" // for Constant … … 45 43 #include "Tuples/Tuples.h" // for isTtype 46 44 #include "TypeEnvironment.h" // for EqvClass, AssertionSet, OpenVarSet 47 #include "typeops.h" // for flatten, occurs 45 #include "typeops.h" // for flatten, occurs, commonType 48 46 49 47 namespace ast { … … 52 50 53 51 namespace SymTab { 54 class Indexer;52 class Indexer; 55 53 } // namespace SymTab 56 54 … … 58 56 59 57 namespace ResolvExpr { 60 61 // Template Helpers:62 template< typename Iterator1, typename Iterator2 >63 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {64 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {65 Type *commonType = 0;66 if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {67 return false;68 } // if69 commonTypes.push_back( commonType );70 } // for71 return ( list1Begin == list1End && list2Begin == list2End );72 }73 74 template< typename Iterator1, typename Iterator2 >75 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {76 std::list< Type* > commonTypes;77 if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {78 deleteAll( commonTypes );79 return true;80 } else {81 return false;82 } // if83 }84 58 85 59 struct Unify_old : public WithShortCircuiting { … … 128 102 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 129 103 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 130 WidenMode widen );104 WidenMode widen, const ast::SymbolTable & symtab ); 131 105 132 106 bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { … … 150 124 151 125 bool typesCompatible( 152 const ast::Type * first, const ast::Type * second, 126 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 153 127 const ast::TypeEnvironment & env ) { 154 128 ast::TypeEnvironment newEnv; … … 160 134 env.apply( newSecond ); 161 135 162 findOpenVars( newFirst, open, closed, need, have, FirstClosed );163 findOpenVars( newSecond, open, closed, need, have, FirstOpen );164 165 return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden() );136 // findOpenVars( newFirst, open, closed, need, have, FirstClosed ); 137 findOpenVars( newSecond, open, closed, need, have, newEnv, FirstOpen ); 138 139 return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 166 140 } 167 141 … … 183 157 184 158 bool typesCompatibleIgnoreQualifiers( 185 const ast::Type * first, const ast::Type * second, 159 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 186 160 const ast::TypeEnvironment & env ) { 187 161 ast::TypeEnvironment newEnv; … … 216 190 subFirst, 217 191 subSecond, 218 newEnv, need, have, open, noWiden() );192 newEnv, need, have, open, noWiden(), symtab ); 219 193 } 220 194 … … 786 760 const ast::OpenVarSet & open; 787 761 WidenMode widen; 762 const ast::SymbolTable & symtab; 788 763 public: 789 764 static size_t traceId; … … 792 767 Unify_new( 793 768 const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 794 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen ) 769 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 770 const ast::SymbolTable & symtab ) 795 771 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 796 result(false) {}772 symtab(symtab), result(false) {} 797 773 798 774 void previsit( const ast::Node * ) { visit_children = false; } … … 812 788 result = unifyExact( 813 789 pointer->base, pointer2->base, tenv, need, have, open, 814 noWiden() );790 noWiden(), symtab ); 815 791 } 816 792 } … … 835 811 836 812 result = unifyExact( 837 array->base, array2->base, tenv, need, have, open, noWiden()); 813 array->base, array2->base, tenv, need, have, open, noWiden(), 814 symtab ); 838 815 } 839 816 … … 841 818 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 842 819 result = unifyExact( 843 ref->base, ref2->base, tenv, need, have, open, noWiden()); 820 ref->base, ref2->base, tenv, need, have, open, noWiden(), 821 symtab ); 844 822 } 845 823 } … … 850 828 static bool unifyTypeList( 851 829 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 852 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open 830 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 831 const ast::SymbolTable & symtab 853 832 ) { 854 833 while ( crnt1 != end1 && crnt2 != end2 ) { … … 863 842 return unifyExact( 864 843 t1, tupleFromTypes( crnt2, end2 ), env, need, have, open, 865 noWiden() );844 noWiden(), symtab ); 866 845 } else if ( ! isTuple1 && isTuple2 ) { 867 846 // combine remainder of list1, then unify 868 847 return unifyExact( 869 848 tupleFromTypes( crnt1, end1 ), t2, env, need, have, open, 870 noWiden() );849 noWiden(), symtab ); 871 850 } 872 851 873 852 if ( ! unifyExact( 874 t1, t2, env, need, have, open, noWiden() )853 t1, t2, env, need, have, open, noWiden(), symtab ) 875 854 ) return false; 876 855 … … 886 865 return unifyExact( 887 866 t1, tupleFromTypes( crnt2, end2 ), env, need, have, open, 888 noWiden() );867 noWiden(), symtab ); 889 868 } else if ( crnt2 != end2 ) { 890 869 // try unifying empty tuple with ttype … … 893 872 return unifyExact( 894 873 tupleFromTypes( crnt1, end1 ), t2, env, need, have, open, 895 noWiden() );874 noWiden(), symtab ); 896 875 } 897 876 … … 903 882 const std::vector< ast::ptr< ast::Type > > & list2, 904 883 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 905 const ast::OpenVarSet & open 884 const ast::OpenVarSet & open, const ast::SymbolTable & symtab 906 885 ) { 907 886 return unifyTypeList( 908 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open); 887 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 888 symtab ); 909 889 } 910 890 … … 947 927 ) return; 948 928 949 if ( ! unifyTypeList( params, params2, tenv, need, have, open ) ) return;929 if ( ! unifyTypeList( params, params2, tenv, need, have, open, symtab ) ) return; 950 930 if ( ! unifyTypeList( 951 func->returns, func2->returns, tenv, need, have, open ) ) return;931 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return; 952 932 953 933 markAssertions( have, need, func ); … … 1020 1000 1021 1001 if ( ! unifyExact( 1022 pty, pty2, tenv, need, have, open, noWiden() ) ) {1002 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) { 1023 1003 result = false; 1024 1004 return; … … 1049 1029 1050 1030 void postvisit( const ast::TypeInstType * typeInst ) { 1051 assert( open.find( *typeInst ) == open.end() );1031 // assert( open.find( *typeInst ) == open.end() ); 1052 1032 handleRefType( typeInst, type2 ); 1053 1033 } … … 1059 1039 const std::vector< ast::ptr< ast::Type > > & list1, 1060 1040 const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 1061 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open 1041 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1042 const ast::SymbolTable & symtab 1062 1043 ) { 1063 1044 auto crnt1 = list1.begin(); … … 1074 1055 return unifyExact( 1075 1056 t1, tupleFromTypes( list2 ), env, need, have, open, 1076 noWiden() );1057 noWiden(), symtab ); 1077 1058 } else if ( ! isTuple1 && isTuple2 ) { 1078 1059 // combine entirety of list1, then unify 1079 1060 return unifyExact( 1080 1061 tupleFromTypes( list1 ), t2, env, need, have, open, 1081 noWiden() );1062 noWiden(), symtab ); 1082 1063 } 1083 1064 1084 1065 if ( ! unifyExact( 1085 t1, t2, env, need, have, open, noWiden() )1066 t1, t2, env, need, have, open, noWiden(), symtab ) 1086 1067 ) return false; 1087 1068 … … 1097 1078 return unifyExact( 1098 1079 t1, tupleFromTypes( list2 ), env, need, have, open, 1099 noWiden() );1080 noWiden(), symtab ); 1100 1081 } else if ( crnt2 != list2.end() ) { 1101 1082 // try unifying empty tuple with ttype … … 1106 1087 return unifyExact( 1107 1088 tupleFromTypes( list1 ), t2, env, need, have, open, 1108 noWiden() );1089 noWiden(), symtab ); 1109 1090 } 1110 1091 … … 1125 1106 auto types2 = flatten( flat2 ); 1126 1107 1127 result = unifyList( types, types2, tenv, need, have, open );1108 result = unifyList( types, types2, tenv, need, have, open, symtab ); 1128 1109 } 1129 1110 … … 1149 1130 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1150 1131 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1151 ast::OpenVarSet & open 1132 ast::OpenVarSet & open, const ast::SymbolTable & symtab 1152 1133 ) { 1153 1134 ast::ptr<ast::Type> common; 1154 return unify( type1, type2, env, need, have, open, common );1135 return unify( type1, type2, env, need, have, open, symtab, common ); 1155 1136 } 1156 1137 … … 1158 1139 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1159 1140 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1160 ast::OpenVarSet & open, ast::ptr<ast::Type> & common1141 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1161 1142 ) { 1162 1143 ast::OpenVarSet closed; 1163 findOpenVars( type1, open, closed, need, have, FirstClosed );1164 findOpenVars( type2, open, closed, need, have, FirstOpen );1144 // findOpenVars( type1, open, closed, need, have, FirstClosed ); 1145 findOpenVars( type2, open, closed, need, have, env, FirstOpen ); 1165 1146 return unifyInexact( 1166 type1, type2, env, need, have, open, WidenMode{ true, true }, common );1147 type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common ); 1167 1148 } 1168 1149 … … 1170 1151 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 1171 1152 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1172 WidenMode widen 1153 WidenMode widen, const ast::SymbolTable & symtab 1173 1154 ) { 1174 1155 if ( type1->qualifiers != type2->qualifiers ) return false; … … 1179 1160 entry1 = var1 ? open.find( *var1 ) : open.end(), 1180 1161 entry2 = var2 ? open.find( *var2 ) : open.end(); 1181 bool isopen1 = entry1 != open.end(); 1182 bool isopen2 = entry2 != open.end(); 1183 1162 // bool isopen1 = entry1 != open.end(); 1163 // bool isopen2 = entry2 != open.end(); 1164 bool isopen1 = var1 && env.lookup(*var1); 1165 bool isopen2 = var2 && env.lookup(*var2); 1166 1167 /* 1184 1168 if ( isopen1 && isopen2 ) { 1185 1169 if ( entry1->second.kind != entry2->second.kind ) return false; 1186 1170 return env.bindVarToVar( 1187 1171 var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have, 1188 open, widen );1172 open, widen, symtab ); 1189 1173 } else if ( isopen1 ) { 1190 return env.bindVar( var1, type2, entry1->second, need, have, open, widen );1174 return env.bindVar( var1, type2, entry1->second, need, have, open, widen, symtab ); 1191 1175 } else if ( isopen2 ) { 1192 return env.bindVar( var2, type1, entry2->second, need, have, open, widen ); 1193 } else { 1176 return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab ); 1177 } */ 1178 if ( isopen1 && isopen2 ) { 1179 if ( var1->base->kind != var2->base->kind ) return false; 1180 return env.bindVarToVar( 1181 var1, var2, ast::TypeData{ var1->base->kind, var1->base->sized||var2->base->sized }, need, have, 1182 open, widen, symtab ); 1183 } else if ( isopen1 ) { 1184 return env.bindVar( var1, type2, ast::TypeData{var1->base}, need, have, open, widen, symtab ); 1185 } else if ( isopen2 ) { 1186 return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen, symtab ); 1187 }else { 1194 1188 return ast::Pass<Unify_new>::read( 1195 type1, type2, env, need, have, open, widen ); 1196 } 1189 type1, type2, env, need, have, open, widen, symtab ); 1190 } 1191 1197 1192 } 1198 1193 … … 1200 1195 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1201 1196 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1202 const ast::OpenVarSet & open, WidenMode widen, 1197 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 1203 1198 ast::ptr<ast::Type> & common 1204 1199 ) { … … 1214 1209 ast::ptr< ast::Type > t2_(t2); 1215 1210 1216 if ( unifyExact( t1, t2, env, need, have, open, widen ) ) {1211 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) { 1217 1212 // if exact unification on unqualified types, try to merge qualifiers 1218 1213 if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) { … … 1224 1219 } 1225 1220 1226 } else if (( common = commonType( t1, t2, env, need, have, open, widen ))) {1221 } else if (( common = commonType( t1, t2, env, need, have, open, widen, symtab ))) { 1227 1222 // no exact unification, but common type 1228 1223 auto c = shallowCopy(common.get());
Note:
See TracChangeset
for help on using the changeset viewer.