Changes in src/ResolvExpr/Unify.cc [ef9988b:07de76b]
- File:
-
- 1 edited
-
src/ResolvExpr/Unify.cc (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
ref9988b r07de76b 25 25 #include <vector> 26 26 27 #include "AST/Copy.hpp"28 27 #include "AST/Decl.hpp" 29 28 #include "AST/Node.hpp" 30 29 #include "AST/Pass.hpp" 31 #include "AST/Print.hpp"32 30 #include "AST/Type.hpp" 33 31 #include "AST/TypeEnvironment.hpp" … … 137 135 findOpenVars( newSecond, open, closed, need, have, FirstOpen ); 138 136 139 return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 137 return unifyExact( 138 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 140 139 } 141 140 … … 149 148 newFirst->get_qualifiers() = Type::Qualifiers(); 150 149 newSecond->get_qualifiers() = Type::Qualifiers(); 151 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; 152 159 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 153 160 delete newFirst; … … 163 170 ast::AssertionSet need, have; 164 171 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; 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 ); 174 177 175 178 return unifyExact( 176 subFirst, 177 subSecond, 178 newEnv, need, have, open, noWiden(), symtab ); 179 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 179 180 } 180 181 … … 325 326 326 327 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; 327 333 AssertionSet::iterator i = assertions.find( assert ); 328 334 if ( i != assertions.end() ) { 335 /// std::cerr << "found it!" << std::endl; 329 336 i->second.isUsed = true; 330 337 } // if … … 702 709 const ast::SymbolTable & symtab; 703 710 public: 704 static size_t traceId;705 711 bool result; 706 712 … … 791 797 for ( const ast::DeclWithType * d : src ) { 792 798 ast::Pass<TtypeExpander_new> expander{ env }; 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() ); 799 d = d->accept( expander ); 800 auto types = flatten( d->get_type() ); 798 801 for ( ast::ptr< ast::Type > & t : types ) { 799 802 // outermost const, volatile, _Atomic qualifiers in parameters should not play … … 804 807 // requirements than a non-mutex function 805 808 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); 806 dst.emplace_back( new ast::ObjectDecl{ d c->location, "", t } );809 dst.emplace_back( new ast::ObjectDecl{ d->location, "", t } ); 807 810 } 808 811 } … … 940 943 941 944 private: 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 ) { 945 template< typename RefType > 946 const RefType * handleRefType( const RefType * inst, const ast::Type * other ) { 946 947 // check that the other type is compatible and named the same 947 auto otherInst = dynamic_cast< const XInstType * >( other );948 this->result = otherInst && inst->name == otherInst->name;948 auto otherInst = dynamic_cast< const RefType * >( other ); 949 result = otherInst && inst->name == otherInst->name; 949 950 return otherInst; 950 951 } … … 967 968 } 968 969 969 template< typename XInstType >970 void handleGenericRefType( const XInstType * inst, const ast::Type * other ) {970 template< typename RefType > 971 void handleGenericRefType( const RefType * inst, const ast::Type * other ) { 971 972 // check that other type is compatible and named the same 972 const XInstType * otherInst= handleRefType( inst, other );973 if ( ! this->result) return;973 const RefType * inst2 = handleRefType( inst, other ); 974 if ( ! inst2 ) return; 974 975 975 976 // check that parameters of types unify, if any 976 977 const std::vector< ast::ptr< ast::Expr > > & params = inst->params; 977 const std::vector< ast::ptr< ast::Expr > > & params2 = otherInst->params;978 const std::vector< ast::ptr< ast::Expr > > & params2 = inst2->params; 978 979 979 980 auto it = params.begin(); … … 1113 1114 1114 1115 ast::Pass<TtypeExpander_new> expander{ tenv }; 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 ); 1116 const ast::Type * flat = tuple->accept( expander ); 1117 const ast::Type * flat2 = tuple2->accept( expander ); 1120 1118 1121 1119 auto types = flatten( flat ); … … 1142 1140 }; 1143 1141 1144 // size_t Unify_new::traceId = Stats::Heap::new_stacktrace_id("Unify_new");1145 1142 bool unify( 1146 1143 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, … … 1191 1188 ast::Pass<Unify_new> comparator{ type2, env, need, have, open, widen, symtab }; 1192 1189 type1->accept( comparator ); 1193 return comparator. core.result;1190 return comparator.pass.result; 1194 1191 } 1195 1192 } … … 1205 1202 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 1206 1203 // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1 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); 1204 ast::ptr<ast::Type> t1{ type1 }, t2{ type2 }; 1205 reset_qualifiers( t1 ); 1206 reset_qualifiers( t2 ); 1213 1207 1214 1208 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) { 1209 t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones 1210 1215 1211 // if exact unification on unqualified types, try to merge qualifiers 1216 1212 if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) { 1217 t1->qualifiers = q1 | q2;1218 common = t1;1213 common = type1; 1214 reset_qualifiers( common, q1 | q2 ); 1219 1215 return true; 1220 1216 } else { … … 1223 1219 1224 1220 } else if (( common = commonType( t1, t2, widen, symtab, env, open ) )) { 1221 t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones 1222 1225 1223 // no exact unification, but common type 1226 auto c = shallowCopy(common.get()); 1227 c->qualifiers = q1 | q2; 1228 common = c; 1224 reset_qualifiers( common, q1 | q2 ); 1229 1225 return true; 1230 1226 } else {
Note:
See TracChangeset
for help on using the changeset viewer.