source: src/ResolvExpr/ConversionCost.cc@ eb28d7e

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

pack 7 resolver Costs into single word

  • Property mode set to 100644
File size: 30.9 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 : Fri Apr 26 16:33:04 2019
13// Update Count : 24
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 // GENERATED END
252 static_assert(
253 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
254 "Missing row in the cost matrix"
255 );
256
257 // GENERATED START, DO NOT EDIT
258 // GENERATED BY BasicTypes-gen.cc
259 static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
260 /* 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 */
261 /* 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, },
262 /* 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, },
263 /* 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, },
264 /* 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, },
265 /* 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, },
266 /* 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, },
267 /* 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, },
268 /* 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, },
269 /* 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, },
270 /* 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, },
271 /* 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, },
272 /* 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, },
273 /* 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, },
274 /* 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, },
275 /* _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, },
276 /* _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, },
277 /* _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, },
278 /* _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, },
279 /* 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, },
280 /* 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, },
281 /* _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, },
282 /* _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, },
283 /* 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, },
284 /* _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, },
285 /* 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, },
286 /* 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, },
287 /* 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, },
288 /* _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, },
289 /* 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, },
290 /* _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, },
291 /* _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, },
292 /* 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, },
293 /* 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, },
294 /* 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, },
295 /* _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, },
296 /*_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, },
297 }; // signMatrix
298 // GENERATED END
299 static_assert(
300 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
301 "Missing row in the sign matrix"
302 );
303
304 void ConversionCost::postvisit( VoidType * ) {
305 cost = Cost::infinity;
306 }
307
308 void ConversionCost::postvisit(BasicType *basicType) {
309 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
310 int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
311 if ( tableResult == -1 ) {
312 cost = Cost::unsafe;
313 } else {
314 cost = Cost::zero;
315 cost.incSafe( tableResult );
316 cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
317 } // if
318 } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
319 // xxx - not positive this is correct, but appears to allow casting int => enum
320 cost = Cost::unsafe;
321 } // if
322 // no cases for zero_t/one_t because it should not be possible to convert int, etc. to zero_t/one_t.
323 }
324
325 void ConversionCost::postvisit( PointerType * pointerType ) {
326 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
327 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
328 Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
329 Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
330 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
331 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
332 if ( tq1 == tq2 ) {
333 // types are the same
334 cost = Cost::zero;
335 } else {
336 // types are the same, except otherPointer has more qualifiers
337 cost = Cost::safe;
338 } // if
339 } else {
340 int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
341 PRINT( std::cerr << " :: " << assignResult << std::endl; )
342 if ( assignResult > 0 && tq1 <= tq2 ) {
343 // 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?
344 if ( tq1 == tq2 ) {
345 cost = Cost::safe;
346 } else if ( tq1 < tq2 ) {
347 cost = Cost::safe+Cost::safe;
348 }
349 } else if ( assignResult < 0 ) {
350 cost = Cost::unsafe;
351 } // if
352 // assignResult == 0 means Cost::Infinity
353 } // if
354 // case case for zero_t because it should not be possible to convert pointers to zero_t.
355 } // if
356 }
357
358 void ConversionCost::postvisit( ArrayType * ) {}
359
360 void ConversionCost::postvisit( ReferenceType * refType ) {
361 // Note: dest can never be a reference, since it would have been caught in an earlier check
362 assert( ! dynamic_cast< ReferenceType * >( dest ) );
363 // convert reference to rvalue: cv T1 & => T2
364 // recursively compute conversion cost from T1 to T2.
365 // cv can be safely dropped because of 'implicit dereference' behavior.
366 cost = costFunc( refType->base, dest, indexer, env );
367 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
368 cost.incReference(); // prefer exact qualifiers
369 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
370 cost.incSafe(); // then gaining qualifiers
371 } else {
372 cost.incUnsafe(); // lose qualifiers as last resort
373 }
374 PRINT( std::cerr << refType << " ==> " << dest << " " << cost << std::endl; )
375 }
376
377 void ConversionCost::postvisit( FunctionType * ) {}
378
379 void ConversionCost::postvisit( StructInstType * inst ) {
380 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
381 if ( inst->name == destAsInst->name ) {
382 cost = Cost::zero;
383 } // if
384 } // if
385 }
386
387 void ConversionCost::postvisit( UnionInstType * inst ) {
388 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
389 if ( inst->name == destAsInst->name ) {
390 cost = Cost::zero;
391 } // if
392 } // if
393 }
394
395 void ConversionCost::postvisit( EnumInstType * ) {
396 static Type::Qualifiers q;
397 static BasicType integer( q, BasicType::SignedInt );
398 cost = costFunc( &integer, dest, indexer, env ); // safe if dest >= int
399 if ( cost < Cost::unsafe ) {
400 cost.incSafe();
401 } // if
402 }
403
404 void ConversionCost::postvisit( TraitInstType * ) {}
405
406 void ConversionCost::postvisit( TypeInstType *inst ) {
407 if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
408 cost = costFunc( eqvClass->type, dest, indexer, env );
409 } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
410 if ( inst->name == destAsInst->name ) {
411 cost = Cost::zero;
412 }
413 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
414 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
415 // all typedefs should be gone by this point
416 assert( type );
417 if ( type->base ) {
418 cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
419 } // if
420 } // if
421 }
422
423 void ConversionCost::postvisit( TupleType * tupleType ) {
424 Cost c = Cost::zero;
425 if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
426 std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
427 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
428 while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
429 Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
430 if ( newCost == Cost::infinity ) {
431 return;
432 } // if
433 c += newCost;
434 } // while
435 if ( destIt != destAsTuple->types.end() ) {
436 cost = Cost::infinity;
437 } else {
438 cost = c;
439 } // if
440 } // if
441 }
442
443 void ConversionCost::postvisit( VarArgsType * ) {
444 if ( dynamic_cast< VarArgsType* >( dest ) ) {
445 cost = Cost::zero;
446 }
447 }
448
449 void ConversionCost::postvisit( ZeroType * ) {
450 if ( dynamic_cast< ZeroType * >( dest ) ) {
451 cost = Cost::zero;
452 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
453 // copied from visit(BasicType*) for signed int, but +1 for safe conversions
454 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
455 if ( tableResult == -1 ) {
456 cost = Cost::unsafe;
457 } else {
458 cost = Cost::zero;
459 cost.incSafe( tableResult + 1 );
460 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
461 } // if
462 } else if ( dynamic_cast< PointerType* >( dest ) ) {
463 cost = Cost::safe;
464 } // if
465 }
466
467 void ConversionCost::postvisit( OneType * ) {
468 if ( dynamic_cast< OneType * >( dest ) ) {
469 cost = Cost::zero;
470 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
471 // copied from visit(BasicType*) for signed int, but +1 for safe conversions
472 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
473 if ( tableResult == -1 ) {
474 cost = Cost::unsafe;
475 } else {
476 cost = Cost::zero;
477 cost.incSafe( tableResult + 1 );
478 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
479 } // if
480 } // if
481 }
482} // namespace ResolvExpr
483
484// Local Variables: //
485// tab-width: 4 //
486// mode: c++ //
487// compile-command: "make install" //
488// End: //
Note: See TracBrowser for help on using the repository browser.