- File:
-
- 1 edited
-
src/ResolvExpr/ConversionCost.cc (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/ConversionCost.cc
rb0837e4 r00ac42e 42 42 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 43 43 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 44 EqvClass eqvClass; 45 NamedTypeDecl *namedType; 46 PRINT( std::cerr << "type inst " << destAsTypeInst->get_name(); ) 47 if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) { 48 if ( eqvClass.type ) { 49 return conversionCost( src, eqvClass.type, indexer, env ); 44 PRINT( std::cerr << "type inst " << destAsTypeInst->name; ) 45 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) { 46 if ( eqvClass->type ) { 47 return conversionCost( src, eqvClass->type, indexer, env ); 50 48 } else { 51 49 return Cost::infinity; 52 50 } 53 } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() )) ) {51 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) { 54 52 PRINT( std::cerr << " found" << std::endl; ) 55 53 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType ); 56 54 // all typedefs should be gone by this point 57 55 assert( type ); 58 if ( type-> get_base()) {59 return conversionCost( src, type-> get_base(), indexer, env ) + Cost::safe;56 if ( type->base ) { 57 return conversionCost( src, type->base, indexer, env ) + Cost::safe; 60 58 } // if 61 59 } // if … … 77 75 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) { 78 76 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 79 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer &){77 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){ 80 78 return ptrsAssignable( t1, t2, env ); 81 79 }); 82 80 } else { 83 ConversionCost converter( dest, indexer, env);81 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost ); 84 82 src->accept( converter ); 85 if ( converter. get_cost() == Cost::infinity ) {83 if ( converter.pass.get_cost() == Cost::infinity ) { 86 84 return Cost::infinity; 87 85 } else { 88 return converter. get_cost() + Cost::zero;86 return converter.pass.get_cost() + Cost::zero; 89 87 } // if 90 88 } // if … … 92 90 93 91 Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 94 PRINT( std::cerr << "convert to reference cost... diff " << diff << std::endl; )92 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; ) 95 93 if ( diff > 0 ) { 96 94 // TODO: document this 97 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )-> get_base(), dest, diff-1, indexer, env, func );95 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func ); 98 96 cost.incReference(); 99 97 return cost; 100 98 } else if ( diff < -1 ) { 101 99 // TODO: document this 102 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )-> get_base(), diff+1, indexer, env, func );100 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func ); 103 101 cost.incReference(); 104 102 return cost; … … 108 106 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references 109 107 PRINT( std::cerr << "converting between references" << std::endl; ) 110 if ( srcAsRef->get_base()->get_qualifiers() <= destAsRef->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), destAsRef->get_base(), indexer, env ) ) { 111 return Cost::safe; 108 Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers(); 109 Type::Qualifiers tq2 = destAsRef->base->get_qualifiers(); 110 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) { 111 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) 112 if ( tq1 == tq2 ) { 113 // types are the same 114 return Cost::zero; 115 } else { 116 // types are the same, except otherPointer has more qualifiers 117 return Cost::safe; 118 } 112 119 } else { // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right? 113 int assignResult = func( srcAsRef-> get_base(), destAsRef->get_base(), env, indexer);120 int assignResult = func( srcAsRef->base, destAsRef->base, indexer, env ); 114 121 PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; ) 115 122 if ( assignResult > 0 ) { … … 121 128 } else { 122 129 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; ) 123 ConversionCost converter( dest, indexer, env);130 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost ); 124 131 src->accept( converter ); 125 return converter. get_cost();132 return converter.pass.get_cost(); 126 133 } // if 127 134 } else { … … 129 136 assert( diff == -1 && destAsRef ); 130 137 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; ) 131 if ( typesCompatibleIgnoreQualifiers( src, destAsRef-> get_base(), indexer, env ) ) {138 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) { 132 139 PRINT( std::cerr << "converting compatible base type" << std::endl; ) 133 140 if ( src->get_lvalue() ) { … … 137 144 ) 138 145 // lvalue-to-reference conversion: cv lvalue T => cv T & 139 if ( src->get_qualifiers() == destAsRef-> get_base()->get_qualifiers() ) {146 if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) { 140 147 return Cost::reference; // cost needs to be non-zero to add cast 141 } if ( src->get_qualifiers() < destAsRef-> get_base()->get_qualifiers() ) {148 } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) { 142 149 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same 143 150 } else { 144 151 return Cost::unsafe; 145 152 } // if 146 } else if ( destAsRef-> get_base()->get_const() ) {153 } else if ( destAsRef->base->get_const() ) { 147 154 PRINT( std::cerr << "rvalue to const ref conversion" << std::endl; ) 148 155 // rvalue-to-const-reference conversion: T => const T & … … 161 168 Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 162 169 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth(); 163 return convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func ); 164 } 165 166 ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) 167 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ) { 170 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func ); 171 PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; ) 172 return cost; 173 } 174 175 ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 176 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) { 168 177 } 169 178 … … 219 228 */ 220 229 221 static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = { 222 /* Src \ Dest: Bool Char SChar UChar Short UShort Int UInt Long ULong LLong ULLong Float Double LDbl FCplex DCplex LDCplex FImag DImag LDImag I128, U128 */ 223 /* Bool */ { 0, 1, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 12, 13, 14, 12, 13, 14, -1, -1, -1, 10, 11, }, 224 /* Char */ { -1, 0, -1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 11, 12, 13, 11, 12, 13, -1, -1, -1, 9, 10, }, 225 /* SChar */ { -1, -1, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 11, 12, 13, 11, 12, 13, -1, -1, -1, 9, 10, }, 226 /* UChar */ { -1, -1, -1, 0, 1, 2, 3, 4, 4, 5, 6, 7, 10, 11, 12, 10, 11, 12, -1, -1, -1, 8, 9, }, 227 /* Short */ { -1, -1, -1, -1, 0, 1, 2, 3, 3, 4, 5, 6, 9, 10, 11, 9, 10, 11, -1, -1, -1, 7, 8, }, 228 /* UShort */{ -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 4, 5, 8, 9, 10, 8, 9, 10, -1, -1, -1, 6, 7, }, 229 /* Int */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 4, 7, 8, 9, 7, 8, 9, -1, -1, -1, 5, 6, }, 230 /* UInt */ { -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, 2, 3, 6, 7, 8, 6, 7, 8, -1, -1, -1, 4, 5, }, 231 /* Long */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 6, 7, 8, 6, 7, 8, -1, -1, -1, 4, 5, }, 232 /* ULong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 5, 6, 7, 5, 6, 7, -1, -1, -1, 3, 4, }, 233 /* LLong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 4, 5, 6, 4, 5, 6, -1, -1, -1, 2, 3, }, 234 /* ULLong */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, 4, 5, 3, 4, 5, -1, -1, -1, 1, 2, }, 235 236 /* Float */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 1, 2, 3, -1, -1, -1, -1, -1, }, 237 /* Double */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 1, 2, -1, -1, -1, -1, -1, }, 238 /* LDbl */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, -1, -1, -1, }, 239 /* FCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, -1, -1, -1, -1, }, 240 /* DCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, }, 241 /* LDCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, }, 242 /* FImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 0, 1, 2, -1, -1, }, 243 /* DImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, 0, 1, -1, -1, }, 244 /* LDImag */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0, -1, -1, }, 245 246 /* I128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 3, 4, 5, -1, -1, -1, 0, 1, }, 247 /* U128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 2, 3, 4, -1, -1, -1, -1, 0, }, 230 static const int costMatrix[][ BasicType::NUMBER_OF_BASIC_TYPES ] = { 231 /* Src \ Dest: Bool Char SChar UChar Short UShort Int UInt Long ULong LLong ULLong Float Double LDbl FCplex DCplex LDCplex FImag DImag LDImag I128, U128, F80, F128 */ 232 /* Bool */ { 0, 1, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 12, 13, 14, 12, 13, 14, -1, -1, -1, 10, 11, 14, 15}, 233 /* Char */ { -1, 0, -1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 11, 12, 13, 11, 12, 13, -1, -1, -1, 9, 10, 13, 14}, 234 /* SChar */ { -1, -1, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 11, 12, 13, 11, 12, 13, -1, -1, -1, 9, 10, 13, 14}, 235 /* UChar */ { -1, -1, -1, 0, 1, 2, 3, 4, 4, 5, 6, 7, 10, 11, 12, 10, 11, 12, -1, -1, -1, 8, 9, 12, 13}, 236 /* Short */ { -1, -1, -1, -1, 0, 1, 2, 3, 3, 4, 5, 6, 9, 10, 11, 9, 10, 11, -1, -1, -1, 7, 8, 11, 12}, 237 /* UShort */{ -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 4, 5, 8, 9, 10, 8, 9, 10, -1, -1, -1, 6, 7, 10, 11}, 238 /* Int */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 4, 7, 8, 9, 7, 8, 9, -1, -1, -1, 5, 6, 9, 10}, 239 /* UInt */ { -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, 2, 3, 6, 7, 8, 6, 7, 8, -1, -1, -1, 4, 5, 8, 9}, 240 /* Long */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 6, 7, 8, 6, 7, 8, -1, -1, -1, 4, 5, 8, 9}, 241 /* ULong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 5, 6, 7, 5, 6, 7, -1, -1, -1, 3, 4, 7, 8}, 242 /* LLong */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 4, 5, 6, 4, 5, 6, -1, -1, -1, 2, 3, 6, 7}, 243 /* ULLong */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, 4, 5, 3, 4, 5, -1, -1, -1, 1, 2, 5, 6}, 244 245 /* Float */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 1, 2, 3, -1, -1, -1, -1, -1, 2, 3}, 246 /* Double */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 1, 2, -1, -1, -1, -1, -1, 1, 2}, 247 /* LDbl */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1}, 248 /* FCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, -1, -1, -1, -1, -1, -1}, 249 /* DCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, -1, -1, -1}, 250 /* LDCplex */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1}, 251 /* FImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 0, 1, 2, -1, -1, -1, -1}, 252 /* DImag */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, 0, 1, -1, -1, -1, -1}, 253 /* LDImag */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0, -1, -1, -1, -1}, 254 255 /* I128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 3, 4, 5, -1, -1, -1, 0, 1, 4, 4}, 256 /* U128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 2, 3, 4, -1, -1, -1, -1, 0, 3, 3}, 257 258 /* F80 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 0, 1}, 259 /* F128 */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 0}, 248 260 }; 249 250 void ConversionCost::visit( __attribute((unused)) VoidType *voidType ) { 261 static_assert( 262 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES, 263 "Each basic type kind should have a corresponding row in the cost matrix" 264 ); 265 266 267 void ConversionCost::postvisit( VoidType * ) { 251 268 cost = Cost::infinity; 252 269 } 253 270 254 void ConversionCost:: visit(BasicType *basicType) {271 void ConversionCost::postvisit(BasicType *basicType) { 255 272 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { 256 273 int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ]; … … 264 281 // xxx - not positive this is correct, but appears to allow casting int => enum 265 282 cost = Cost::unsafe; 266 } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) { 267 cost = Cost::unsafe; 268 } // if 269 } 270 271 void ConversionCost::visit( PointerType * pointerType ) { 283 } // if 284 // no cases for zero_t/one_t because it should not be possible to convert int, etc. to zero_t/one_t. 285 } 286 287 void ConversionCost::postvisit( PointerType * pointerType ) { 272 288 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { 273 PRINT( std::cerr << pointerType << " ===> " << destAsPtr; ) 274 Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers(); 275 Type::Qualifiers tq2 = destAsPtr->get_base()->get_qualifiers(); 276 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) { 289 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; ) 290 Type::Qualifiers tq1 = pointerType->base->get_qualifiers(); 291 Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers(); 292 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 293 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) 277 294 if ( tq1 == tq2 ) { 278 295 // types are the same … … 280 297 } else { 281 298 // types are the same, except otherPointer has more qualifiers 282 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )283 299 cost = Cost::safe; 284 300 } 285 } else { // xxx - this discards qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?301 } else { 286 302 int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env ); 287 303 PRINT( std::cerr << " :: " << assignResult << std::endl; ) 288 if ( assignResult > 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) { 289 cost = Cost::safe; 304 if ( assignResult > 0 && tq1 <= tq2 ) { 305 // xxx - want the case where qualifiers are added to be more expensive than the case where qualifiers are the same. Is 1 safe vs. 2 safe correct? 306 if ( tq1 == tq2 ) { 307 cost = Cost::safe; 308 } else if ( tq1 < tq2 ) { 309 cost = Cost::safe+Cost::safe; 310 } 290 311 } else if ( assignResult < 0 ) { 291 312 cost = Cost::unsafe; … … 293 314 // assignResult == 0 means Cost::Infinity 294 315 } // if 295 } else if ( dynamic_cast< ZeroType * >( dest ) ) { 296 cost = Cost::unsafe; 297 } // if 298 } 299 300 void ConversionCost::visit( ArrayType * ) {} 301 302 void ConversionCost::visit( ReferenceType * refType ) { 316 // case case for zero_t because it should not be possible to convert pointers to zero_t. 317 } // if 318 } 319 320 void ConversionCost::postvisit( ArrayType * ) {} 321 322 void ConversionCost::postvisit( ReferenceType * refType ) { 303 323 // Note: dest can never be a reference, since it would have been caught in an earlier check 304 324 assert( ! dynamic_cast< ReferenceType * >( dest ) ); … … 306 326 // recursively compute conversion cost from T1 to T2. 307 327 // cv can be safely dropped because of 'implicit dereference' behavior. 308 refType->base->accept( *this);328 cost = costFunc( refType->base, dest, indexer, env ); 309 329 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) { 310 330 cost.incReference(); // prefer exact qualifiers … … 317 337 } 318 338 319 void ConversionCost:: visit( FunctionType * ) {}320 321 void ConversionCost:: visit( StructInstType * inst ) {339 void ConversionCost::postvisit( FunctionType * ) {} 340 341 void ConversionCost::postvisit( StructInstType * inst ) { 322 342 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) { 323 343 if ( inst->name == destAsInst->name ) { … … 327 347 } 328 348 329 void ConversionCost:: visit( UnionInstType * inst ) {349 void ConversionCost::postvisit( UnionInstType * inst ) { 330 350 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) { 331 351 if ( inst->name == destAsInst->name ) { … … 335 355 } 336 356 337 void ConversionCost:: visit( EnumInstType * ) {357 void ConversionCost::postvisit( EnumInstType * ) { 338 358 static Type::Qualifiers q; 339 359 static BasicType integer( q, BasicType::SignedInt ); 340 integer.accept( *this); // safe if dest >= int360 cost = costFunc( &integer, dest, indexer, env ); // safe if dest >= int 341 361 if ( cost < Cost::unsafe ) { 342 362 cost.incSafe(); … … 344 364 } 345 365 346 void ConversionCost::visit( TraitInstType * ) {} 347 348 void ConversionCost::visit( TypeInstType *inst ) { 349 EqvClass eqvClass; 350 NamedTypeDecl *namedType; 351 if ( env.lookup( inst->get_name(), eqvClass ) ) { 352 cost = conversionCost( eqvClass.type, dest, indexer, env ); 366 void ConversionCost::postvisit( TraitInstType * ) {} 367 368 void ConversionCost::postvisit( TypeInstType *inst ) { 369 if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) { 370 cost = costFunc( eqvClass->type, dest, indexer, env ); 353 371 } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) { 354 if ( inst-> get_name() == destAsInst->get_name()) {372 if ( inst->name == destAsInst->name ) { 355 373 cost = Cost::zero; 356 374 } 357 } else if ( ( namedType = indexer.lookupType( inst->get_name() )) ) {375 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) { 358 376 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType ); 359 377 // all typedefs should be gone by this point 360 378 assert( type ); 361 if ( type-> get_base()) {362 cost = co nversionCost( type->get_base(), dest, indexer, env ) + Cost::safe;363 } // if 364 } // if 365 } 366 367 void ConversionCost:: visit( TupleType * tupleType ) {379 if ( type->base ) { 380 cost = costFunc( type->base, dest, indexer, env ) + Cost::safe; 381 } // if 382 } // if 383 } 384 385 void ConversionCost::postvisit( TupleType * tupleType ) { 368 386 Cost c = Cost::zero; 369 387 if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) { 370 std::list< Type * >::const_iterator srcIt = tupleType-> get_types().begin();371 std::list< Type * >::const_iterator destIt = destAsTuple-> get_types().begin();372 while ( srcIt != tupleType-> get_types().end() && destIt != destAsTuple->get_types().end() ) {373 Cost newCost = co nversionCost( *srcIt++, *destIt++, indexer, env );388 std::list< Type * >::const_iterator srcIt = tupleType->types.begin(); 389 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin(); 390 while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) { 391 Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env ); 374 392 if ( newCost == Cost::infinity ) { 375 393 return; … … 377 395 c += newCost; 378 396 } // while 379 if ( destIt != destAsTuple-> get_types().end() ) {397 if ( destIt != destAsTuple->types.end() ) { 380 398 cost = Cost::infinity; 381 399 } else { … … 385 403 } 386 404 387 void ConversionCost:: visit( VarArgsType * ) {405 void ConversionCost::postvisit( VarArgsType * ) { 388 406 if ( dynamic_cast< VarArgsType* >( dest ) ) { 389 407 cost = Cost::zero; … … 391 409 } 392 410 393 void ConversionCost:: visit( ZeroType * ) {411 void ConversionCost::postvisit( ZeroType * ) { 394 412 if ( dynamic_cast< ZeroType * >( dest ) ) { 395 413 cost = Cost::zero; … … 408 426 } 409 427 410 void ConversionCost:: visit( OneType * ) {428 void ConversionCost::postvisit( OneType * ) { 411 429 if ( dynamic_cast< OneType * >( dest ) ) { 412 430 cost = Cost::zero;
Note:
See TracChangeset
for help on using the changeset viewer.