source: src/ResolvExpr/ConversionCost.cc@ b8524ca

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 b8524ca was 9d5089e, checked in by Aaron Moss <a3moss@…>, 6 years ago

Port CandidateFinder::makeFunctionCandidates() and deps

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