Changeset 000178a


Ignore:
Timestamp:
Nov 2, 2017, 2:29:22 PM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
ddae809
Parents:
6de43b6
Message:

Refactor reference CommonType? code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CommonType.cc

    r6de43b6 r000178a  
    6161        };
    6262
    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;
    6565                AssertionSet have, need;
    6666                OpenVarSet newOpen( openVars );
    6767                // 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;
    8879        }
    8980
     
    9990
    10091                        // 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;
    105105                        }
    106106                        // 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.