source: src/ResolvExpr/ConversionCost.cc@ aba20d2

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since aba20d2 was 1c9568f0, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

choose integral zero over nullptr for any integral context

  • Property mode set to 100644
File size: 31.1 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 : Mon May 6 14:18:22 2019
13// Update Count : 25
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#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
41
42#if 0
43#define PRINT(x) x
44#else
45#define PRINT(x)
46#endif
47
48 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
49 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
50 PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
51 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
52 if ( eqvClass->type ) {
53 return conversionCost( src, eqvClass->type, indexer, env );
54 } else {
55 return Cost::infinity;
56 }
57 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
58 PRINT( std::cerr << " found" << std::endl; )
59 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
60 // all typedefs should be gone by this point
61 assert( type );
62 if ( type->base ) {
63 return conversionCost( src, type->base, indexer, env ) + Cost::safe;
64 } // if
65 } // if
66 PRINT( std::cerr << " not found" << std::endl; )
67 } // if
68 PRINT(
69 std::cerr << "src is ";
70 src->print( std::cerr );
71 std::cerr << std::endl << "dest is ";
72 dest->print( std::cerr );
73 std::cerr << std::endl << "env is" << std::endl;
74 env.print( std::cerr, 8 );
75 )
76 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
77 PRINT( std::cerr << "compatible!" << std::endl; )
78 return Cost::zero;
79 } else if ( dynamic_cast< VoidType* >( dest ) ) {
80 return Cost::safe;
81 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
82 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
83 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
84 return ptrsAssignable( t1, t2, env );
85 });
86 } else {
87 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
88 src->accept( converter );
89 if ( converter.pass.get_cost() == Cost::infinity ) {
90 return Cost::infinity;
91 } else {
92 return converter.pass.get_cost() + Cost::zero;
93 } // if
94 } // if
95 }
96
97 Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
98 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
99 if ( diff > 0 ) {
100 // TODO: document this
101 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
102 cost.incReference();
103 return cost;
104 } else if ( diff < -1 ) {
105 // TODO: document this
106 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
107 cost.incReference();
108 return cost;
109 } else if ( diff == 0 ) {
110 ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
111 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
112 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
113 PRINT( std::cerr << "converting between references" << std::endl; )
114 Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
115 Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
116 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
117 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
118 if ( tq1 == tq2 ) {
119 // types are the same
120 return Cost::zero;
121 } else {
122 // types are the same, except otherPointer has more qualifiers
123 return Cost::safe;
124 }
125 } else { // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
126 int assignResult = func( srcAsRef->base, destAsRef->base, indexer, env );
127 PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
128 if ( assignResult > 0 ) {
129 return Cost::safe;
130 } else if ( assignResult < 0 ) {
131 return Cost::unsafe;
132 } // if
133 } // if
134 } else {
135 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
136 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
137 src->accept( converter );
138 return converter.pass.get_cost();
139 } // if
140 } else {
141 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
142 assert( diff == -1 && destAsRef );
143 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
144 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
145 PRINT( std::cerr << "converting compatible base type" << std::endl; )
146 if ( src->get_lvalue() ) {
147 PRINT(
148 std::cerr << "lvalue to reference conversion" << std::endl;
149 std::cerr << src << " => " << destAsRef << std::endl;
150 )
151 // lvalue-to-reference conversion: cv lvalue T => cv T &
152 if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
153 return Cost::reference; // cost needs to be non-zero to add cast
154 } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
155 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
156 } else {
157 return Cost::unsafe;
158 } // if
159 } else if ( destAsRef->base->get_const() ) {
160 PRINT( std::cerr << "rvalue to const ref conversion" << std::endl; )
161 // rvalue-to-const-reference conversion: T => const T &
162 return Cost::safe;
163 } else {
164 PRINT( std::cerr << "rvalue to non-const reference conversion" << std::endl; )
165 // rvalue-to-reference conversion: T => T &
166 return Cost::unsafe;
167 } // if
168 } // if
169 PRINT( std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl; )
170 }
171 return Cost::infinity;
172 }
173
174 Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
175 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
176 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
177 PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
178 return cost;
179 }
180
181 ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
182 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
183 }
184
185 // GENERATED START, DO NOT EDIT
186 // GENERATED BY BasicTypes-gen.cc
187 /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
188 _Bool
189 char signed char unsigned char
190 signed short int unsigned short int
191 signed int unsigned int
192 signed long int unsigned long int
193 signed long long int unsigned long long int
194 __int128 unsigned __int128
195 _Float16 _Float16 _Complex
196 _Float32 _Float32 _Complex
197 float float _Complex
198 _Float32x _Float32x _Complex
199 _Float64 _Float64 _Complex
200 double double _Complex
201 _Float64x _Float64x _Complex
202 __float80
203 _Float128 _Float128 _Complex
204 __float128
205 long double long double _Complex
206 _Float128x _Float128x _Complex
207 */
208 // GENERATED END
209
210 // GENERATED START, DO NOT EDIT
211 // GENERATED BY BasicTypes-gen.cc
212 static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
213 /* 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 */
214 /* 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, },
215 /* 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, },
216 /* 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, },
217 /* 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, },
218 /* 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, },
219 /* 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, },
220 /* 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, },
221 /* 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, },
222 /* 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, },
223 /* 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, },
224 /* 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, },
225 /* 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, },
226 /* 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, },
227 /* 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, },
228 /* _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, },
229 /* _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, },
230 /* _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, },
231 /* _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, },
232 /* 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, },
233 /* 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, },
234 /* _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, },
235 /* _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, },
236 /* 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, },
237 /* _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, },
238 /* 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, },
239 /* 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, },
240 /* 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, },
241 /* _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, },
242 /* 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, },
243 /* _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, },
244 /* _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, },
245 /* 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, },
246 /* 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, },
247 /* 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, },
248 /* _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, },
249 /*_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, },
250 }; // costMatrix
251 static const int maxIntCost = 15;
252 // GENERATED END
253 static_assert(
254 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
255 "Missing row in the cost matrix"
256 );
257
258 // GENERATED START, DO NOT EDIT
259 // GENERATED BY BasicTypes-gen.cc
260 static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
261 /* 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 */
262 /* 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, },
263 /* 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, },
264 /* 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, },
265 /* 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, },
266 /* 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, },
267 /* 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, },
268 /* 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, },
269 /* 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, },
270 /* 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, },
271 /* 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, },
272 /* 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, },
273 /* 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, },
274 /* 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, },
275 /* 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, },
276 /* _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, },
277 /* _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, },
278 /* _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, },
279 /* _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, },
280 /* 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, },
281 /* 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, },
282 /* _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, },
283 /* _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, },
284 /* 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, },
285 /* _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, },
286 /* 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, },
287 /* 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, },
288 /* 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, },
289 /* _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, },
290 /* 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, },
291 /* _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, },
292 /* _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, },
293 /* 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, },
294 /* 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, },
295 /* 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, },
296 /* _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, },
297 /*_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, },
298 }; // signMatrix
299 // GENERATED END
300 static_assert(
301 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
302 "Missing row in the sign matrix"
303 );
304
305 void ConversionCost::postvisit( VoidType * ) {
306 cost = Cost::infinity;
307 }
308
309 void ConversionCost::postvisit(BasicType *basicType) {
310 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
311 int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
312 if ( tableResult == -1 ) {
313 cost = Cost::unsafe;
314 } else {
315 cost = Cost::zero;
316 cost.incSafe( tableResult );
317 cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
318 } // if
319 } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
320 // xxx - not positive this is correct, but appears to allow casting int => enum
321 cost = Cost::unsafe;
322 } // if
323 // no cases for zero_t/one_t because it should not be possible to convert int, etc. to zero_t/one_t.
324 }
325
326 void ConversionCost::postvisit( PointerType * pointerType ) {
327 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
328 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
329 Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
330 Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
331 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
332 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
333 if ( tq1 == tq2 ) {
334 // types are the same
335 cost = Cost::zero;
336 } else {
337 // types are the same, except otherPointer has more qualifiers
338 cost = Cost::safe;
339 } // if
340 } else {
341 int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
342 PRINT( std::cerr << " :: " << assignResult << std::endl; )
343 if ( assignResult > 0 && tq1 <= tq2 ) {
344 // 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?
345 if ( tq1 == tq2 ) {
346 cost = Cost::safe;
347 } else if ( tq1 < tq2 ) {
348 cost = Cost::safe+Cost::safe;
349 }
350 } else if ( assignResult < 0 ) {
351 cost = Cost::unsafe;
352 } // if
353 // assignResult == 0 means Cost::Infinity
354 } // if
355 // case case for zero_t because it should not be possible to convert pointers to zero_t.
356 } // if
357 }
358
359 void ConversionCost::postvisit( ArrayType * ) {}
360
361 void ConversionCost::postvisit( ReferenceType * refType ) {
362 // Note: dest can never be a reference, since it would have been caught in an earlier check
363 assert( ! dynamic_cast< ReferenceType * >( dest ) );
364 // convert reference to rvalue: cv T1 & => T2
365 // recursively compute conversion cost from T1 to T2.
366 // cv can be safely dropped because of 'implicit dereference' behavior.
367 cost = costFunc( refType->base, dest, indexer, env );
368 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
369 cost.incReference(); // prefer exact qualifiers
370 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
371 cost.incSafe(); // then gaining qualifiers
372 } else {
373 cost.incUnsafe(); // lose qualifiers as last resort
374 }
375 PRINT( std::cerr << refType << " ==> " << dest << " " << cost << std::endl; )
376 }
377
378 void ConversionCost::postvisit( FunctionType * ) {}
379
380 void ConversionCost::postvisit( StructInstType * inst ) {
381 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
382 if ( inst->name == destAsInst->name ) {
383 cost = Cost::zero;
384 } // if
385 } // if
386 }
387
388 void ConversionCost::postvisit( UnionInstType * inst ) {
389 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
390 if ( inst->name == destAsInst->name ) {
391 cost = Cost::zero;
392 } // if
393 } // if
394 }
395
396 void ConversionCost::postvisit( EnumInstType * ) {
397 static Type::Qualifiers q;
398 static BasicType integer( q, BasicType::SignedInt );
399 cost = costFunc( &integer, dest, indexer, env ); // safe if dest >= int
400 if ( cost < Cost::unsafe ) {
401 cost.incSafe();
402 } // if
403 }
404
405 void ConversionCost::postvisit( TraitInstType * ) {}
406
407 void ConversionCost::postvisit( TypeInstType *inst ) {
408 if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
409 cost = costFunc( eqvClass->type, dest, indexer, env );
410 } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
411 if ( inst->name == destAsInst->name ) {
412 cost = Cost::zero;
413 }
414 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
415 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
416 // all typedefs should be gone by this point
417 assert( type );
418 if ( type->base ) {
419 cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
420 } // if
421 } // if
422 }
423
424 void ConversionCost::postvisit( TupleType * tupleType ) {
425 Cost c = Cost::zero;
426 if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
427 std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
428 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
429 while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
430 Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
431 if ( newCost == Cost::infinity ) {
432 return;
433 } // if
434 c += newCost;
435 } // while
436 if ( destIt != destAsTuple->types.end() ) {
437 cost = Cost::infinity;
438 } else {
439 cost = c;
440 } // if
441 } // if
442 }
443
444 void ConversionCost::postvisit( VarArgsType * ) {
445 if ( dynamic_cast< VarArgsType* >( dest ) ) {
446 cost = Cost::zero;
447 }
448 }
449
450 void ConversionCost::postvisit( ZeroType * ) {
451 if ( dynamic_cast< ZeroType * >( dest ) ) {
452 cost = Cost::zero;
453 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
454 // copied from visit(BasicType*) for signed int, but +1 for safe conversions
455 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
456 if ( tableResult == -1 ) {
457 cost = Cost::unsafe;
458 } else {
459 cost = Cost::zero;
460 cost.incSafe( tableResult + 1 );
461 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
462 } // if
463 } else if ( dynamic_cast< PointerType* >( dest ) ) {
464 cost = Cost::zero;
465 cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation
466 } // if
467 }
468
469 void ConversionCost::postvisit( OneType * ) {
470 if ( dynamic_cast< OneType * >( dest ) ) {
471 cost = Cost::zero;
472 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
473 // copied from visit(BasicType*) for signed int, but +1 for safe conversions
474 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
475 if ( tableResult == -1 ) {
476 cost = Cost::unsafe;
477 } else {
478 cost = Cost::zero;
479 cost.incSafe( tableResult + 1 );
480 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
481 } // if
482 } // if
483 }
484} // namespace ResolvExpr
485
486// Local Variables: //
487// tab-width: 4 //
488// mode: c++ //
489// compile-command: "make install" //
490// End: //
Note: See TracBrowser for help on using the repository browser.