Changeset ee574a2 for src/ResolvExpr/Unify.cc
- Timestamp:
- Jun 4, 2019, 4:45:04 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- de8dfac2
- Parents:
- 4ae2364
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r4ae2364 ree574a2 136 136 137 137 return unifyExact( 138 newFirst, newSecond, newEnv, need, have, open, WidenMode{ false, false }, symtab );138 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 139 139 } 140 140 … … 173 173 env.apply( newFirst ); 174 174 env.apply( newSecond ); 175 clear_qualifiers( newFirst );176 clear_qualifiers( newSecond );175 reset_qualifiers( newFirst ); 176 reset_qualifiers( newSecond ); 177 177 178 178 return unifyExact( 179 newFirst, newSecond, newEnv, need, have, open, WidenMode{ false, false }, symtab );179 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 180 180 } 181 181 … … 700 700 } 701 701 702 class Unify_new : public ast::WithShortCircuiting {702 class Unify_new final : public ast::WithShortCircuiting { 703 703 const ast::Type * type2; 704 704 ast::TypeEnvironment & tenv; … … 720 720 void previsit( const ast::Node * ) { visit_children = false; } 721 721 722 void previsit( const ast::VoidType * ) { 723 visit_children = false; 722 void postvisit( const ast::VoidType * ) { 724 723 result = dynamic_cast< const ast::VoidType * >( type2 ); 725 724 } 726 725 727 void previsit( const ast::BasicType * basic ) { 728 visit_children = false; 726 void postvisit( const ast::BasicType * basic ) { 729 727 if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) { 730 728 result = basic->kind == basic2->kind; … … 732 730 } 733 731 734 void previsit( const ast::PointerType * pointer ) { 735 visit_children = false; 732 void postvisit( const ast::PointerType * pointer ) { 736 733 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) { 737 734 result = unifyExact( 738 735 pointer->base, pointer2->base, tenv, need, have, open, 739 WidenMode{ false, false }, symtab ); 740 } 741 } 742 743 void previsit( const ast::ArrayType * array ) { 744 visit_children = false; 736 noWiden(), symtab ); 737 } 738 } 739 740 void postvisit( const ast::ArrayType * array ) { 745 741 auto array2 = dynamic_cast< const ast::ArrayType * >( type2 ); 746 742 if ( ! array2 ) return; … … 761 757 762 758 result = unifyExact( 763 array->base, array2->base, tenv, need, have, open, WidenMode{ false, false },759 array->base, array2->base, tenv, need, have, open, noWiden(), 764 760 symtab ); 765 761 } 766 762 767 void previsit( const ast::ReferenceType * ref ) { 768 visit_children = false; 763 void postvisit( const ast::ReferenceType * ref ) { 769 764 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 770 765 result = unifyExact( 771 ref->base, ref2->base, tenv, need, have, open, WidenMode{ false, false },766 ref->base, ref2->base, tenv, need, have, open, noWiden(), 772 767 symtab ); 773 768 } … … 783 778 TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {} 784 779 785 const ast::Type * post mutate( const ast::TypeInstType * typeInst ) {780 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) { 786 781 if ( const ast::EqvClass * clz = tenv.lookup( typeInst->name ) ) { 787 782 // expand ttype parameter into its actual type … … 811 806 // overloaded on outermost mutex and a mutex function has different 812 807 // requirements than a non-mutex function 813 t.get_and_mutate()->qualifiers 814 -= ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic; 808 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); 815 809 dst.emplace_back( new ast::ObjectDecl{ d->location, "", t } ); 816 810 } … … 851 845 return unifyExact( 852 846 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 853 WidenMode{ false, false }, symtab );847 noWiden(), symtab ); 854 848 } else if ( ! isTuple1 && isTuple2 ) { 855 849 // combine remainder of list1, then unify 856 850 return unifyExact( 857 851 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 858 WidenMode{ false, false }, symtab );852 noWiden(), symtab ); 859 853 } 860 854 861 855 if ( ! unifyExact( 862 t1, t2, env, need, have, open, WidenMode{ false, false }, symtab )856 t1, t2, env, need, have, open, noWiden(), symtab ) 863 857 ) return false; 864 858 … … 874 868 return unifyExact( 875 869 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 876 WidenMode{ false, false }, symtab );870 noWiden(), symtab ); 877 871 } else if ( crnt2 != end2 ) { 878 872 // try unifying empty tuple with ttype … … 881 875 return unifyExact( 882 876 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 883 WidenMode{ false, false }, symtab );877 noWiden(), symtab ); 884 878 } 885 879 … … 919 913 920 914 public: 921 void previsit( const ast::FunctionType * func ) { 922 visit_children = false; 915 void postvisit( const ast::FunctionType * func ) { 923 916 auto func2 = dynamic_cast< const ast::FunctionType * >( type2 ); 924 917 if ( ! func2 ) return; … … 952 945 template< typename RefType > 953 946 const RefType * handleRefType( const RefType * inst, const ast::Type * other ) { 954 visit_children = false;955 947 // check that the other type is compatible and named the same 956 948 auto otherInst = dynamic_cast< const RefType * >( other ); … … 1011 1003 1012 1004 if ( ! unifyExact( 1013 pty, pty2, tenv, need, have, open, WidenMode{ false, false }, symtab ) ) {1005 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) { 1014 1006 result = false; 1015 1007 return; … … 1023 1015 1024 1016 public: 1025 void p revisit( const ast::StructInstType * aggrType ) {1017 void postvisit( const ast::StructInstType * aggrType ) { 1026 1018 handleGenericRefType( aggrType, type2 ); 1027 1019 } 1028 1020 1029 void p revisit( const ast::UnionInstType * aggrType ) {1021 void postvisit( const ast::UnionInstType * aggrType ) { 1030 1022 handleGenericRefType( aggrType, type2 ); 1031 1023 } 1032 1024 1033 void p revisit( const ast::EnumInstType * aggrType ) {1025 void postvisit( const ast::EnumInstType * aggrType ) { 1034 1026 handleRefType( aggrType, type2 ); 1035 1027 } 1036 1028 1037 void p revisit( const ast::TraitInstType * aggrType ) {1029 void postvisit( const ast::TraitInstType * aggrType ) { 1038 1030 handleRefType( aggrType, type2 ); 1039 1031 } 1040 1032 1041 void p revisit( const ast::TypeInstType * typeInst ) {1033 void postvisit( const ast::TypeInstType * typeInst ) { 1042 1034 assert( open.find( typeInst->name ) == open.end() ); 1043 1035 handleRefType( typeInst, type2 ); … … 1078 1070 return unifyExact( 1079 1071 t1, tupleFromTypes( list2 ), env, need, have, open, 1080 WidenMode{ false, false }, symtab );1072 noWiden(), symtab ); 1081 1073 } else if ( ! isTuple1 && isTuple2 ) { 1082 1074 // combine entirety of list1, then unify 1083 1075 return unifyExact( 1084 1076 tupleFromTypes( list1 ), t2, env, need, have, open, 1085 WidenMode{ false, false }, symtab );1077 noWiden(), symtab ); 1086 1078 } 1087 1079 1088 1080 if ( ! unifyExact( 1089 t1, t2, env, need, have, open, WidenMode{ false, false }, symtab )1081 t1, t2, env, need, have, open, noWiden(), symtab ) 1090 1082 ) return false; 1091 1083 … … 1101 1093 return unifyExact( 1102 1094 t1, tupleFromTypes( list2 ), env, need, have, open, 1103 WidenMode{ false, false }, symtab );1095 noWiden(), symtab ); 1104 1096 } else if ( crnt2 != list2.end() ) { 1105 1097 // try unifying empty tuple with ttype … … 1110 1102 return unifyExact( 1111 1103 tupleFromTypes( list1 ), t2, env, need, have, open, 1112 WidenMode{ false, false }, symtab );1104 noWiden(), symtab ); 1113 1105 } 1114 1106 … … 1117 1109 1118 1110 public: 1119 void previsit( const ast::TupleType * tuple ) { 1120 visit_children = false; 1111 void postvisit( const ast::TupleType * tuple ) { 1121 1112 auto tuple2 = dynamic_cast< const ast::TupleType * >( type2 ); 1122 1113 if ( ! tuple2 ) return; … … 1132 1123 } 1133 1124 1134 void previsit( const ast::VarArgsType * ) { 1135 visit_children = false; 1125 void postvisit( const ast::VarArgsType * ) { 1136 1126 result = dynamic_cast< const ast::VarArgsType * >( type2 ); 1137 1127 } 1138 1128 1139 void previsit( const ast::ZeroType * ) { 1140 visit_children = false; 1129 void postvisit( const ast::ZeroType * ) { 1141 1130 result = dynamic_cast< const ast::ZeroType * >( type2 ); 1142 1131 } 1143 1132 1144 void previsit( const ast::OneType * ) { 1145 visit_children = false; 1133 void postvisit( const ast::OneType * ) { 1146 1134 result = dynamic_cast< const ast::OneType * >( type2 ); 1147 1135 } … … 1151 1139 template< typename RefType > void handleGenericRefType( RefType *inst, Type *other ); 1152 1140 }; 1141 1142 bool unify( 1143 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1144 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1145 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1146 ) { 1147 ast::OpenVarSet closed; 1148 findOpenVars( type1, open, closed, need, have, FirstClosed ); 1149 findOpenVars( type2, open, closed, need, have, FirstOpen ); 1150 return unifyInexact( 1151 type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common ); 1152 } 1153 1153 1154 1154 bool unifyExact( … … 1184 1184 1185 1185 bool unifyInexact( 1186 ast::ptr<ast::Type> & type1, ast::ptr<ast::Type> & type2, ast::TypeEnvironment & env, 1187 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1188 WidenMode widen, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1186 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1187 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1188 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 1189 ast::ptr<ast::Type> & common 1189 1190 ) { 1190 1191 ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers; … … 1193 1194 // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1 1194 1195 ast::ptr<ast::Type> t1{ type1 }, t2{ type2 }; 1195 clear_qualifiers( t1 );1196 clear_qualifiers( t2 );1196 reset_qualifiers( t1 ); 1197 reset_qualifiers( t2 ); 1197 1198 1198 1199 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) { … … 1201 1202 // if exact unification on unqualified types, try to merge qualifiers 1202 1203 if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) { 1203 common.set_and_mutate( type1 )->qualifiers = q1 | q2; 1204 common = type1; 1205 reset_qualifiers( common, q1 | q2 ); 1204 1206 return true; 1205 1207 } else { … … 1211 1213 1212 1214 // no exact unification, but common type 1213 common.get_and_mutate()->qualifiers = q1 | q2;1215 reset_qualifiers( common, q1 | q2 ); 1214 1216 return true; 1215 1217 } else {
Note: See TracChangeset
for help on using the changeset viewer.