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
Line 
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//
7// ConversionCost.cc --
8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 07:06:19 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Feb 13 23:04:51 2019
13// Update Count : 22
14//
15
16#include "ConversionCost.h"
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
28
29namespace ResolvExpr {
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 };
39
40#if 0
41#define PRINT(x) x
42#else
43#define PRINT(x)
44#endif
45 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
46 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
47 PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
48 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
49 if ( eqvClass->type ) {
50 return conversionCost( src, eqvClass->type, indexer, env );
51 } else {
52 return Cost::infinity;
53 }
54 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
55 PRINT( std::cerr << " found" << std::endl; )
56 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
57 // all typedefs should be gone by this point
58 assert( type );
59 if ( type->base ) {
60 return conversionCost( src, type->base, indexer, env ) + Cost::safe;
61 } // if
62 } // if
63 PRINT( std::cerr << " not found" << std::endl; )
64 } // if
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 )
73 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
74 PRINT( std::cerr << "compatible!" << std::endl; )
75 return Cost::zero;
76 } else if ( dynamic_cast< VoidType* >( dest ) ) {
77 return Cost::safe;
78 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
79 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
80 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
81 return ptrsAssignable( t1, t2, env );
82 });
83 } else {
84 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
85 src->accept( converter );
86 if ( converter.pass.get_cost() == Cost::infinity ) {
87 return Cost::infinity;
88 } else {
89 return converter.pass.get_cost() + Cost::zero;
90 } // if
91 } // if
92 }
93
94 Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
95 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
96 if ( diff > 0 ) {
97 // TODO: document this
98 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
99 cost.incReference();
100 return cost;
101 } else if ( diff < -1 ) {
102 // TODO: document this
103 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
104 cost.incReference();
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
110 PRINT( std::cerr << "converting between references" << std::endl; )
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 ) ) {
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 }
122 } else { // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
123 int assignResult = func( srcAsRef->base, destAsRef->base, indexer, env );
124 PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
125 if ( assignResult > 0 ) {
126 return Cost::safe;
127 } else if ( assignResult < 0 ) {
128 return Cost::unsafe;
129 } // if
130 } // if
131 } else {
132 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
133 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
134 src->accept( converter );
135 return converter.pass.get_cost();
136 } // if
137 } else {
138 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
139 assert( diff == -1 && destAsRef );
140 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
141 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
142 PRINT( std::cerr << "converting compatible base type" << std::endl; )
143 if ( src->get_lvalue() ) {
144 PRINT(
145 std::cerr << "lvalue to reference conversion" << std::endl;
146 std::cerr << src << " => " << destAsRef << std::endl;
147 )
148 // lvalue-to-reference conversion: cv lvalue T => cv T &
149 if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
150 return Cost::reference; // cost needs to be non-zero to add cast
151 } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
152 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
153 } else {
154 return Cost::unsafe;
155 } // if
156 } else if ( destAsRef->base->get_const() ) {
157 PRINT( std::cerr << "rvalue to const ref conversion" << std::endl; )
158 // rvalue-to-const-reference conversion: T => const T &
159 return Cost::safe;
160 } else {
161 PRINT( std::cerr << "rvalue to non-const reference conversion" << std::endl; )
162 // rvalue-to-reference conversion: T => T &
163 return Cost::unsafe;
164 } // if
165 } // if
166 PRINT( std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl; )
167 }
168 return Cost::infinity;
169 }
170
171 Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
172 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
173 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
174 PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
175 return cost;
176 }
177
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 ) {
180 }
181#if 0
182/*
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
231*/
232
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},
247
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},
257
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},
263 };
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 );
268#endif
269
270 // GENERATED START, DO NOT EDIT
271 /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
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
291 */
292 // GENERATED END
293
294 // GENERATED START, DO NOT EDIT
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,
333 }; // costMatrix
334 // GENERATED END
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
340 // GENERATED START, DO NOT EDIT
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,
379 }; // signMatrix
380 // GENERATED END
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 );
385
386 void ConversionCost::postvisit( VoidType * ) {
387 cost = Cost::infinity;
388 }
389
390 void ConversionCost::postvisit(BasicType *basicType) {
391 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
392 int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
393 if ( tableResult == -1 ) {
394 cost = Cost::unsafe;
395 } else {
396 cost = Cost::zero;
397 cost.incSafe( tableResult );
398 cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
399 } // if
400 } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
401 // xxx - not positive this is correct, but appears to allow casting int => enum
402 cost = Cost::unsafe;
403 } // if
404 // no cases for zero_t/one_t because it should not be possible to convert int, etc. to zero_t/one_t.
405 }
406
407 void ConversionCost::postvisit( PointerType * pointerType ) {
408 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
409 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
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 ) ) {
413 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
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;
420 } // if
421 } else {
422 int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
423 PRINT( std::cerr << " :: " << assignResult << std::endl; )
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 }
431 } else if ( assignResult < 0 ) {
432 cost = Cost::unsafe;
433 } // if
434 // assignResult == 0 means Cost::Infinity
435 } // if
436 // case case for zero_t because it should not be possible to convert pointers to zero_t.
437 } // if
438 }
439
440 void ConversionCost::postvisit( ArrayType * ) {}
441
442 void ConversionCost::postvisit( ReferenceType * refType ) {
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.
448 cost = costFunc( refType->base, dest, indexer, env );
449 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
450 cost.incReference(); // prefer exact qualifiers
451 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
452 cost.incSafe(); // then gaining qualifiers
453 } else {
454 cost.incUnsafe(); // lose qualifiers as last resort
455 }
456 PRINT( std::cerr << refType << " ==> " << dest << " " << cost << std::endl; )
457 }
458
459 void ConversionCost::postvisit( FunctionType * ) {}
460
461 void ConversionCost::postvisit( StructInstType * inst ) {
462 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
463 if ( inst->name == destAsInst->name ) {
464 cost = Cost::zero;
465 } // if
466 } // if
467 }
468
469 void ConversionCost::postvisit( UnionInstType * inst ) {
470 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
471 if ( inst->name == destAsInst->name ) {
472 cost = Cost::zero;
473 } // if
474 } // if
475 }
476
477 void ConversionCost::postvisit( EnumInstType * ) {
478 static Type::Qualifiers q;
479 static BasicType integer( q, BasicType::SignedInt );
480 cost = costFunc( &integer, dest, indexer, env ); // safe if dest >= int
481 if ( cost < Cost::unsafe ) {
482 cost.incSafe();
483 } // if
484 }
485
486 void ConversionCost::postvisit( TraitInstType * ) {}
487
488 void ConversionCost::postvisit( TypeInstType *inst ) {
489 if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
490 cost = costFunc( eqvClass->type, dest, indexer, env );
491 } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
492 if ( inst->name == destAsInst->name ) {
493 cost = Cost::zero;
494 }
495 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
496 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
497 // all typedefs should be gone by this point
498 assert( type );
499 if ( type->base ) {
500 cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
501 } // if
502 } // if
503 }
504
505 void ConversionCost::postvisit( TupleType * tupleType ) {
506 Cost c = Cost::zero;
507 if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
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() ) {
511 Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
512 if ( newCost == Cost::infinity ) {
513 return;
514 } // if
515 c += newCost;
516 } // while
517 if ( destIt != destAsTuple->types.end() ) {
518 cost = Cost::infinity;
519 } else {
520 cost = c;
521 } // if
522 } // if
523 }
524
525 void ConversionCost::postvisit( VarArgsType * ) {
526 if ( dynamic_cast< VarArgsType* >( dest ) ) {
527 cost = Cost::zero;
528 }
529 }
530
531 void ConversionCost::postvisit( ZeroType * ) {
532 if ( dynamic_cast< ZeroType * >( dest ) ) {
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 ) {
538 cost = Cost::unsafe;
539 } else {
540 cost = Cost::zero;
541 cost.incSafe( tableResult + 1 );
542 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
543 } // if
544 } else if ( dynamic_cast< PointerType* >( dest ) ) {
545 cost = Cost::safe;
546 } // if
547 }
548
549 void ConversionCost::postvisit( OneType * ) {
550 if ( dynamic_cast< OneType * >( dest ) ) {
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 ) {
556 cost = Cost::unsafe;
557 } else {
558 cost = Cost::zero;
559 cost.incSafe( tableResult + 1 );
560 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
561 } // if
562 } // if
563 }
564} // namespace ResolvExpr
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.