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