source: src/ResolvExpr/ConversionCost.cc@ 85d44c6

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr persistent-indexer pthread-emulation qualifiedEnum
Last change on this file since 85d44c6 was e15853c, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

remove leading underscores in enums for _FloatNN and _Bool

  • Property mode set to 100644
File size: 35.3 KB
RevLine 
[a32b204]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[a436947]7// ConversionCost.cc --
[a32b204]8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 07:06:19 2015
11// Last Modified By : Peter A. Buhr
[e15853c]12// Last Modified On : Wed Feb 13 23:04:51 2019
13// Update Count : 22
[a32b204]14//
[51b73452]15
16#include "ConversionCost.h"
[ea6332d]17
18#include <cassert> // for assert
19#include <list> // for list, list<>::const_iterator
20#include <string> // for operator==, string
21
22#include "ResolvExpr/Cost.h" // for Cost
23#include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment
24#include "SymTab/Indexer.h" // for Indexer
25#include "SynTree/Declaration.h" // for TypeDecl, NamedTypeDecl
26#include "SynTree/Type.h" // for Type, BasicType, TypeInstType
27#include "typeops.h" // for typesCompatibleIgnoreQualifiers
[51b73452]28
29namespace ResolvExpr {
[cdcddfe1]30 const Cost Cost::zero = Cost{ 0, 0, 0, 0, 0, 0, 0 };
31 const Cost Cost::infinity = Cost{ -1, -1, -1, -1, -1, 1, -1 };
32 const Cost Cost::unsafe = Cost{ 1, 0, 0, 0, 0, 0, 0 };
33 const Cost Cost::poly = Cost{ 0, 1, 0, 0, 0, 0, 0 };
34 const Cost Cost::safe = Cost{ 0, 0, 1, 0, 0, 0, 0 };
35 const Cost Cost::sign = Cost{ 0, 0, 0, 1, 0, 0, 0 };
36 const Cost Cost::var = Cost{ 0, 0, 0, 0, 1, 0, 0 };
37 const Cost Cost::spec = Cost{ 0, 0, 0, 0, 0, -1, 0 };
38 const Cost Cost::reference = Cost{ 0, 0, 0, 0, 0, 0, 1 };
[b46e3bd]39
[5ccb10d]40#if 0
41#define PRINT(x) x
42#else
43#define PRINT(x)
44#endif
[a32b204]45 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
46 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
[eb0aedb]47 PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
[00ac42e]48 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
49 if ( eqvClass->type ) {
50 return conversionCost( src, eqvClass->type, indexer, env );
[0b150ec]51 } else {
52 return Cost::infinity;
53 }
[00ac42e]54 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
[5ccb10d]55 PRINT( std::cerr << " found" << std::endl; )
[a32b204]56 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
57 // all typedefs should be gone by this point
58 assert( type );
[eb0aedb]59 if ( type->base ) {
60 return conversionCost( src, type->base, indexer, env ) + Cost::safe;
[a32b204]61 } // if
62 } // if
[5ccb10d]63 PRINT( std::cerr << " not found" << std::endl; )
[a32b204]64 } // if
[5ccb10d]65 PRINT(
66 std::cerr << "src is ";
67 src->print( std::cerr );
68 std::cerr << std::endl << "dest is ";
69 dest->print( std::cerr );
70 std::cerr << std::endl << "env is" << std::endl;
71 env.print( std::cerr, 8 );
72 )
[a32b204]73 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
[5ccb10d]74 PRINT( std::cerr << "compatible!" << std::endl; )
[89be1c68]75 return Cost::zero;
[a32b204]76 } else if ( dynamic_cast< VoidType* >( dest ) ) {
[89be1c68]77 return Cost::safe;
[2463d0e]78 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
[5ccb10d]79 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
[721cd19f]80 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
[0c6596f]81 return ptrsAssignable( t1, t2, env );
82 });
[a32b204]83 } else {
[bd0b6b62]84 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
[a32b204]85 src->accept( converter );
[bd0b6b62]86 if ( converter.pass.get_cost() == Cost::infinity ) {
[a32b204]87 return Cost::infinity;
88 } else {
[bd0b6b62]89 return converter.pass.get_cost() + Cost::zero;
[a32b204]90 } // if
91 } // if
92 }
93
[0c6596f]94 Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
[6e027d6]95 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
[89be1c68]96 if ( diff > 0 ) {
97 // TODO: document this
[eb0aedb]98 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
[7ebaa56]99 cost.incReference();
[89be1c68]100 return cost;
101 } else if ( diff < -1 ) {
102 // TODO: document this
[eb0aedb]103 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
[7ebaa56]104 cost.incReference();
[89be1c68]105 return cost;
106 } else if ( diff == 0 ) {
107 ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
108 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
109 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
[5ccb10d]110 PRINT( std::cerr << "converting between references" << std::endl; )
[eb0aedb]111 Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
112 Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
113 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
[6e027d6]114 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
115 if ( tq1 == tq2 ) {
116 // types are the same
117 return Cost::zero;
118 } else {
119 // types are the same, except otherPointer has more qualifiers
120 return Cost::safe;
121 }
[89be1c68]122 } else { // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
[721cd19f]123 int assignResult = func( srcAsRef->base, destAsRef->base, indexer, env );
[5ccb10d]124 PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
[b0837e4]125 if ( assignResult > 0 ) {
[89be1c68]126 return Cost::safe;
[b0837e4]127 } else if ( assignResult < 0 ) {
[89be1c68]128 return Cost::unsafe;
129 } // if
[2463d0e]130 } // if
131 } else {
[5ccb10d]132 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
[bd0b6b62]133 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
[89be1c68]134 src->accept( converter );
[bd0b6b62]135 return converter.pass.get_cost();
[89be1c68]136 } // if
[2463d0e]137 } else {
[89be1c68]138 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
139 assert( diff == -1 && destAsRef );
[108f3cdb]140 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
[eb0aedb]141 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
[5ccb10d]142 PRINT( std::cerr << "converting compatible base type" << std::endl; )
[89be1c68]143 if ( src->get_lvalue() ) {
[5ccb10d]144 PRINT(
145 std::cerr << "lvalue to reference conversion" << std::endl;
146 std::cerr << src << " => " << destAsRef << std::endl;
147 )
[89be1c68]148 // lvalue-to-reference conversion: cv lvalue T => cv T &
[eb0aedb]149 if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
[7ebaa56]150 return Cost::reference; // cost needs to be non-zero to add cast
[eb0aedb]151 } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
[7ebaa56]152 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
[89be1c68]153 } else {
154 return Cost::unsafe;
155 } // if
[eb0aedb]156 } else if ( destAsRef->base->get_const() ) {
[5ccb10d]157 PRINT( std::cerr << "rvalue to const ref conversion" << std::endl; )
[89be1c68]158 // rvalue-to-const-reference conversion: T => const T &
159 return Cost::safe;
160 } else {
[5ccb10d]161 PRINT( std::cerr << "rvalue to non-const reference conversion" << std::endl; )
[89be1c68]162 // rvalue-to-reference conversion: T => T &
163 return Cost::unsafe;
164 } // if
165 } // if
[5ccb10d]166 PRINT( std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl; )
[2463d0e]167 }
168 return Cost::infinity;
169 }
170
[0c6596f]171 Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
[89be1c68]172 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
[eddb399]173 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
174 PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
175 return cost;
[89be1c68]176 }
177
[721cd19f]178 ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
179 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
[a32b204]180 }
[cdcddfe1]181#if 0
[51b73452]182/*
[a32b204]183 Old
184 ===
185 Double
186 |
187 Float
188 |
189 ULong
190 / \
191 UInt Long
192 \ /
193 Int
194 |
195 Ushort
196 |
197 Short
198 |
199 Uchar
200 / \
201 Schar Char
202
203 New
204 ===
205 +-----LongDoubleComplex--+
206 LongDouble--+ | +-LongDoubleImag
207 | +---DoubleComplex---+ |
208 Double------+ | +----DoubleImag
209 | +-FloatComplex-+ |
210 Float---------+ +-------FloatImag
211 |
212 ULongLong
213 |
214 LongLong
215 |
216 ULong
217 / \
218 UInt Long
219 \ /
220 Int
221 |
222 Ushort
223 |
224 Short
225 |
226 Uchar
227 / \
228 Schar Char
229 \ /
230 Bool
[51b73452]231*/
232
[4ee3b0c1]233 static const int costMatrix[][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
234 /* 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 */
235 /* 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},
236 /* 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},
237 /* 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},
238 /* 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},
239 /* 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},
240 /* 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},
241 /* 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},
242 /* 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},
243 /* 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},
244 /* 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},
245 /* 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},
246 /* 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},
[201aeb9]247
[4ee3b0c1]248 /* 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},
249 /* 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},
250 /* 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},
251 /* 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},
252 /* 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},
253 /* 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},
254 /* 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},
255 /* 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},
256 /* 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},
[201aeb9]257
[4ee3b0c1]258 /* 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},
259 /* 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},
260
261 /* 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},
262 /* 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},
[a32b204]263 };
[4ee3b0c1]264 static_assert(
265 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
266 "Each basic type kind should have a corresponding row in the cost matrix"
267 );
[cdcddfe1]268#endif
[4ee3b0c1]269
[e15853c]270 // GENERATED START, DO NOT EDIT
[cdcddfe1]271 /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
[e15853c]272 _Bool
273 char signed char unsigned char
274 signed short int unsigned short int
275 signed int unsigned int
276 signed long int unsigned long int
277 signed long long int unsigned long long int
278 __int128 unsigned __int128
279 _Float16 _Float16 _Complex
280 _Float32 _Float32 _Complex
281 float float _Complex
282 _Float32x _Float32x _Complex
283 _Float64 _Float64 _Complex
284 double double _Complex
285 _Float64x _Float64x _Complex
286 __float80
287 _Float128 _Float128 _Complex
288 __float128
289 long double long double _Complex
290 _Float128x _Float128x _Complex
[cdcddfe1]291 */
[e15853c]292 // GENERATED END
[cdcddfe1]293
[e15853c]294 // GENERATED START, DO NOT EDIT
[cdcddfe1]295 static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
296 /* 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 */
297 /* 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,
298 /* 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,
299 /* 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,
300 /* 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,
301 /* 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,
302 /* 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,
303 /* 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,
304 /* 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,
305 /* 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,
306 /* 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,
307 /* 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,
308 /* 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,
309 /* 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,
310 /* 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,
311 /* _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,
312 /* _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,
313 /* _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,
314 /* _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,
315 /* 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,
316 /* 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,
317 /* _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,
318 /* _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,
319 /* 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,
320 /* _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,
321 /* 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,
322 /* 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,
323 /* 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,
324 /* _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,
325 /* 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,
326 /* _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,
327 /* _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,
328 /* 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,
329 /* 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,
330 /* 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,
331 /* _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,
332 /*_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,
[e15853c]333 }; // costMatrix
334 // GENERATED END
[cdcddfe1]335 static_assert(
336 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
337 "Missing row in the cost matrix"
338 );
339
[e15853c]340 // GENERATED START, DO NOT EDIT
[cdcddfe1]341 static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
342 /* 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 */
343 /* 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,
344 /* 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,
345 /* 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,
346 /* 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,
347 /* 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,
348 /* 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,
349 /* 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,
350 /* 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,
351 /* 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,
352 /* 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,
353 /* 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,
354 /* 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,
355 /* 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,
356 /* 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,
357 /* _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,
358 /* _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,
359 /* _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,
360 /* _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,
361 /* 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,
362 /* 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,
363 /* _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,
364 /* _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,
365 /* 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,
366 /* _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,
367 /* 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,
368 /* 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,
369 /* 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,
370 /* _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,
371 /* 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,
372 /* _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,
373 /* _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,
374 /* 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,
375 /* 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,
376 /* 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,
377 /* _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,
378 /*_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,
[e15853c]379 }; // signMatrix
380 // GENERATED END
[cdcddfe1]381 static_assert(
382 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
383 "Missing row in the sign matrix"
384 );
[a32b204]385
[bd0b6b62]386 void ConversionCost::postvisit( VoidType * ) {
[a32b204]387 cost = Cost::infinity;
388 }
389
[bd0b6b62]390 void ConversionCost::postvisit(BasicType *basicType) {
[a32b204]391 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
392 int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
393 if ( tableResult == -1 ) {
[89be1c68]394 cost = Cost::unsafe;
[a32b204]395 } else {
[89be1c68]396 cost = Cost::zero;
397 cost.incSafe( tableResult );
[cdcddfe1]398 cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
[a32b204]399 } // if
[a436947]400 } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
401 // xxx - not positive this is correct, but appears to allow casting int => enum
[89be1c68]402 cost = Cost::unsafe;
[89e6ffc]403 } // if
[98278b3a]404 // no cases for zero_t/one_t because it should not be possible to convert int, etc. to zero_t/one_t.
[a32b204]405 }
406
[bd0b6b62]407 void ConversionCost::postvisit( PointerType * pointerType ) {
[a32b204]408 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
[6e027d6]409 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
[eb0aedb]410 Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
411 Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
412 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
[6e027d6]413 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
[cb43451]414 if ( tq1 == tq2 ) {
415 // types are the same
416 cost = Cost::zero;
417 } else {
418 // types are the same, except otherPointer has more qualifiers
419 cost = Cost::safe;
[cdcddfe1]420 } // if
[b8b075cd]421 } else {
[b0837e4]422 int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
[5ccb10d]423 PRINT( std::cerr << " :: " << assignResult << std::endl; )
[b8b075cd]424 if ( assignResult > 0 && tq1 <= tq2 ) {
425 // 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?
426 if ( tq1 == tq2 ) {
427 cost = Cost::safe;
428 } else if ( tq1 < tq2 ) {
429 cost = Cost::safe+Cost::safe;
430 }
[b0837e4]431 } else if ( assignResult < 0 ) {
[89be1c68]432 cost = Cost::unsafe;
[a32b204]433 } // if
[cb43451]434 // assignResult == 0 means Cost::Infinity
[a32b204]435 } // if
[98278b3a]436 // case case for zero_t because it should not be possible to convert pointers to zero_t.
[a32b204]437 } // if
438 }
439
[bd0b6b62]440 void ConversionCost::postvisit( ArrayType * ) {}
[2463d0e]441
[bd0b6b62]442 void ConversionCost::postvisit( ReferenceType * refType ) {
[2463d0e]443 // Note: dest can never be a reference, since it would have been caught in an earlier check
444 assert( ! dynamic_cast< ReferenceType * >( dest ) );
445 // convert reference to rvalue: cv T1 & => T2
446 // recursively compute conversion cost from T1 to T2.
447 // cv can be safely dropped because of 'implicit dereference' behavior.
[721cd19f]448 cost = costFunc( refType->base, dest, indexer, env );
[150ec33]449 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
[cb43451]450 cost.incReference(); // prefer exact qualifiers
[150ec33]451 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
[cb43451]452 cost.incSafe(); // then gaining qualifiers
453 } else {
454 cost.incUnsafe(); // lose qualifiers as last resort
455 }
[5ccb10d]456 PRINT( std::cerr << refType << " ==> " << dest << " " << cost << std::endl; )
[2463d0e]457 }
458
[bd0b6b62]459 void ConversionCost::postvisit( FunctionType * ) {}
[a32b204]460
[bd0b6b62]461 void ConversionCost::postvisit( StructInstType * inst ) {
[a32b204]462 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
[150ec33]463 if ( inst->name == destAsInst->name ) {
[a32b204]464 cost = Cost::zero;
465 } // if
466 } // if
467 }
468
[bd0b6b62]469 void ConversionCost::postvisit( UnionInstType * inst ) {
[150ec33]470 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
471 if ( inst->name == destAsInst->name ) {
[a32b204]472 cost = Cost::zero;
473 } // if
474 } // if
475 }
476
[bd0b6b62]477 void ConversionCost::postvisit( EnumInstType * ) {
[a32b204]478 static Type::Qualifiers q;
479 static BasicType integer( q, BasicType::SignedInt );
[721cd19f]480 cost = costFunc( &integer, dest, indexer, env ); // safe if dest >= int
[89be1c68]481 if ( cost < Cost::unsafe ) {
[a32b204]482 cost.incSafe();
483 } // if
484 }
485
[bd0b6b62]486 void ConversionCost::postvisit( TraitInstType * ) {}
[a32b204]487
[bd0b6b62]488 void ConversionCost::postvisit( TypeInstType *inst ) {
[00ac42e]489 if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
490 cost = costFunc( eqvClass->type, dest, indexer, env );
[a32b204]491 } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
[eb0aedb]492 if ( inst->name == destAsInst->name ) {
[a32b204]493 cost = Cost::zero;
494 }
[00ac42e]495 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
[a32b204]496 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
497 // all typedefs should be gone by this point
498 assert( type );
[eb0aedb]499 if ( type->base ) {
[721cd19f]500 cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
[a32b204]501 } // if
502 } // if
503 }
504
[bd0b6b62]505 void ConversionCost::postvisit( TupleType * tupleType ) {
[89be1c68]506 Cost c = Cost::zero;
[b0837e4]507 if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
[eb0aedb]508 std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
509 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
510 while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
[721cd19f]511 Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
[a32b204]512 if ( newCost == Cost::infinity ) {
513 return;
514 } // if
515 c += newCost;
516 } // while
[eb0aedb]517 if ( destIt != destAsTuple->types.end() ) {
[a32b204]518 cost = Cost::infinity;
519 } else {
520 cost = c;
521 } // if
522 } // if
523 }
[44b7088]524
[bd0b6b62]525 void ConversionCost::postvisit( VarArgsType * ) {
[90c3b1c]526 if ( dynamic_cast< VarArgsType* >( dest ) ) {
[44b7088]527 cost = Cost::zero;
528 }
529 }
[89e6ffc]530
[bd0b6b62]531 void ConversionCost::postvisit( ZeroType * ) {
[b0837e4]532 if ( dynamic_cast< ZeroType * >( dest ) ) {
[89e6ffc]533 cost = Cost::zero;
534 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
535 // copied from visit(BasicType*) for signed int, but +1 for safe conversions
536 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
537 if ( tableResult == -1 ) {
[89be1c68]538 cost = Cost::unsafe;
[89e6ffc]539 } else {
[89be1c68]540 cost = Cost::zero;
541 cost.incSafe( tableResult + 1 );
[cdcddfe1]542 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
543 } // if
[89e6ffc]544 } else if ( dynamic_cast< PointerType* >( dest ) ) {
[89be1c68]545 cost = Cost::safe;
[cdcddfe1]546 } // if
[89e6ffc]547 }
548
[bd0b6b62]549 void ConversionCost::postvisit( OneType * ) {
[b0837e4]550 if ( dynamic_cast< OneType * >( dest ) ) {
[89e6ffc]551 cost = Cost::zero;
552 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
553 // copied from visit(BasicType*) for signed int, but +1 for safe conversions
554 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
555 if ( tableResult == -1 ) {
[89be1c68]556 cost = Cost::unsafe;
[89e6ffc]557 } else {
[89be1c68]558 cost = Cost::zero;
559 cost.incSafe( tableResult + 1 );
[cdcddfe1]560 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
561 } // if
562 } // if
[89e6ffc]563 }
[51b73452]564} // namespace ResolvExpr
[a32b204]565
566// Local Variables: //
567// tab-width: 4 //
568// mode: c++ //
569// compile-command: "make install" //
570// End: //
Note: See TracBrowser for help on using the repository browser.