Changeset b067d9b for src/ResolvExpr/ConversionCost.cc
- Timestamp:
- Oct 29, 2019, 4:01:24 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 773db65, 9421f3d8
- Parents:
- 7951100 (diff), 8364209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/ConversionCost.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 07:06:19 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Sep 25 15:43:34 201713 // Update Count : 1011 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Aug 12 10:21:00 2019 13 // Update Count : 27 14 14 // 15 15 … … 28 28 29 29 namespace ResolvExpr { 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 ); 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 36 41 37 42 #if 0 … … 40 45 #define PRINT(x) 41 46 #endif 42 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 43 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 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 ) ) { 44 51 PRINT( std::cerr << "type inst " << destAsTypeInst->name; ) 45 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {52 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 46 53 if ( eqvClass->type ) { 47 return conversionCost( src, eqvClass->type, indexer, env );54 return conversionCost( src, eqvClass->type, srcIsLvalue, indexer, env ); 48 55 } else { 49 56 return Cost::infinity; 50 57 } 51 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {58 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 52 59 PRINT( std::cerr << " found" << std::endl; ) 53 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );60 const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType ); 54 61 // all typedefs should be gone by this point 55 62 assert( type ); 56 63 if ( type->base ) { 57 return conversionCost( src, type->base, indexer, env ) + Cost::safe; 64 return conversionCost( src, type->base, srcIsLvalue, indexer, env ) 65 + Cost::safe; 58 66 } // if 59 67 } // if … … 71 79 PRINT( std::cerr << "compatible!" << std::endl; ) 72 80 return Cost::zero; 73 } else if ( dynamic_cast< VoidType* >( dest ) ) {81 } else if ( dynamic_cast< const VoidType * >( dest ) ) { 74 82 return Cost::safe; 75 } else if ( ReferenceType * refType = dynamic_cast<ReferenceType * > ( dest ) ) {83 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 76 84 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 77 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1,Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){85 return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){ 78 86 return ptrsAssignable( t1, t2, env ); 79 87 }); 80 88 } else { 81 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost ); 89 PassVisitor<ConversionCost> converter( 90 dest, srcIsLvalue, indexer, env, 91 (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&)) 92 conversionCost ); 82 93 src->accept( converter ); 83 94 if ( converter.pass.get_cost() == Cost::infinity ) { … … 89 100 } 90 101 91 Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 102 static Cost convertToReferenceCost( const Type * src, const Type * dest, bool srcIsLvalue, 103 int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 92 104 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; ) 93 105 if ( diff > 0 ) { 94 106 // TODO: document this 95 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func ); 107 Cost cost = convertToReferenceCost( 108 strict_dynamic_cast< const ReferenceType * >( src )->base, dest, srcIsLvalue, 109 diff-1, indexer, env, func ); 96 110 cost.incReference(); 97 111 return cost; 98 112 } else if ( diff < -1 ) { 99 113 // TODO: document this 100 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func ); 114 Cost cost = convertToReferenceCost( 115 src, strict_dynamic_cast< const ReferenceType * >( dest )->base, srcIsLvalue, 116 diff+1, indexer, env, func ); 101 117 cost.incReference(); 102 118 return cost; 103 119 } else if ( diff == 0 ) { 104 ReferenceType * srcAsRef = dynamic_cast<ReferenceType * >( src );105 ReferenceType * destAsRef = dynamic_cast<ReferenceType * >( dest );120 const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src ); 121 const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest ); 106 122 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references 107 123 PRINT( std::cerr << "converting between references" << std::endl; ) 108 Type::Qualifiers tq1 = srcAsRef->base-> get_qualifiers();109 Type::Qualifiers tq2 = destAsRef->base-> get_qualifiers();124 Type::Qualifiers tq1 = srcAsRef->base->tq; 125 Type::Qualifiers tq2 = destAsRef->base->tq; 110 126 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) { 111 127 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 128 144 } else { 129 145 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; ) 130 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost ); 146 PassVisitor<ConversionCost> converter( 147 dest, srcIsLvalue, indexer, env, 148 (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&)) 149 conversionCost ); 131 150 src->accept( converter ); 132 151 return converter.pass.get_cost(); 133 152 } // if 134 153 } else { 135 ReferenceType * destAsRef = dynamic_cast<ReferenceType * >( dest );154 const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest ); 136 155 assert( diff == -1 && destAsRef ); 137 156 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; ) 138 157 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) { 139 158 PRINT( std::cerr << "converting compatible base type" << std::endl; ) 140 if ( src ->get_lvalue()) {159 if ( srcIsLvalue ) { 141 160 PRINT( 142 161 std::cerr << "lvalue to reference conversion" << std::endl; … … 144 163 ) 145 164 // lvalue-to-reference conversion: cv lvalue T => cv T & 146 if ( src-> get_qualifiers() == destAsRef->base->get_qualifiers()) {165 if ( src->tq == destAsRef->base->tq ) { 147 166 return Cost::reference; // cost needs to be non-zero to add cast 148 } if ( src-> get_qualifiers() < destAsRef->base->get_qualifiers()) {167 } if ( src->tq < destAsRef->base->tq ) { 149 168 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same 150 169 } else { … … 166 185 } 167 186 168 Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 187 Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue, 188 const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 169 189 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth(); 170 Cost cost = convertToReferenceCost( src, dest, s depth-ddepth, indexer, env, func );190 Cost cost = convertToReferenceCost( src, dest, srcIsLvalue, sdepth-ddepth, indexer, env, func ); 171 191 PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; ) 172 192 return cost; 173 193 } 174 194 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 }; 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 261 267 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"268 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 269 "Missing row in the cost matrix" 264 270 ); 265 271 266 267 void ConversionCost::postvisit( VoidType * ) { 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 * ) { 268 320 cost = Cost::infinity; 269 321 } 270 322 271 void ConversionCost::postvisit( BasicType *basicType) {272 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {273 int tableResult = costMatrix[ basicType-> get_kind() ][ destAsBasic->get_kind()];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 ]; 274 326 if ( tableResult == -1 ) { 275 327 cost = Cost::unsafe; … … 277 329 cost = Cost::zero; 278 330 cost.incSafe( tableResult ); 279 } // if 280 } else if ( dynamic_cast< EnumInstType *>( dest ) ) { 331 cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] ); 332 } // if 333 } else if ( dynamic_cast< const EnumInstType * >( dest ) ) { 281 334 // xxx - not positive this is correct, but appears to allow casting int => enum 282 335 cost = Cost::unsafe; … … 285 338 } 286 339 287 void ConversionCost::postvisit( PointerType * pointerType ) {288 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {340 void ConversionCost::postvisit( const PointerType * pointerType ) { 341 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) { 289 342 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; ) 290 Type::Qualifiers tq1 = pointerType->base-> get_qualifiers();291 Type::Qualifiers tq2 = destAsPtr->base-> get_qualifiers();343 Type::Qualifiers tq1 = pointerType->base->tq; 344 Type::Qualifiers tq2 = destAsPtr->base->tq; 292 345 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 293 346 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 298 351 // types are the same, except otherPointer has more qualifiers 299 352 cost = Cost::safe; 300 } 353 } // if 301 354 } else { 302 355 int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env ); … … 318 371 } 319 372 320 void ConversionCost::postvisit( ArrayType * ) {}321 322 void ConversionCost::postvisit( ReferenceType * refType ) {373 void ConversionCost::postvisit( const ArrayType * ) {} 374 375 void ConversionCost::postvisit( const ReferenceType * refType ) { 323 376 // Note: dest can never be a reference, since it would have been caught in an earlier check 324 assert( ! dynamic_cast< ReferenceType * >( dest ) );377 assert( ! dynamic_cast< const ReferenceType * >( dest ) ); 325 378 // convert reference to rvalue: cv T1 & => T2 326 379 // recursively compute conversion cost from T1 to T2. 327 380 // cv can be safely dropped because of 'implicit dereference' behavior. 328 cost = costFunc( refType->base, dest, indexer, env );329 if ( refType->base-> get_qualifiers() == dest->get_qualifiers()) {381 cost = costFunc( refType->base, dest, srcIsLvalue, indexer, env ); 382 if ( refType->base->tq == dest->tq ) { 330 383 cost.incReference(); // prefer exact qualifiers 331 } else if ( refType->base-> get_qualifiers() < dest->get_qualifiers()) {384 } else if ( refType->base->tq < dest->tq ) { 332 385 cost.incSafe(); // then gaining qualifiers 333 386 } else { … … 337 390 } 338 391 339 void ConversionCost::postvisit( FunctionType * ) {}340 341 void ConversionCost::postvisit( StructInstType * inst ) {342 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {392 void ConversionCost::postvisit( const FunctionType * ) {} 393 394 void ConversionCost::postvisit( const StructInstType * inst ) { 395 if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) { 343 396 if ( inst->name == destAsInst->name ) { 344 397 cost = Cost::zero; … … 347 400 } 348 401 349 void ConversionCost::postvisit( UnionInstType * inst ) {350 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {402 void ConversionCost::postvisit( const UnionInstType * inst ) { 403 if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) { 351 404 if ( inst->name == destAsInst->name ) { 352 405 cost = Cost::zero; … … 355 408 } 356 409 357 void ConversionCost::postvisit( EnumInstType * ) {410 void ConversionCost::postvisit( const EnumInstType * ) { 358 411 static Type::Qualifiers q; 359 412 static BasicType integer( q, BasicType::SignedInt ); 360 cost = costFunc( &integer, dest, indexer, env ); // safe if dest >= int413 cost = costFunc( &integer, dest, srcIsLvalue, indexer, env ); // safe if dest >= int 361 414 if ( cost < Cost::unsafe ) { 362 415 cost.incSafe(); … … 364 417 } 365 418 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 ) ) {419 void ConversionCost::postvisit( const TraitInstType * ) {} 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 ) ) { 372 425 if ( inst->name == destAsInst->name ) { 373 426 cost = Cost::zero; 374 427 } 375 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {376 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );428 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) { 429 const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType ); 377 430 // all typedefs should be gone by this point 378 431 assert( type ); 379 432 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 ) {433 cost = costFunc( type->base, dest, srcIsLvalue, indexer, env ) + Cost::safe; 434 } // if 435 } // if 436 } 437 438 void ConversionCost::postvisit( const TupleType * tupleType ) { 386 439 Cost c = Cost::zero; 387 if ( TupleType * destAsTuple = dynamic_cast<TupleType * >( dest ) ) {440 if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) { 388 441 std::list< Type * >::const_iterator srcIt = tupleType->types.begin(); 389 442 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin(); 390 443 while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) { 391 Cost newCost = costFunc( * srcIt++, *destIt++, indexer, env );444 Cost newCost = costFunc( * srcIt++, * destIt++, srcIsLvalue, indexer, env ); 392 445 if ( newCost == Cost::infinity ) { 393 446 return; … … 403 456 } 404 457 405 void ConversionCost::postvisit( VarArgsType * ) {406 if ( dynamic_cast< VarArgsType* >( dest ) ) {407 cost = Cost::zero; 408 } 409 } 410 411 void ConversionCost::postvisit( ZeroType * ) {412 if ( dynamic_cast< ZeroType * >( dest ) ) {413 cost = Cost::zero; 414 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {415 // copied from visit(BasicType *) for signed int, but +1 for safe conversions416 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()];458 void ConversionCost::postvisit( const VarArgsType * ) { 459 if ( dynamic_cast< const VarArgsType * >( dest ) ) { 460 cost = Cost::zero; 461 } 462 } 463 464 void ConversionCost::postvisit( const ZeroType * ) { 465 if ( dynamic_cast< const ZeroType * >( dest ) ) { 466 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 conversions 469 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 417 470 if ( tableResult == -1 ) { 418 471 cost = Cost::unsafe; … … 420 473 cost = Cost::zero; 421 474 cost.incSafe( tableResult + 1 ); 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 ) ) { 430 cost = Cost::zero; 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() ]; 475 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 476 } // if 477 } else if ( dynamic_cast< const PointerType * >( dest ) ) { 478 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 ]; 434 489 if ( tableResult == -1 ) { 435 490 cost = Cost::unsafe; … … 437 492 cost = Cost::zero; 438 493 cost.incSafe( tableResult + 1 ); 494 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 495 } // if 496 } // if 497 } 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 system 505 // is removed. 506 static Cost localConversionCost( 507 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 508 const ast::TypeEnvironment & env 509 ) { 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 & env 514 ) { 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; 439 521 } 440 } 441 } 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 } 528 } 529 } 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 => enum 632 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::infinity 658 } 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 442 798 } // namespace ResolvExpr 443 799
Note:
See TracChangeset
for help on using the changeset viewer.