- File:
-
- 1 edited
-
src/ResolvExpr/ConversionCost.cc (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/ConversionCost.cc
r849720f r00ac42e 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 07:06:19 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Aug 12 10:21:00 201913 // Update Count : 2711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 25 15:43:34 2017 13 // Update Count : 10 14 14 // 15 15 … … 28 28 29 29 namespace ResolvExpr { 30 #if 0 31 const Cost Cost::zero = Cost{ 0, 0, 0, 0, 0, 0, 0 }; 32 const Cost Cost::infinity = Cost{ -1, -1, -1, -1, -1, 1, -1 }; 33 const Cost Cost::unsafe = Cost{ 1, 0, 0, 0, 0, 0, 0 }; 34 const Cost Cost::poly = Cost{ 0, 1, 0, 0, 0, 0, 0 }; 35 const Cost Cost::safe = Cost{ 0, 0, 1, 0, 0, 0, 0 }; 36 const Cost Cost::sign = Cost{ 0, 0, 0, 1, 0, 0, 0 }; 37 const Cost Cost::var = Cost{ 0, 0, 0, 0, 1, 0, 0 }; 38 const Cost Cost::spec = Cost{ 0, 0, 0, 0, 0, -1, 0 }; 39 const Cost Cost::reference = Cost{ 0, 0, 0, 0, 0, 0, 1 }; 40 #endif 30 const Cost Cost::zero = Cost( 0, 0, 0, 0 ); 31 const Cost Cost::infinity = Cost( -1, -1, -1, -1 ); 32 const Cost Cost::unsafe = Cost( 1, 0, 0, 0 ); 33 const Cost Cost::poly = Cost( 0, 1, 0, 0 ); 34 const Cost Cost::safe = Cost( 0, 0, 1, 0 ); 35 const Cost Cost::reference = Cost( 0, 0, 0, 1 ); 41 36 42 37 #if 0 … … 45 40 #define PRINT(x) 46 41 #endif 47 48 Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue, 49 const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 50 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 42 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 43 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 51 44 PRINT( std::cerr << "type inst " << destAsTypeInst->name; ) 52 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {45 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) { 53 46 if ( eqvClass->type ) { 54 return conversionCost( src, eqvClass->type, srcIsLvalue,indexer, env );47 return conversionCost( src, eqvClass->type, indexer, env ); 55 48 } else { 56 49 return Cost::infinity; 57 50 } 58 } else if ( const NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {51 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) { 59 52 PRINT( std::cerr << " found" << std::endl; ) 60 const TypeDecl * type = dynamic_cast< const TypeDecl* >( namedType );53 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType ); 61 54 // all typedefs should be gone by this point 62 55 assert( type ); 63 56 if ( type->base ) { 64 return conversionCost( src, type->base, srcIsLvalue, indexer, env ) 65 + Cost::safe; 57 return conversionCost( src, type->base, indexer, env ) + Cost::safe; 66 58 } // if 67 59 } // if … … 79 71 PRINT( std::cerr << "compatible!" << std::endl; ) 80 72 return Cost::zero; 81 } else if ( dynamic_cast< const VoidType* >( dest ) ) {73 } else if ( dynamic_cast< VoidType* >( dest ) ) { 82 74 return Cost::safe; 83 } else if ( const ReferenceType * refType = dynamic_cast< constReferenceType * > ( dest ) ) {75 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) { 84 76 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 85 return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * const t1, constType * t2, const SymTab::Indexer &, const TypeEnvironment & env ){77 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){ 86 78 return ptrsAssignable( t1, t2, env ); 87 79 }); 88 80 } else { 89 PassVisitor<ConversionCost> converter( 90 dest, srcIsLvalue, indexer, env, 91 (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&)) 92 conversionCost ); 81 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost ); 93 82 src->accept( converter ); 94 83 if ( converter.pass.get_cost() == Cost::infinity ) { … … 100 89 } 101 90 102 static Cost convertToReferenceCost( const Type * src, const Type * dest, bool srcIsLvalue, 103 int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 91 Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 104 92 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; ) 105 93 if ( diff > 0 ) { 106 94 // TODO: document this 107 Cost cost = convertToReferenceCost( 108 strict_dynamic_cast< const ReferenceType * >( src )->base, dest, srcIsLvalue, 109 diff-1, indexer, env, func ); 95 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func ); 110 96 cost.incReference(); 111 97 return cost; 112 98 } else if ( diff < -1 ) { 113 99 // TODO: document this 114 Cost cost = convertToReferenceCost( 115 src, strict_dynamic_cast< const ReferenceType * >( dest )->base, srcIsLvalue, 116 diff+1, indexer, env, func ); 100 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func ); 117 101 cost.incReference(); 118 102 return cost; 119 103 } else if ( diff == 0 ) { 120 const ReferenceType * srcAsRef = dynamic_cast< constReferenceType * >( src );121 const ReferenceType * destAsRef = dynamic_cast< constReferenceType * >( dest );104 ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src ); 105 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest ); 122 106 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references 123 107 PRINT( std::cerr << "converting between references" << std::endl; ) 124 Type::Qualifiers tq1 = srcAsRef->base-> tq;125 Type::Qualifiers tq2 = destAsRef->base-> tq;108 Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers(); 109 Type::Qualifiers tq2 = destAsRef->base->get_qualifiers(); 126 110 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) { 127 111 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 144 128 } else { 145 129 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; ) 146 PassVisitor<ConversionCost> converter( 147 dest, srcIsLvalue, indexer, env, 148 (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&)) 149 conversionCost ); 130 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost ); 150 131 src->accept( converter ); 151 132 return converter.pass.get_cost(); 152 133 } // if 153 134 } else { 154 const ReferenceType * destAsRef = dynamic_cast< constReferenceType * >( dest );135 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest ); 155 136 assert( diff == -1 && destAsRef ); 156 137 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; ) 157 138 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) { 158 139 PRINT( std::cerr << "converting compatible base type" << std::endl; ) 159 if ( src IsLvalue) {140 if ( src->get_lvalue() ) { 160 141 PRINT( 161 142 std::cerr << "lvalue to reference conversion" << std::endl; … … 163 144 ) 164 145 // lvalue-to-reference conversion: cv lvalue T => cv T & 165 if ( src-> tq == destAsRef->base->tq) {146 if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) { 166 147 return Cost::reference; // cost needs to be non-zero to add cast 167 } if ( src-> tq < destAsRef->base->tq) {148 } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) { 168 149 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same 169 150 } else { … … 185 166 } 186 167 187 Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue, 188 const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 168 Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 189 169 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth(); 190 Cost cost = convertToReferenceCost( src, dest, s rcIsLvalue, sdepth-ddepth, indexer, env, func );170 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func ); 191 171 PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; ) 192 172 return cost; 193 173 } 194 174 195 ConversionCost::ConversionCost( const Type * dest, bool srcIsLvalue, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 196 : dest( dest ), srcIsLvalue( srcIsLvalue ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) { 197 } 198 199 // GENERATED START, DO NOT EDIT 200 // GENERATED BY BasicTypes-gen.cc 201 /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves) 202 _Bool 203 char signed char unsigned char 204 signed short int unsigned short int 205 signed int unsigned int 206 signed long int unsigned long int 207 signed long long int unsigned long long int 208 __int128 unsigned __int128 209 _Float16 _Float16 _Complex 210 _Float32 _Float32 _Complex 211 float float _Complex 212 _Float32x _Float32x _Complex 213 _Float64 _Float64 _Complex 214 double double _Complex 215 _Float64x _Float64x _Complex 216 __float80 217 _Float128 _Float128 _Complex 218 __float128 219 long double long double _Complex 220 _Float128x _Float128x _Complex 221 */ 222 // GENERATED END 223 224 // GENERATED START, DO NOT EDIT 225 // GENERATED BY BasicTypes-gen.cc 226 static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node 227 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 228 /* B */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 16, 18, 17, }, 229 /* C */ { -1, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 230 /* SC */ { -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 231 /* UC */ { -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 232 /* SI */ { -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, }, 233 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, }, 234 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, }, 235 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, }, 236 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, }, 237 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, }, 238 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, }, 239 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, }, 240 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, }, 241 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, }, 242 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 9, 11, 10, }, 243 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, -1, 7, -1, -1, 8, -1, 9, }, 244 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 8, 10, 9, }, 245 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, -1, 6, -1, -1, 7, -1, 8, }, 246 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 7, 9, 8, }, 247 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -1, 5, -1, -1, 6, -1, 7, }, 248 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 6, 8, 7, }, 249 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, 5, -1, 6, }, 250 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 5, 7, 6, }, 251 /* _FDC */ { -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, 1, -1, 2, -1, -1, 3, -1, -1, 4, -1, 5, }, 252 /* D */ { -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, 1, 1, 2, 2, 3, 3, 4, 5, 4, 6, 5, }, 253 /* DC */ { -1, -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, -1, 1, -1, -1, 2, -1, -1, 3, -1, 4, }, 254 /* F80X */ { -1, -1, -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, 1, 1, 2, 2, 3, 4, 3, 5, 4, }, 255 /* _FDXC */ { -1, -1, -1, -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, -1, -1, 1, -1, -1, 2, -1, 3, }, 256 /* F80 */ { -1, -1, -1, -1, -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, 1, 2, 2, 3, 3, 4, 4, }, 257 /* _FB */ { -1, -1, -1, -1, -1, -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, 1, 1, 2, 2, 3, 3, }, 258 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -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, -1, -1, 1, -1, 2, }, 259 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -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, 1, 2, 2, 3, }, 260 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -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, 1, 1, 2, }, 261 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, -1, 1, }, 262 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, 1, }, 263 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, }, 264 }; // costMatrix 265 static const int maxIntCost = 15; 266 // GENERATED END 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 ) { 177 } 178 179 /* 180 Old 181 === 182 Double 183 | 184 Float 185 | 186 ULong 187 / \ 188 UInt Long 189 \ / 190 Int 191 | 192 Ushort 193 | 194 Short 195 | 196 Uchar 197 / \ 198 Schar Char 199 200 New 201 === 202 +-----LongDoubleComplex--+ 203 LongDouble--+ | +-LongDoubleImag 204 | +---DoubleComplex---+ | 205 Double------+ | +----DoubleImag 206 | +-FloatComplex-+ | 207 Float---------+ +-------FloatImag 208 | 209 ULongLong 210 | 211 LongLong 212 | 213 ULong 214 / \ 215 UInt Long 216 \ / 217 Int 218 | 219 Ushort 220 | 221 Short 222 | 223 Uchar 224 / \ 225 Schar Char 226 \ / 227 Bool 228 */ 229 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}, 260 }; 267 261 static_assert( 268 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,269 " Missing row in the cost matrix"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" 270 264 ); 271 265 272 // GENERATED START, DO NOT EDIT 273 // GENERATED BY BasicTypes-gen.cc 274 static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion 275 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 276 /* B */ { 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 277 /* C */ { -1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 278 /* SC */ { -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 279 /* UC */ { -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 280 /* SI */ { -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 281 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 282 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 283 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 284 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 285 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 286 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 287 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 288 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 289 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 290 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 291 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 292 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 293 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 294 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 295 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 296 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 297 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 298 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 299 /* _FDC */ { -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, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 300 /* D */ { -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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 301 /* DC */ { -1, -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, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 302 /* F80X */ { -1, -1, -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, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 303 /* _FDXC */ { -1, -1, -1, -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, -1, -1, 0, -1, -1, 0, -1, 0, }, 304 /* F80 */ { -1, -1, -1, -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, 0, 0, 0, 0, 0, 0, 0, 0, }, 305 /* _FB */ { -1, -1, -1, -1, -1, -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, 0, 0, 0, 0, 0, 0, }, 306 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -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, -1, -1, 0, -1, 0, }, 307 /* FB */ { -1, -1, -1, -1, -1, -1, -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, 0, 0, 0, 0, 0, }, 308 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -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, 0, 0, 0, }, 309 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, -1, 0, }, 310 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, 0, }, 311 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, }, 312 }; // signMatrix 313 // GENERATED END 314 static_assert( 315 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 316 "Missing row in the sign matrix" 317 ); 318 319 void ConversionCost::postvisit( const VoidType * ) { 266 267 void ConversionCost::postvisit( VoidType * ) { 320 268 cost = Cost::infinity; 321 269 } 322 270 323 void ConversionCost::postvisit( const BasicType *basicType) {324 if ( const BasicType * destAsBasic = dynamic_cast< const BasicType* >( dest ) ) {325 int tableResult = costMatrix[ basicType-> kind ][ destAsBasic->kind];271 void ConversionCost::postvisit(BasicType *basicType) { 272 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { 273 int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ]; 326 274 if ( tableResult == -1 ) { 327 275 cost = Cost::unsafe; … … 329 277 cost = Cost::zero; 330 278 cost.incSafe( tableResult ); 331 cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] ); 332 } // if 333 } else if ( dynamic_cast< const EnumInstType * >( dest ) ) { 279 } // if 280 } else if ( dynamic_cast< EnumInstType *>( dest ) ) { 334 281 // xxx - not positive this is correct, but appears to allow casting int => enum 335 282 cost = Cost::unsafe; … … 338 285 } 339 286 340 void ConversionCost::postvisit( constPointerType * pointerType ) {341 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType* >( dest ) ) {287 void ConversionCost::postvisit( PointerType * pointerType ) { 288 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { 342 289 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; ) 343 Type::Qualifiers tq1 = pointerType->base-> tq;344 Type::Qualifiers tq2 = destAsPtr->base-> tq;290 Type::Qualifiers tq1 = pointerType->base->get_qualifiers(); 291 Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers(); 345 292 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 346 293 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 351 298 // types are the same, except otherPointer has more qualifiers 352 299 cost = Cost::safe; 353 } // if300 } 354 301 } else { 355 302 int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env ); … … 371 318 } 372 319 373 void ConversionCost::postvisit( constArrayType * ) {}374 375 void ConversionCost::postvisit( constReferenceType * refType ) {320 void ConversionCost::postvisit( ArrayType * ) {} 321 322 void ConversionCost::postvisit( ReferenceType * refType ) { 376 323 // Note: dest can never be a reference, since it would have been caught in an earlier check 377 assert( ! dynamic_cast< constReferenceType * >( dest ) );324 assert( ! dynamic_cast< ReferenceType * >( dest ) ); 378 325 // convert reference to rvalue: cv T1 & => T2 379 326 // recursively compute conversion cost from T1 to T2. 380 327 // cv can be safely dropped because of 'implicit dereference' behavior. 381 cost = costFunc( refType->base, dest, srcIsLvalue,indexer, env );382 if ( refType->base-> tq == dest->tq) {328 cost = costFunc( refType->base, dest, indexer, env ); 329 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) { 383 330 cost.incReference(); // prefer exact qualifiers 384 } else if ( refType->base-> tq < dest->tq) {331 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) { 385 332 cost.incSafe(); // then gaining qualifiers 386 333 } else { … … 390 337 } 391 338 392 void ConversionCost::postvisit( constFunctionType * ) {}393 394 void ConversionCost::postvisit( constStructInstType * inst ) {395 if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType* >( dest ) ) {339 void ConversionCost::postvisit( FunctionType * ) {} 340 341 void ConversionCost::postvisit( StructInstType * inst ) { 342 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) { 396 343 if ( inst->name == destAsInst->name ) { 397 344 cost = Cost::zero; … … 400 347 } 401 348 402 void ConversionCost::postvisit( constUnionInstType * inst ) {403 if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType* >( dest ) ) {349 void ConversionCost::postvisit( UnionInstType * inst ) { 350 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) { 404 351 if ( inst->name == destAsInst->name ) { 405 352 cost = Cost::zero; … … 408 355 } 409 356 410 void ConversionCost::postvisit( constEnumInstType * ) {357 void ConversionCost::postvisit( EnumInstType * ) { 411 358 static Type::Qualifiers q; 412 359 static BasicType integer( q, BasicType::SignedInt ); 413 cost = costFunc( &integer, dest, srcIsLvalue,indexer, env ); // safe if dest >= int360 cost = costFunc( &integer, dest, indexer, env ); // safe if dest >= int 414 361 if ( cost < Cost::unsafe ) { 415 362 cost.incSafe(); … … 417 364 } 418 365 419 void ConversionCost::postvisit( constTraitInstType * ) {}420 421 void ConversionCost::postvisit( const TypeInstType *inst ) {422 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {423 cost = costFunc( eqvClass->type, dest, srcIsLvalue,indexer, env );424 } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType* >( dest ) ) {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 ); 371 } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) { 425 372 if ( inst->name == destAsInst->name ) { 426 373 cost = Cost::zero; 427 374 } 428 } else if ( const NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {429 const TypeDecl * type = dynamic_cast< const TypeDecl* >( namedType );375 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) { 376 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType ); 430 377 // all typedefs should be gone by this point 431 378 assert( type ); 432 379 if ( type->base ) { 433 cost = costFunc( type->base, dest, srcIsLvalue,indexer, env ) + Cost::safe;434 } // if 435 } // if 436 } 437 438 void ConversionCost::postvisit( constTupleType * tupleType ) {380 cost = costFunc( type->base, dest, indexer, env ) + Cost::safe; 381 } // if 382 } // if 383 } 384 385 void ConversionCost::postvisit( TupleType * tupleType ) { 439 386 Cost c = Cost::zero; 440 if ( const TupleType * destAsTuple = dynamic_cast< constTupleType * >( dest ) ) {387 if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) { 441 388 std::list< Type * >::const_iterator srcIt = tupleType->types.begin(); 442 389 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin(); 443 390 while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) { 444 Cost newCost = costFunc( * srcIt++, * destIt++, srcIsLvalue, indexer, env );391 Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env ); 445 392 if ( newCost == Cost::infinity ) { 446 393 return; … … 456 403 } 457 404 458 void ConversionCost::postvisit( constVarArgsType * ) {459 if ( dynamic_cast< const VarArgsType* >( dest ) ) {405 void ConversionCost::postvisit( VarArgsType * ) { 406 if ( dynamic_cast< VarArgsType* >( dest ) ) { 460 407 cost = Cost::zero; 461 408 } 462 409 } 463 410 464 void ConversionCost::postvisit( constZeroType * ) {465 if ( dynamic_cast< constZeroType * >( dest ) ) {411 void ConversionCost::postvisit( ZeroType * ) { 412 if ( dynamic_cast< ZeroType * >( dest ) ) { 466 413 cost = Cost::zero; 467 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType* >( dest ) ) {468 // copied from visit(BasicType *) for signed int, but +1 for safe conversions469 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> kind];414 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { 415 // copied from visit(BasicType*) for signed int, but +1 for safe conversions 416 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ]; 470 417 if ( tableResult == -1 ) { 471 418 cost = Cost::unsafe; … … 473 420 cost = Cost::zero; 474 421 cost.incSafe( tableResult + 1 ); 475 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 476 } // if 477 } else if ( dynamic_cast< const PointerType * >( dest ) ) { 422 } 423 } else if ( dynamic_cast< PointerType* >( dest ) ) { 424 cost = Cost::safe; 425 } 426 } 427 428 void ConversionCost::postvisit( OneType * ) { 429 if ( dynamic_cast< OneType * >( dest ) ) { 478 430 cost = Cost::zero; 479 cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation 480 } // if 481 } 482 483 void ConversionCost::postvisit( const OneType * ) { 484 if ( dynamic_cast< const OneType * >( dest ) ) { 485 cost = Cost::zero; 486 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 487 // copied from visit(BasicType *) for signed int, but +1 for safe conversions 488 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 431 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { 432 // copied from visit(BasicType*) for signed int, but +1 for safe conversions 433 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ]; 489 434 if ( tableResult == -1 ) { 490 435 cost = Cost::unsafe; … … 492 437 cost = Cost::zero; 493 438 cost.incSafe( tableResult + 1 ); 494 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );495 } // if496 } // if497 }498 499 static int localPtrsAssignable(const ast::Type * t1, const ast::Type * t2,500 const ast::SymbolTable &, const ast::TypeEnvironment & env ) {501 return ptrsAssignable( t1, t2, env );502 }503 504 // TODO: This is used for overload resolution. It might be able to be dropped once the old system505 // is removed.506 static Cost localConversionCost(507 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,508 const ast::TypeEnvironment & env509 ) { return conversionCost( src, dst, symtab, env ); }510 511 Cost conversionCost(512 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,513 const ast::TypeEnvironment & env514 ) {515 if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {516 if ( const ast::EqvClass * eqv = env.lookup( inst->name ) ) {517 if ( eqv->bound ) {518 return conversionCost(src, eqv->bound, symtab, env );519 } else {520 return Cost::infinity;521 }522 } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {523 const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( named );524 assertf( type, "Unexpected typedef." );525 if ( type->base ) {526 return conversionCost( src, type->base, symtab, env ) + Cost::safe;527 439 } 528 440 } 529 441 } 530 if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) {531 return Cost::zero;532 } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {533 return Cost::safe;534 } else if ( const ast::ReferenceType * refType =535 dynamic_cast< const ast::ReferenceType * >( dst ) ) {536 return convertToReferenceCost( src, refType, symtab, env, localPtrsAssignable );537 } else {538 ast::Pass<ConversionCost_new> converter( dst, symtab, env, localConversionCost );539 src->accept( converter );540 return converter.pass.cost;541 }542 }543 544 static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst,545 int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,546 NumCostCalculation func ) {547 if ( 0 < diff ) {548 Cost cost = convertToReferenceCost(549 strict_dynamic_cast< const ast::ReferenceType * >( src )->base,550 dst, (diff - 1), symtab, env, func );551 cost.incReference();552 return cost;553 } else if ( diff < -1 ) {554 Cost cost = convertToReferenceCost(555 src, strict_dynamic_cast< const ast::ReferenceType * >( dst )->base,556 (diff + 1), symtab, env, func );557 cost.incReference();558 return cost;559 } else if ( 0 == diff ) {560 const ast::ReferenceType * srcAsRef = dynamic_cast< const ast::ReferenceType * >( src );561 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );562 if ( srcAsRef && dstAsRef ) {563 ast::CV::Qualifiers tq1 = srcAsRef->base->qualifiers;564 ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers;565 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(566 srcAsRef->base, dstAsRef->base, symtab, env ) ) {567 if ( tq1 == tq2 ) {568 return Cost::zero;569 } else {570 return Cost::safe;571 }572 } else {573 int assignResult = func( srcAsRef->base, dstAsRef->base, symtab, env );574 if ( 0 < assignResult ) {575 return Cost::safe;576 } else if ( assignResult < 0 ) {577 return Cost::unsafe;578 }579 }580 } else {581 ast::Pass<ConversionCost_new> converter( dst, symtab, env, localConversionCost );582 src->accept( converter );583 return converter.pass.cost;584 }585 } else {586 assert( -1 == diff );587 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );588 assert( dstAsRef );589 if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, symtab, env ) ) {590 if ( src->is_lvalue() ) {591 if ( src->qualifiers == dstAsRef->base->qualifiers ) {592 return Cost::reference;593 } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {594 return Cost::safe;595 } else {596 return Cost::unsafe;597 }598 } else if ( dstAsRef->base->is_const() ) {599 return Cost::safe;600 } else {601 return Cost::unsafe;602 }603 }604 }605 return Cost::infinity;606 }607 608 Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,609 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,610 NumCostCalculation func ) {611 int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();612 return convertToReferenceCost( src, dst, sdepth - ddepth, symtab, env, func );613 }614 615 void ConversionCost_new::postvisit( const ast::VoidType * voidType ) {616 (void)voidType;617 cost = Cost::infinity;618 }619 620 void ConversionCost_new::postvisit( const ast::BasicType * basicType ) {621 if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {622 int tableResult = costMatrix[ basicType->kind ][ dstAsBasic->kind ];623 if ( tableResult == -1 ) {624 cost = Cost::unsafe;625 } else {626 cost = Cost::zero;627 cost.incSafe( tableResult );628 cost.incSign( signMatrix[ basicType->kind ][ dstAsBasic->kind ] );629 }630 } else if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) {631 // xxx - not positive this is correct, but appears to allow casting int => enum632 cost = Cost::unsafe;633 }634 }635 636 void ConversionCost_new::postvisit( const ast::PointerType * pointerType ) {637 if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {638 ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;639 ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;640 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(641 pointerType->base, dstAsPtr->base, symtab, env ) ) {642 if ( tq1 == tq2 ) {643 cost = Cost::zero;644 } else {645 cost = Cost::safe;646 }647 } else {648 int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );649 if ( 0 < assignResult && tq1 <= tq2 ) {650 if ( tq1 == tq2 ) {651 cost = Cost::safe;652 } else {653 cost = Cost::safe + Cost::safe;654 }655 } else if ( assignResult < 0 ) {656 cost = Cost::unsafe;657 } // else Cost::infinity658 }659 }660 }661 662 void ConversionCost_new::postvisit( const ast::ArrayType * arrayType ) {663 (void)arrayType;664 }665 666 void ConversionCost_new::postvisit( const ast::ReferenceType * refType ) {667 assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );668 669 cost = costCalc( refType->base, dst, symtab, env );670 if ( refType->base->qualifiers == dst->qualifiers ) {671 cost.incReference();672 } else if ( refType->base->qualifiers < dst->qualifiers ) {673 cost.incSafe();674 } else {675 cost.incUnsafe();676 }677 }678 679 void ConversionCost_new::postvisit( const ast::FunctionType * functionType ) {680 (void)functionType;681 }682 683 void ConversionCost_new::postvisit( const ast::StructInstType * structInstType ) {684 if ( const ast::StructInstType * dstAsInst =685 dynamic_cast< const ast::StructInstType * >( dst ) ) {686 if ( structInstType->name == dstAsInst->name ) {687 cost = Cost::zero;688 }689 }690 }691 692 void ConversionCost_new::postvisit( const ast::UnionInstType * unionInstType ) {693 if ( const ast::UnionInstType * dstAsInst =694 dynamic_cast< const ast::UnionInstType * >( dst ) ) {695 if ( unionInstType->name == dstAsInst->name ) {696 cost = Cost::zero;697 }698 }699 }700 701 void ConversionCost_new::postvisit( const ast::EnumInstType * enumInstType ) {702 (void)enumInstType;703 static const ast::BasicType integer( ast::BasicType::SignedInt );704 cost = costCalc( &integer, dst, symtab, env );705 if ( cost < Cost::unsafe ) {706 cost.incSafe();707 }708 }709 710 void ConversionCost_new::postvisit( const ast::TraitInstType * traitInstType ) {711 (void)traitInstType;712 }713 714 void ConversionCost_new::postvisit( const ast::TypeInstType * typeInstType ) {715 if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {716 cost = costCalc( eqv->bound, dst, symtab, env );717 } else if ( const ast::TypeInstType * dstAsInst =718 dynamic_cast< const ast::TypeInstType * >( dst ) ) {719 if ( typeInstType->name == dstAsInst->name ) {720 cost = Cost::zero;721 }722 } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {723 const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );724 assertf( type, "Unexpected typedef.");725 if ( type->base ) {726 cost = costCalc( type->base, dst, symtab, env ) + Cost::safe;727 }728 }729 }730 731 void ConversionCost_new::postvisit( const ast::TupleType * tupleType ) {732 Cost c = Cost::zero;733 if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {734 auto srcIt = tupleType->types.begin();735 auto dstIt = dstAsTuple->types.begin();736 auto srcEnd = tupleType->types.end();737 auto dstEnd = dstAsTuple->types.end();738 while ( srcIt != srcEnd && dstIt != dstEnd ) {739 Cost newCost = costCalc( * srcIt++, * dstIt++, symtab, env );740 if ( newCost == Cost::infinity ) {741 return;742 }743 c += newCost;744 }745 if ( dstIt != dstEnd ) {746 cost = Cost::infinity;747 } else {748 cost = c;749 }750 }751 }752 753 void ConversionCost_new::postvisit( const ast::VarArgsType * varArgsType ) {754 (void)varArgsType;755 if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {756 cost = Cost::zero;757 }758 }759 760 void ConversionCost_new::postvisit( const ast::ZeroType * zeroType ) {761 (void)zeroType;762 if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {763 cost = Cost::zero;764 } else if ( const ast::BasicType * dstAsBasic =765 dynamic_cast< const ast::BasicType * >( dst ) ) {766 int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];767 if ( -1 == tableResult ) {768 cost = Cost::unsafe;769 } else {770 cost = Cost::zero;771 cost.incSafe( tableResult + 1 );772 cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );773 }774 }775 }776 777 void ConversionCost_new::postvisit( const ast::OneType * oneType ) {778 (void)oneType;779 if ( dynamic_cast< const ast::OneType * >( dst ) ) {780 cost = Cost::zero;781 } else if ( const ast::BasicType * dstAsBasic =782 dynamic_cast< const ast::BasicType * >( dst ) ) {783 int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];784 if ( -1 == tableResult ) {785 cost = Cost::unsafe;786 } else {787 cost = Cost::zero;788 cost.incSafe( tableResult + 1 );789 cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );790 }791 } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {792 cost = Cost::zero;793 cost.incSafe( maxIntCost + 2 );794 }795 }796 797 798 442 } // namespace ResolvExpr 799 443
Note:
See TracChangeset
for help on using the changeset viewer.