source: src/ResolvExpr/ConversionCost.cc@ 47bfefd

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 47bfefd was 6fd1955, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

update GENERATED BY file name

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