Ignore:
Timestamp:
Jul 17, 2017, 2:35:52 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
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:
7ebaa56
Parents:
b46e3bd
Message:

Remove Cost constructors, use only named members

This change makes it easier to read code involving costs, since in almost every case, only a single part of the cost tuple is relevant. Furthermore, this change makes it much simpler to add another dimension to the cost tuple, since only Cost.h needs to be updated, rather than every location using the cost constructor.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ConversionCost.cc

    rb46e3bd r89be1c68  
    4545                                assert( type );
    4646                                if ( type->get_base() ) {
    47                                         return conversionCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 );
     47                                        return conversionCost( src, type->get_base(), indexer, env ) + Cost::safe;
    4848                                } // if
    4949                        } // if
     
    5858                if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
    5959///     std::cout << "compatible!" << std::endl;
    60                         return Cost( 0, 0, 0 );
     60                        return Cost::zero;
    6161                } else if ( dynamic_cast< VoidType* >( dest ) ) {
    62                         return Cost( 0, 0, 1 );
     62                        return Cost::safe;
    6363                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    6464                        // std::cerr << "conversionCost: dest is reference" << std::endl;
     
    7070                                return Cost::infinity;
    7171                        } else {
    72                                 return converter.get_cost() + Cost( 0, 0, 0 );
    73                         } // if
    74                 } // if
    75         }
    76 
    77         Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
    78                 // std::cerr << "convert to reference cost..." << std::endl;
    79                 if ( ReferenceType *srcAsRef = dynamic_cast< ReferenceType * >( src ) ) { // pointer-like conversions between references
    80                         // std::cerr << "converting between references" << std::endl;
    81                         if ( srcAsRef->get_base()->get_qualifiers() <= dest->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), dest->get_base(), indexer, env ) ) {
    82                                 return Cost( 0, 0, 1 );
    83                         } else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    84                                 int assignResult = ptrsAssignable( srcAsRef->get_base(), dest->get_base(), env );
    85                                 if ( assignResult < 0 ) {
    86                                         return Cost( 0, 0, 1 );
    87                                 } else if ( assignResult > 0 ) {
    88                                         return Cost( 1, 0, 0 );
    89                                 } // if
    90                         } // if
    91                 } else if ( typesCompatibleIgnoreQualifiers( src, dest->get_base(), indexer, env ) ) {
    92                         // std::cerr << "converting compatible base type" << std::endl;
    93                         if ( src->get_lvalue() ) {
    94                                 // std::cerr << "lvalue to reference conversion" << std::endl;
    95                                 // lvalue-to-reference conversion:  cv lvalue T => cv T &
    96                                 if ( src->get_qualifiers() == dest->get_base()->get_qualifiers() ) {
    97                                         return Cost( 0, 0, 1 ); // cost needs to be non-zero to add cast
    98                                 } if ( src->get_qualifiers() < dest->get_base()->get_qualifiers() ) {
    99                                         return Cost( 0, 0, 2 ); // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
     72                                return converter.get_cost() + Cost::zero;
     73                        } // if
     74                } // if
     75        }
     76
     77        Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     78                std::cerr << "convert to reference cost..." << std::endl;
     79                if ( diff > 0 ) {
     80                        // TODO: document this
     81                        Cost cost = convertToReferenceCost( safe_dynamic_cast< ReferenceType * >( src )->get_base(), dest, diff-1, indexer, env );
     82                        // TODO: increment reference cost
     83                        cost.incSafe();
     84                        return cost;
     85                } else if ( diff < -1 ) {
     86                        // TODO: document this
     87                        Cost cost = convertToReferenceCost( src, safe_dynamic_cast< ReferenceType * >( dest )->get_base(), diff+1, indexer, env );
     88                        // TODO: increment reference cost
     89                        cost.incSafe();
     90                        return cost;
     91                } else if ( diff == 0 ) {
     92                        ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
     93                        ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
     94                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
     95                                std::cerr << "converting between references" << std::endl;
     96                                if ( srcAsRef->get_base()->get_qualifiers() <= destAsRef->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), destAsRef->get_base(), indexer, env ) ) {
     97                                        return Cost::safe;
     98                                } else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
     99                                        int assignResult = ptrsAssignable( srcAsRef->get_base(), destAsRef->get_base(), env );
     100                                        if ( assignResult < 0 ) {
     101                                                return Cost::safe;
     102                                        } else if ( assignResult > 0 ) {
     103                                                return Cost::unsafe;
     104                                        } // if
     105                                } // if
     106                        } else {
     107                                std::cerr << "reference to rvalue conversion" << std::endl;
     108                                ConversionCost converter( dest, indexer, env );
     109                                src->accept( converter );
     110                                return converter.get_cost();
     111                        } // if
     112                } else {
     113                        ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
     114                        assert( diff == -1 && destAsRef );
     115                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->get_base(), indexer, env ) ) {
     116                                std::cerr << "converting compatible base type" << std::endl;
     117                                if ( src->get_lvalue() ) {
     118                                        std::cerr << "lvalue to reference conversion" << std::endl;
     119                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
     120                                        if ( src->get_qualifiers() == destAsRef->get_base()->get_qualifiers() ) {
     121                                                return Cost::safe; // cost needs to be non-zero to add cast
     122                                        } if ( src->get_qualifiers() < destAsRef->get_base()->get_qualifiers() ) {
     123                                                return Cost::safe + Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
     124                                        } else {
     125                                                return Cost::unsafe;
     126                                        } // if
     127                                } else if ( destAsRef->get_base()->get_const() ) {
     128                                        std::cerr << "rvalue to const ref conversion" << std::endl;
     129                                        // rvalue-to-const-reference conversion: T => const T &
     130                                        return Cost::safe;
    100131                                } else {
    101                                         return Cost( 1, 0, 0 );
    102                                 }
    103                         } else if ( dest->get_base()->get_const() ) {
    104                                 // std::cerr << "rvalue to const ref conversion" << std::endl;
    105                                 // rvalue-to-const-reference conversion: T => const T &
    106                                 return Cost( 0, 0, 1 );
    107                         } else {
    108                                 // std::cerr << "rvalue to non-const reference conversion" << std::endl;
    109                                 // rvalue-to-reference conversion: T => T &
    110                                 return Cost( 1, 0, 0 );
    111                         }
    112                 } else {
    113                         // std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl;
     132                                        // std::cerr << "rvalue to non-const reference conversion" << std::endl;
     133                                        // rvalue-to-reference conversion: T => T &
     134                                        return Cost::unsafe;
     135                                } // if
     136                        } // if
     137                        std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl;
    114138                }
    115139                return Cost::infinity;
     140        }
     141
     142        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     143                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
     144                return convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env );
    116145        }
    117146
     
    205234                        int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
    206235                        if ( tableResult == -1 ) {
    207                                 cost = Cost( 1, 0, 0 );
    208                         } else {
    209                                 cost = Cost( 0, 0, tableResult );
     236                                cost = Cost::unsafe;
     237                        } else {
     238                                cost = Cost::zero;
     239                                cost.incSafe( tableResult );
    210240                        } // if
    211241                } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
    212242                        // xxx - not positive this is correct, but appears to allow casting int => enum
    213                         cost = Cost( 1, 0, 0 );
     243                        cost = Cost::unsafe;
    214244                } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
    215                         cost = Cost( 1, 0, 0 );
     245                        cost = Cost::unsafe;
    216246                } // if
    217247        }
     
    220250                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    221251                        if ( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
    222                                 cost = Cost( 0, 0, 1 );
     252                                cost = Cost::safe;
    223253                        } else {  // xxx - this discards pointer qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    224254                                int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env );
    225255                                if ( assignResult < 0 ) {
    226                                         cost = Cost( 0, 0, 1 );
     256                                        cost = Cost::safe;
    227257                                } else if ( assignResult > 0 ) {
    228                                         cost = Cost( 1, 0, 0 );
     258                                        cost = Cost::unsafe;
    229259                                } // if
    230260                        } // if
    231261                } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
    232                         cost = Cost( 1, 0, 0 );
     262                        cost = Cost::unsafe;
    233263                } // if
    234264        }
     
    243273                // cv can be safely dropped because of 'implicit dereference' behavior.
    244274                refType->get_base()->accept( *this );
     275                // TODO: increment reference cost
     276                cost.incSafe();
    245277        }
    246278
     
    267299                static BasicType integer( q, BasicType::SignedInt );
    268300                integer.accept( *this );  // safe if dest >= int
    269                 if ( cost < Cost( 1, 0, 0 ) ) {
     301                if ( cost < Cost::unsafe ) {
    270302                        cost.incSafe();
    271303                } // if
     
    289321                        assert( type );
    290322                        if ( type->get_base() ) {
    291                                 cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost( 0, 0, 1 );
     323                                cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost::safe;
    292324                        } // if
    293325                } // if
     
    295327
    296328        void ConversionCost::visit( __attribute((unused)) TupleType *tupleType) {
    297                 Cost c;
     329                Cost c = Cost::zero;
    298330                if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
    299331                        std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
     
    327359                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
    328360                        if ( tableResult == -1 ) {
    329                                 cost = Cost( 1, 0, 0 );
    330                         } else {
    331                                 cost = Cost( 0, 0, tableResult + 1 );
     361                                cost = Cost::unsafe;
     362                        } else {
     363                                cost = Cost::zero;
     364                                cost.incSafe( tableResult + 1 );
    332365                        }
    333366                } else if ( dynamic_cast< PointerType* >( dest ) ) {
    334                         cost = Cost( 0, 0, 1 );
     367                        cost = Cost::safe;
    335368                }
    336369        }
     
    343376                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
    344377                        if ( tableResult == -1 ) {
    345                                 cost = Cost( 1, 0, 0 );
    346                         } else {
    347                                 cost = Cost( 0, 0, tableResult + 1 );
     378                                cost = Cost::unsafe;
     379                        } else {
     380                                cost = Cost::zero;
     381                                cost.incSafe( tableResult + 1 );
    348382                        }
    349383                }
Note: See TracChangeset for help on using the changeset viewer.