Changeset e67a82d for src/ResolvExpr/Unify.cc
- Timestamp:
- Aug 20, 2020, 11:48:15 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- d685cb0
- Parents:
- 67ca73e (diff), 013b028 (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/Unify.cc
r67ca73e re67a82d 25 25 #include <vector> 26 26 27 #include "AST/Copy.hpp" 27 28 #include "AST/Decl.hpp" 28 29 #include "AST/Node.hpp" 29 30 #include "AST/Pass.hpp" 31 #include "AST/Print.hpp" 30 32 #include "AST/Type.hpp" 31 33 #include "AST/TypeEnvironment.hpp" … … 135 137 findOpenVars( newSecond, open, closed, need, have, FirstOpen ); 136 138 137 return unifyExact( 138 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 139 return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 139 140 } 140 141 … … 148 149 newFirst->get_qualifiers() = Type::Qualifiers(); 149 150 newSecond->get_qualifiers() = Type::Qualifiers(); 150 /// std::cerr << "first is "; 151 /// first->print( std::cerr ); 152 /// std::cerr << std::endl << "second is "; 153 /// second->print( std::cerr ); 154 /// std::cerr << std::endl << "newFirst is "; 155 /// newFirst->print( std::cerr ); 156 /// std::cerr << std::endl << "newSecond is "; 157 /// newSecond->print( std::cerr ); 158 /// std::cerr << std::endl; 151 159 152 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 160 153 delete newFirst; … … 170 163 ast::AssertionSet need, have; 171 164 172 ast::ptr<ast::Type> newFirst{ first }, newSecond{ second }; 173 env.apply( newFirst ); 174 env.apply( newSecond ); 175 reset_qualifiers( newFirst ); 176 reset_qualifiers( newSecond ); 165 ast::Type * newFirst = shallowCopy( first ); 166 ast::Type * newSecond = shallowCopy( second ); 167 newFirst ->qualifiers = {}; 168 newSecond->qualifiers = {}; 169 ast::ptr< ast::Type > t1_(newFirst ); 170 ast::ptr< ast::Type > t2_(newSecond); 171 172 ast::ptr< ast::Type > subFirst = env.apply(newFirst).node; 173 ast::ptr< ast::Type > subSecond = env.apply(newSecond).node; 177 174 178 175 return unifyExact( 179 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 176 subFirst, 177 subSecond, 178 newEnv, need, have, open, noWiden(), symtab ); 180 179 } 181 180 … … 326 325 327 326 void markAssertionSet( AssertionSet &assertions, DeclarationWithType *assert ) { 328 /// std::cerr << "assertion set is" << std::endl;329 /// printAssertionSet( assertions, std::cerr, 8 );330 /// std::cerr << "looking for ";331 /// assert->print( std::cerr );332 /// std::cerr << std::endl;333 327 AssertionSet::iterator i = assertions.find( assert ); 334 328 if ( i != assertions.end() ) { 335 /// std::cerr << "found it!" << std::endl;336 329 i->second.isUsed = true; 337 330 } // if … … 709 702 const ast::SymbolTable & symtab; 710 703 public: 704 static size_t traceId; 711 705 bool result; 712 706 … … 797 791 for ( const ast::DeclWithType * d : src ) { 798 792 ast::Pass<TtypeExpander_new> expander{ env }; 799 d = d->accept( expander ); 800 auto types = flatten( d->get_type() ); 793 // TtypeExpander pass is impure (may mutate nodes in place) 794 // need to make nodes shared to prevent accidental mutation 795 ast::ptr<ast::DeclWithType> dc = d; 796 dc = dc->accept( expander ); 797 auto types = flatten( dc->get_type() ); 801 798 for ( ast::ptr< ast::Type > & t : types ) { 802 799 // outermost const, volatile, _Atomic qualifiers in parameters should not play … … 807 804 // requirements than a non-mutex function 808 805 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); 809 dst.emplace_back( new ast::ObjectDecl{ d ->location, "", t } );806 dst.emplace_back( new ast::ObjectDecl{ dc->location, "", t } ); 810 807 } 811 808 } … … 943 940 944 941 private: 945 template< typename RefType > 946 const RefType * handleRefType( const RefType * inst, const ast::Type * other ) { 942 // Returns: other, cast as XInstType 943 // Assigns this->result: whether types are compatible (up to generic parameters) 944 template< typename XInstType > 945 const XInstType * handleRefType( const XInstType * inst, const ast::Type * other ) { 947 946 // check that the other type is compatible and named the same 948 auto otherInst = dynamic_cast< const RefType * >( other );949 result = otherInst && inst->name == otherInst->name;947 auto otherInst = dynamic_cast< const XInstType * >( other ); 948 this->result = otherInst && inst->name == otherInst->name; 950 949 return otherInst; 951 950 } … … 968 967 } 969 968 970 template< typename RefType >971 void handleGenericRefType( const RefType * inst, const ast::Type * other ) {969 template< typename XInstType > 970 void handleGenericRefType( const XInstType * inst, const ast::Type * other ) { 972 971 // check that other type is compatible and named the same 973 const RefType * inst2= handleRefType( inst, other );974 if ( ! inst2) return;972 const XInstType * otherInst = handleRefType( inst, other ); 973 if ( ! this->result ) return; 975 974 976 975 // check that parameters of types unify, if any 977 976 const std::vector< ast::ptr< ast::Expr > > & params = inst->params; 978 const std::vector< ast::ptr< ast::Expr > > & params2 = inst2->params;977 const std::vector< ast::ptr< ast::Expr > > & params2 = otherInst->params; 979 978 980 979 auto it = params.begin(); … … 1114 1113 1115 1114 ast::Pass<TtypeExpander_new> expander{ tenv }; 1116 const ast::Type * flat = tuple->accept( expander ); 1117 const ast::Type * flat2 = tuple2->accept( expander ); 1115 1116 ast::ptr<ast::TupleType> tuplec = tuple; 1117 ast::ptr<ast::TupleType> tuple2c = tuple2; 1118 const ast::Type * flat = tuplec->accept( expander ); 1119 const ast::Type * flat2 = tuple2c->accept( expander ); 1118 1120 1119 1121 auto types = flatten( flat ); … … 1140 1142 }; 1141 1143 1144 // size_t Unify_new::traceId = Stats::Heap::new_stacktrace_id("Unify_new"); 1142 1145 bool unify( 1143 1146 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, … … 1188 1191 ast::Pass<Unify_new> comparator{ type2, env, need, have, open, widen, symtab }; 1189 1192 type1->accept( comparator ); 1190 return comparator. pass.result;1193 return comparator.core.result; 1191 1194 } 1192 1195 } … … 1202 1205 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 1203 1206 // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1 1204 ast::ptr<ast::Type> t1{ type1 }, t2{ type2 }; 1205 reset_qualifiers( t1 ); 1206 reset_qualifiers( t2 ); 1207 ast::Type * t1 = shallowCopy(type1.get()); 1208 ast::Type * t2 = shallowCopy(type2.get()); 1209 t1->qualifiers = {}; 1210 t2->qualifiers = {}; 1211 ast::ptr< ast::Type > t1_(t1); 1212 ast::ptr< ast::Type > t2_(t2); 1207 1213 1208 1214 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) { 1209 t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones1210 1211 1215 // if exact unification on unqualified types, try to merge qualifiers 1212 1216 if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) { 1213 common = type1;1214 reset_qualifiers( common, q1 | q2 );1217 t1->qualifiers = q1 | q2; 1218 common = t1; 1215 1219 return true; 1216 1220 } else { … … 1219 1223 1220 1224 } else if (( common = commonType( t1, t2, widen, symtab, env, open ) )) { 1221 t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones1222 1223 1225 // no exact unification, but common type 1224 reset_qualifiers( common, q1 | q2 ); 1226 auto c = shallowCopy(common.get()); 1227 c->qualifiers = q1 | q2; 1228 common = c; 1225 1229 return true; 1226 1230 } else {
Note:
See TracChangeset
for help on using the changeset viewer.