- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/ConversionCost.cc
r7e003011 r2463d0e 57 57 } else if ( dynamic_cast< VoidType* >( dest ) ) { 58 58 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 ); 59 62 } else { 60 63 ConversionCost converter( dest, indexer, env ); … … 66 69 } // if 67 70 } // 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; 68 112 } 69 113 … … 173 217 if ( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) { 174 218 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? 176 220 int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env ); 177 221 if ( assignResult < 0 ) { … … 187 231 188 232 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 189 243 void ConversionCost::visit(__attribute((unused)) FunctionType *functionType) {} 190 244 … … 208 262 static Type::Qualifiers q; 209 263 static BasicType integer( q, BasicType::SignedInt ); 210 integer.accept( *this ); 264 integer.accept( *this ); // safe if dest >= int 211 265 if ( cost < Cost( 1, 0, 0 ) ) { 212 266 cost.incSafe();
Note:
See TracChangeset
for help on using the changeset viewer.