Changeset 2463d0e


Ignore:
Timestamp:
Jul 13, 2017, 2:27:58 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:
65cec25
Parents:
0a81c3f
Message:

Add conversion & cast cost for reference conversions

Location:
src/ResolvExpr
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CastCost.cc

    r0a81c3f r2463d0e  
    5454                } else if ( dynamic_cast< VoidType* >( dest ) ) {
    5555                        return Cost( 0, 0, 1 );
     56                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
     57                        return convertToReferenceCost( src, refType, indexer, env );
    5658                } else {
    5759                        CastCost converter( dest, indexer, env );
     
    7678                        cost = Cost( 1, 0, 0 );
    7779                } else {
    78                         ConversionCost::visit( basicType );
     80                        cost = conversionCost( basicType, dest, indexer, env );
    7981                } // if
    8082        }
  • src/ResolvExpr/ConversionCost.cc

    r0a81c3f r2463d0e  
    5757                } else if ( dynamic_cast< VoidType* >( dest ) ) {
    5858                        return Cost( 0, 0, 1 );
     59                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
     60                        // std::cerr << "conversionCost: dest is reference" << std::endl;
     61                        return convertToReferenceCost( src, refType, indexer, env );
    5962                } else {
    6063                        ConversionCost converter( dest, indexer, env );
     
    6669                        } // if
    6770                } // if
     71        }
     72
     73        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     74                // std::cerr << "convert to reference cost..." << std::endl;
     75                if ( ReferenceType *srcAsRef = dynamic_cast< ReferenceType * >( src ) ) { // pointer-like conversions between references
     76                        // std::cerr << "converting between references" << std::endl;
     77                        if ( srcAsRef->get_base()->get_qualifiers() <= dest->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), dest->get_base(), indexer, env ) ) {
     78                                return Cost( 0, 0, 1 );
     79                        } else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
     80                                int assignResult = ptrsAssignable( srcAsRef->get_base(), dest->get_base(), env );
     81                                if ( assignResult < 0 ) {
     82                                        return Cost( 0, 0, 1 );
     83                                } else if ( assignResult > 0 ) {
     84                                        return Cost( 1, 0, 0 );
     85                                } // if
     86                        } // if
     87                } else if ( typesCompatibleIgnoreQualifiers( src, dest->get_base(), indexer, env ) ) {
     88                        // std::cerr << "converting compatible base type" << std::endl;
     89                        if ( src->get_lvalue() ) {
     90                                // std::cerr << "lvalue to reference conversion" << std::endl;
     91                                // lvalue-to-reference conversion:  cv lvalue T => cv T &
     92                                if ( src->get_qualifiers() == dest->get_base()->get_qualifiers() ) {
     93                                        return Cost( 0, 0, 1 ); // cost needs to be non-zero to add cast
     94                                } if ( src->get_qualifiers() < dest->get_base()->get_qualifiers() ) {
     95                                        return Cost( 0, 0, 2 ); // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
     96                                } else {
     97                                        return Cost( 1, 0, 0 );
     98                                }
     99                        } else if ( dest->get_base()->get_const() ) {
     100                                // std::cerr << "rvalue to const ref conversion" << std::endl;
     101                                // rvalue-to-const-reference conversion: T => const T &
     102                                return Cost( 0, 0, 1 );
     103                        } else {
     104                                // std::cerr << "rvalue to non-const reference conversion" << std::endl;
     105                                // rvalue-to-reference conversion: T => T &
     106                                return Cost( 1, 0, 0 );
     107                        }
     108                } else {
     109                        // std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl;
     110                }
     111                return Cost::infinity;
    68112        }
    69113
     
    173217                        if ( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
    174218                                cost = Cost( 0, 0, 1 );
    175                         } else {
     219                        } else {  // xxx - this discards pointer qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    176220                                int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env );
    177221                                if ( assignResult < 0 ) {
     
    187231
    188232        void ConversionCost::visit(__attribute((unused)) ArrayType *arrayType) {}
     233
     234        void ConversionCost::visit(ReferenceType *refType) {
     235                // Note: dest can never be a reference, since it would have been caught in an earlier check
     236                assert( ! dynamic_cast< ReferenceType * >( dest ) );
     237                // convert reference to rvalue: cv T1 & => T2
     238                // recursively compute conversion cost from T1 to T2.
     239                // cv can be safely dropped because of 'implicit dereference' behavior.
     240                refType->get_base()->accept( *this );
     241        }
     242
    189243        void ConversionCost::visit(__attribute((unused)) FunctionType *functionType) {}
    190244
     
    208262                static Type::Qualifiers q;
    209263                static BasicType integer( q, BasicType::SignedInt );
    210                 integer.accept( *this );
     264                integer.accept( *this );  // safe if dest >= int
    211265                if ( cost < Cost( 1, 0, 0 ) ) {
    212266                        cost.incSafe();
  • src/ResolvExpr/ConversionCost.h

    r0a81c3f r2463d0e  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ConversionCost.h -- 
     7// ConversionCost.h --
    88//
    99// Author           : Richard C. Bilson
     
    2626          public:
    2727                ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    28  
     28
    2929                Cost get_cost() const { return cost; }
    3030
     
    3333                virtual void visit(PointerType *pointerType);
    3434                virtual void visit(ArrayType *arrayType);
     35                virtual void visit(ReferenceType *refType);
    3536                virtual void visit(FunctionType *functionType);
    3637                virtual void visit(StructInstType *aggregateUseType);
     
    4950                const TypeEnvironment &env;
    5051        };
     52
     53        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
    5154} // namespace ResolvExpr
    5255
Note: See TracChangeset for help on using the changeset viewer.