Changeset 000178a
- Timestamp:
- Nov 2, 2017, 2:29:22 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- ddae809
- Parents:
- 6de43b6
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CommonType.cc
r6de43b6 r000178a 61 61 }; 62 62 63 Type * handleReference( ReferenceType * refType, Type * other, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment & env, const OpenVarSet &openVars ) {64 Type * result = nullptr, *common = nullptr;63 Type * handleReference( Type * t1, Type * t2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment & env, const OpenVarSet &openVars ) { 64 Type * common = nullptr; 65 65 AssertionSet have, need; 66 66 OpenVarSet newOpen( openVars ); 67 67 // need unify to bind type variables 68 if ( unify( refType->get_base(), other, env, have, need, newOpen, indexer, common ) ) { 69 // std::cerr << "unify success" << std::endl; 70 if ( widenSecond ) { 71 // std::cerr << "widen second" << std::endl; 72 if ( widenFirst || other->get_qualifiers() <= refType->get_qualifiers() ) { 73 result = new ReferenceType( refType->get_qualifiers(), common ); // refType->clone(); 74 result->get_qualifiers() |= other->get_qualifiers(); 75 } 76 } else if ( widenFirst ) { 77 // std::cerr << "widen first" << std::endl; 78 if ( widenSecond || refType->get_qualifiers() <= other->get_qualifiers() ) { 79 result = common; 80 result->get_qualifiers() |= refType->get_qualifiers(); 81 } 82 } 83 } else { 84 // std::cerr << "exact unify failed: " << refType << " " << other << std::endl; 85 } 86 // std::cerr << "common type of reference [" << refType << "] and non-reference [" << other << "] is [" << result << "]" << std::endl; 87 return result; 68 if ( unify( t1, t2, env, have, need, newOpen, indexer, common ) ) { 69 // std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl; 70 if ( (widenFirst || t2->get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) { 71 // std::cerr << "widen okay" << std::endl; 72 common->get_qualifiers() |= t1->get_qualifiers(); 73 common->get_qualifiers() |= t2->get_qualifiers(); 74 return common; 75 } 76 } 77 // std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl; 78 return nullptr; 88 79 } 89 80 … … 99 90 100 91 // special case where one type has a reference depth of 1 larger than the other 101 if ( diff > 0 ) { 102 return handleReference( strict_dynamic_cast<ReferenceType *>( type1 ), type2, widenFirst, widenSecond, indexer, env, openVars ); 103 } else if ( diff < 0 ) { 104 return handleReference( strict_dynamic_cast<ReferenceType *>( type2 ), type1, widenSecond, widenFirst, indexer, env, openVars ); 92 if ( diff > 0 || diff < 0 ) { 93 Type * result = nullptr; 94 if ( ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 ) ) { 95 // formal is reference, so result should be reference 96 result = handleReference( ref1->base, type2, widenFirst, widenSecond, indexer, env, openVars ); 97 if ( result ) result = new ReferenceType( ref1->get_qualifiers(), result ); 98 } else { 99 // formal is value, so result should be value 100 ReferenceType * ref2 = strict_dynamic_cast< ReferenceType * > ( type2 ); 101 result = handleReference( type1, ref2->base, widenFirst, widenSecond, indexer, env, openVars ); 102 } 103 // std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl; 104 return result; 105 105 } 106 106 // otherwise, both are reference types of the same depth and this is handled by the CommonType visitor.
Note: See TracChangeset
for help on using the changeset viewer.