source: src/ResolvExpr/CommonType.cc@ 994030ce

Last change on this file since 994030ce was 918e4165, checked in by Andrew Beach <ajbeach@…>, 2 years ago

Removed some warnings.

  • Property mode set to 100644
File size: 65.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// CommonType.cc --
8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 06:59:27 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu Feb 14 17:10:10 2019
13// Update Count : 24
14//
15
16#include "CommonType.hpp"
17
18#include <cassert> // for strict_dynamic_cast
19#include <map> // for _Rb_tree_const_iterator
20#include <utility> // for pair
21
22#include "AST/Decl.hpp"
23#include "AST/Pass.hpp"
24#include "AST/Type.hpp"
25#include "Common/PassVisitor.h"
26#include "ResolvExpr/TypeEnvironment.h" // for OpenVarSet, AssertionSet
27#include "SymTab/Indexer.h" // for Indexer
28#include "SynTree/Declaration.h" // for TypeDecl, NamedTypeDecl (ptr...
29#include "SynTree/Type.h" // for BasicType, BasicType::Kind::...
30#include "SynTree/Visitor.h" // for Visitor
31#include "Unify.h" // for unifyExact, WidenMode
32#include "typeops.h" // for isFtype
33#include "Tuples/Tuples.h"
34
35// #define DEBUG
36#ifdef DEBUG
37#define PRINT(x) x
38#else
39#define PRINT(x)
40#endif
41
42namespace ResolvExpr {
43 struct CommonType_old : public WithShortCircuiting {
44 CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
45 Type * get_result() const { return result; }
46
47 void previsit( BaseSyntaxNode * ) { visit_children = false; }
48
49 void postvisit( VoidType * voidType );
50 void postvisit( BasicType * basicType );
51 void postvisit( PointerType * pointerType );
52 void postvisit( ArrayType * arrayType );
53 void postvisit( ReferenceType * refType );
54 void postvisit( FunctionType * functionType );
55 void postvisit( StructInstType * aggregateUseType );
56 void postvisit( UnionInstType * aggregateUseType );
57 void postvisit( EnumInstType * aggregateUseType );
58 void postvisit( TraitInstType * aggregateUseType );
59 void postvisit( TypeInstType * aggregateUseType );
60 void postvisit( TupleType * tupleType );
61 void postvisit( VarArgsType * varArgsType );
62 void postvisit( ZeroType * zeroType );
63 void postvisit( OneType * oneType );
64
65 private:
66 template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer );
67 template< typename RefType > void handleRefType( RefType * inst, Type * other );
68
69 Type * result;
70 Type * type2; // inherited
71 bool widenFirst, widenSecond;
72 const SymTab::Indexer &indexer;
73 TypeEnvironment &env;
74 const OpenVarSet &openVars;
75 };
76
77 Type * handleReference( Type * t1, Type * t2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment & env, const OpenVarSet &openVars ) {
78 Type * common = nullptr;
79 AssertionSet have, need;
80 OpenVarSet newOpen( openVars );
81 // need unify to bind type variables
82 if ( unify( t1, t2, env, have, need, newOpen, indexer, common ) ) {
83 PRINT(
84 std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
85 )
86 if ( (widenFirst || t2->tq <= t1->tq) && (widenSecond || t1->tq <= t2->tq) ) {
87 PRINT(
88 std::cerr << "widen okay" << std::endl;
89 )
90 common->tq |= t1->tq;
91 common->tq |= t2->tq;
92 return common;
93 }
94 }
95 PRINT(
96 std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
97 )
98 return nullptr;
99 }
100
101 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
102 PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
103
104 int depth1 = type1->referenceDepth();
105 int depth2 = type2->referenceDepth();
106 if ( depth1 > 0 || depth2 > 0 ) {
107 int diff = depth1-depth2;
108 // TODO: should it be possible for commonType to generate complicated conversions? I would argue no, only conversions that involve types of the same reference level or a difference of 1 should be allowed.
109 // if ( diff > 1 || diff < -1 ) return nullptr;
110
111 // special case where one type has a reference depth of 1 larger than the other
112 if ( diff > 0 || diff < 0 ) {
113 PRINT(
114 std::cerr << "reference depth diff: " << diff << std::endl;
115 )
116 Type * result = nullptr;
117 ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 );
118 ReferenceType * ref2 = dynamic_cast< ReferenceType * >( type2 );
119 if ( diff > 0 ) {
120 // deeper on the left
121 assert( ref1 );
122 result = handleReference( ref1->base, type2, widenFirst, widenSecond, indexer, env, openVars );
123 } else {
124 // deeper on the right
125 assert( ref2 );
126 result = handleReference( type1, ref2->base, widenFirst, widenSecond, indexer, env, openVars );
127 }
128 if ( result && ref1 ) {
129 // formal is reference, so result should be reference
130 PRINT(
131 std::cerr << "formal is reference; result should be reference" << std::endl;
132 )
133 result = new ReferenceType( ref1->tq, result );
134 }
135 PRINT(
136 std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl;
137 )
138 return result;
139 }
140 // otherwise, both are reference types of the same depth and this is handled by the CommonType visitor.
141 }
142
143 type1->accept( visitor );
144 Type * result = visitor.pass.get_result();
145 if ( ! result ) {
146 // this appears to be handling for opaque type declarations
147 if ( widenSecond ) {
148 if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type2 ) ) {
149 if ( const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ) ) {
150 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
151 if ( type->get_base() ) {
152 Type::Qualifiers tq1 = type1->tq, tq2 = type2->tq;
153 AssertionSet have, need;
154 OpenVarSet newOpen( openVars );
155 type1->tq = Type::Qualifiers();
156 type->get_base()->tq = tq1;
157 if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) {
158 result = type1->clone();
159 result->tq = tq1 | tq2;
160 } // if
161 type1->tq = tq1;
162 type->get_base()->tq = Type::Qualifiers();
163 } // if
164 } // if
165 } // if
166 } // if
167 } // if
168#ifdef DEBUG
169 std::cerr << "============= commonType" << std::endl << "type1 is ";
170 type1->print( std::cerr );
171 std::cerr << " type2 is ";
172 type2->print( std::cerr );
173 if ( result ) {
174 std::cerr << " common type is ";
175 result->print( std::cerr );
176 } else {
177 std::cerr << " no common type";
178 } // if
179 std::cerr << std::endl;
180#endif
181 return result;
182 }
183
184 // GENERATED START, DO NOT EDIT
185 // GENERATED BY BasicTypes-gen.cc
186 #define BT BasicType::
187 static const BasicType::Kind commonTypes[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor
188 /* B C SC UC SI SUI
189 I UI LI LUI LLI LLUI
190 IB UIB _FH _FH _F _FC
191 F FC _FX _FXC FD _FDC
192 D DC F80X _FDXC F80 _FB
193 _FLDC FB LD LDC _FBX _FLDXC
194 */
195 {
196 /* B */ BT Bool, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,
197 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
198 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
199 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
200 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
201 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
202 },
203 {
204 /* C */ BT Char, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,
205 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
206 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
207 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
208 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
209 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
210 },
211 {
212 /* SC */ BT SignedChar, BT SignedChar, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,
213 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
214 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
215 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
216 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
217 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
218 },
219 {
220 /* UC */ BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,
221 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
222 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
223 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
224 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
225 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
226 },
227 {
228 /* SI */ BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortUnsignedInt,
229 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
230 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
231 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
232 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
233 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
234 },
235 {
236 /* SUI */ BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt,
237 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
238 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
239 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
240 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
241 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
242 },
243 {
244 /* I */ BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt,
245 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
246 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
247 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
248 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
249 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
250 },
251 {
252 /* UI */ BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt,
253 BT UnsignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
254 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
255 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
256 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
257 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
258 },
259 {
260 /* LI */ BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt,
261 BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
262 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
263 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
264 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
265 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
266 },
267 {
268 /* LUI */ BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt,
269 BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
270 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
271 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
272 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
273 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
274 },
275 {
276 /* LLI */ BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt,
277 BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt,
278 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
279 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
280 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
281 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
282 },
283 {
284 /* LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
285 BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
286 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
287 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
288 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
289 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
290 },
291 {
292 /* IB */ BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128,
293 BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128,
294 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
295 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
296 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
297 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
298 },
299 {
300 /* UIB */ BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128,
301 BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128,
302 BT UnsignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
303 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
304 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
305 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
306 },
307 {
308 /* _FH */ BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16,
309 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16,
310 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex,
311 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
312 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
313 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
314 },
315 {
316 /* _FH */ BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex,
317 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex,
318 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat32Complex, BT uFloat32Complex,
319 BT FloatComplex, BT FloatComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex,
320 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex,
321 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex,
322 },
323 {
324 /* _F */ BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32,
325 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32,
326 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32Complex, BT uFloat32, BT uFloat32Complex,
327 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
328 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
329 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
330 },
331 {
332 /* _FC */ BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex,
333 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex,
334 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex,
335 BT FloatComplex, BT FloatComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex,
336 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex,
337 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex,
338 },
339 {
340 /* F */ BT Float, BT Float, BT Float, BT Float, BT Float, BT Float,
341 BT Float, BT Float, BT Float, BT Float, BT Float, BT Float,
342 BT Float, BT Float, BT Float, BT FloatComplex, BT Float, BT FloatComplex,
343 BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
344 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
345 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
346 },
347 {
348 /* FC */ BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex,
349 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex,
350 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex,
351 BT FloatComplex, BT FloatComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex,
352 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex,
353 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex,
354 },
355 {
356 /* _FX */ BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x,
357 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x,
358 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex,
359 BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex,
360 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
361 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
362 },
363 {
364 /* _FXC */ BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex,
365 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex,
366 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex,
367 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex,
368 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex,
369 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex,
370 },
371 {
372 /* FD */ BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64,
373 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64,
374 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex,
375 BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex,
376 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
377 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
378 },
379 {
380 /* _FDC */ BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex,
381 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex,
382 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex,
383 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex,
384 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex,
385 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex,
386 },
387 {
388 /* D */ BT Double, BT Double, BT Double, BT Double, BT Double, BT Double,
389 BT Double, BT Double, BT Double, BT Double, BT Double, BT Double,
390 BT Double, BT Double, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex,
391 BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex,
392 BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
393 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
394 },
395 {
396 /* DC */ BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex,
397 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex,
398 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex,
399 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex,
400 BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex,
401 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex,
402 },
403 {
404 /* F80X */ BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x,
405 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x,
406 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex,
407 BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex,
408 BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
409 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
410 },
411 {
412 /* _FDXC */ BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex,
413 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex,
414 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex,
415 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex,
416 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex,
417 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex,
418 },
419 {
420 /* F80 */ BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80,
421 BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80,
422 BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex,
423 BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex,
424 BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat128,
425 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
426 },
427 {
428 /* _FB */ BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128,
429 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128,
430 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex,
431 BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex,
432 BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128,
433 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
434 },
435 {
436 /* _FLDC */ BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex,
437 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex,
438 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex,
439 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex,
440 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex,
441 BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex,
442 },
443 {
444 /* FB */ BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128,
445 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128,
446 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex,
447 BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex,
448 BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uuFloat128,
449 BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
450 },
451 {
452 /* LD */ BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble,
453 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble,
454 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex,
455 BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex,
456 BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDouble,
457 BT LongDoubleComplex, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex,
458 },
459 {
460 /* LDC */ BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex,
461 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex,
462 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex,
463 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex,
464 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex,
465 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex,
466 },
467 {
468 /* _FBX */ BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x,
469 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x,
470 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex,
471 BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex,
472 BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128x,
473 BT uFloat128xComplex, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex,
474 },
475 {
476 /* _FLDXC */ BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex,
477 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex,
478 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex,
479 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex,
480 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex,
481 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex,
482 },
483 }; // commonTypes
484 #undef BT
485 // GENERATED END
486 static_assert(
487 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
488 "Each basic type kind should have a corresponding row in the combined type matrix"
489 );
490
491 CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
492 : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) {
493 }
494
495 void CommonType_old::postvisit( VoidType * ) {}
496
497 void CommonType_old::postvisit( BasicType * basicType ) {
498 if ( BasicType * otherBasic = dynamic_cast< BasicType * >( type2 ) ) {
499 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ];
500 if ( ( ( newType == basicType->get_kind() && basicType->tq >= otherBasic->tq ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->tq <= otherBasic->tq ) || widenSecond ) ) {
501 result = new BasicType( basicType->tq | otherBasic->tq, newType );
502 } // if
503 } else if ( dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
504 // use signed int in lieu of the enum/zero/one type
505 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ];
506 if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) {
507 result = new BasicType( basicType->tq | type2->tq, newType );
508 } // if
509 } else if ( const EnumInstType * enumInst = dynamic_cast< const EnumInstType * > ( type2 ) ) {
510 const EnumDecl* enumDecl = enumInst->baseEnum;
511 if ( const Type* baseType = enumDecl->base ) {
512 result = baseType->clone();
513 } else {
514 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ];
515 if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) {
516 result = new BasicType( basicType->tq | type2->tq, newType );
517 } // if
518 }
519 }
520 }
521
522 template< typename Pointer >
523 void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ) {
524 if ( TypeInstType * var = dynamic_cast< TypeInstType * >( otherPointer->get_base() ) ) {
525 OpenVarSet::const_iterator entry = openVars.find( var->get_name() );
526 if ( entry != openVars.end() ) {
527 AssertionSet need, have;
528 WidenMode widen( widenFirst, widenSecond );
529 if ( entry != openVars.end() && ! env.bindVar(var, voidPointer->get_base(), entry->second, need, have, openVars, widen, indexer ) ) return;
530 }
531 }
532 result = voidPointer->clone();
533 result->tq |= otherPointer->tq;
534 }
535
536 void CommonType_old::postvisit( PointerType * pointerType ) {
537 if ( PointerType * otherPointer = dynamic_cast< PointerType * >( type2 ) ) {
538 // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl;
539 if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
540 getCommonWithVoidPointer( otherPointer, pointerType );
541 } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
542 getCommonWithVoidPointer( pointerType, otherPointer );
543 } else if ( ( pointerType->get_base()->tq >= otherPointer->get_base()->tq || widenFirst )
544 && ( pointerType->get_base()->tq <= otherPointer->get_base()->tq || widenSecond ) ) {
545 // std::cerr << "middle case" << std::endl;
546 Type::Qualifiers tq1 = pointerType->get_base()->tq, tq2 = otherPointer->get_base()->tq;
547 pointerType->get_base()->tq = Type::Qualifiers();
548 otherPointer->get_base()->tq = Type::Qualifiers();
549 AssertionSet have, need;
550 OpenVarSet newOpen( openVars );
551 if ( unifyExact( pointerType->get_base(), otherPointer->get_base(), env, have, need, newOpen, indexer ) ) {
552 // std::cerr << "unifyExact success" << std::endl;
553 if ( tq1 < tq2 ) {
554 result = pointerType->clone();
555 } else {
556 result = otherPointer->clone();
557 } // if
558 strict_dynamic_cast<PointerType *>(result)->base->tq = tq1 | tq2;
559 } else {
560 /// std::cerr << "place for ptr-to-type" << std::endl;
561 } // if
562 pointerType->get_base()->tq = tq1;
563 otherPointer->get_base()->tq = tq2;
564 } // if
565 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
566 result = pointerType->clone();
567 result->tq |= type2->tq;
568 } // if
569 }
570
571 void CommonType_old::postvisit( ArrayType * ) {}
572
573 void CommonType_old::postvisit( ReferenceType * refType ) {
574 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( type2 ) ) {
575 // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl;
576 // std::cerr << ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) << (refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond) << std::endl;
577 if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
578 getCommonWithVoidPointer( otherRef, refType );
579 } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
580 getCommonWithVoidPointer( refType, otherRef );
581 } else if ( ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst )
582 && ( refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond ) ) {
583 // std::cerr << "middle case" << std::endl;
584 Type::Qualifiers tq1 = refType->get_base()->tq, tq2 = otherRef->get_base()->tq;
585 refType->get_base()->tq = Type::Qualifiers();
586 otherRef->get_base()->tq = Type::Qualifiers();
587 AssertionSet have, need;
588 OpenVarSet newOpen( openVars );
589 if ( unifyExact( refType->get_base(), otherRef->get_base(), env, have, need, newOpen, indexer ) ) {
590 if ( tq1 < tq2 ) {
591 result = refType->clone();
592 } else {
593 result = otherRef->clone();
594 } // if
595 strict_dynamic_cast<ReferenceType *>(result)->base->tq = tq1 | tq2;
596 } else {
597 /// std::cerr << "place for ptr-to-type" << std::endl;
598 } // if
599 refType->get_base()->tq = tq1;
600 otherRef->get_base()->tq = tq2;
601 } // if
602 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
603 result = refType->clone();
604 result->tq |= type2->tq;
605 } // if
606 }
607
608 void CommonType_old::postvisit( FunctionType * ) {}
609 void CommonType_old::postvisit( StructInstType * ) {}
610 void CommonType_old::postvisit( UnionInstType * ) {}
611
612 void CommonType_old::postvisit( EnumInstType * enumInstType ) {
613 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
614 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType
615 result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars );
616 } // if
617 }
618
619 void CommonType_old::postvisit( TraitInstType * ) {
620 }
621
622 void CommonType_old::postvisit( TypeInstType * inst ) {
623 if ( widenFirst ) {
624 const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() );
625 if ( nt ) {
626 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
627 if ( type->get_base() ) {
628 Type::Qualifiers tq1 = inst->tq, tq2 = type2->tq;
629 AssertionSet have, need;
630 OpenVarSet newOpen( openVars );
631 type2->tq = Type::Qualifiers();
632 type->get_base()->tq = tq1;
633 if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) {
634 result = type2->clone();
635 result->tq = tq1 | tq2;
636 } // if
637 type2->tq = tq2;
638 type->get_base()->tq = Type::Qualifiers();
639 } // if
640 } // if
641 } // if
642 }
643
644 void CommonType_old::postvisit( TupleType * ) {}
645 void CommonType_old::postvisit( VarArgsType * ) {}
646
647 void CommonType_old::postvisit( ZeroType * zeroType ) {
648 if ( widenFirst ) {
649 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
650 if ( widenSecond || zeroType->tq <= type2->tq ) {
651 result = type2->clone();
652 result->tq |= zeroType->tq;
653 }
654 } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) {
655 result = new BasicType( zeroType->tq, BasicType::SignedInt );
656 result->tq |= type2->tq;
657 }
658 }
659 }
660
661 void CommonType_old::postvisit( OneType * oneType ) {
662 if ( widenFirst ) {
663 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
664 if ( widenSecond || oneType->tq <= type2->tq ) {
665 result = type2->clone();
666 result->tq |= oneType->tq;
667 }
668 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
669 result = new BasicType( oneType->tq, BasicType::SignedInt );
670 result->tq |= type2->tq;
671 }
672 }
673 }
674
675 class CommonType_new final : public ast::WithShortCircuiting {
676 const ast::Type * type2;
677 WidenMode widen;
678 ast::TypeEnvironment & tenv;
679 const ast::OpenVarSet & open;
680 ast::AssertionSet & need;
681 ast::AssertionSet & have;
682 public:
683 static size_t traceId;
684 ast::ptr< ast::Type > result;
685
686 CommonType_new(
687 const ast::Type * t2, WidenMode w,
688 ast::TypeEnvironment & env, const ast::OpenVarSet & o,
689 ast::AssertionSet & need, ast::AssertionSet & have )
690 : type2( t2 ), widen( w ), tenv( env ), open( o ), need (need), have (have) ,result() {}
691
692 void previsit( const ast::Node * ) { visit_children = false; }
693
694 void postvisit( const ast::VoidType * ) {}
695
696 void postvisit( const ast::BasicType * basic ) {
697 if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
698 #warning remove casts when `commonTypes` moved to new AST
699 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
700 if (
701 ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
702 || widen.first )
703 && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
704 || widen.second )
705 ) {
706 result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
707 }
708 } else if (
709 dynamic_cast< const ast::ZeroType * >( type2 )
710 || dynamic_cast< const ast::OneType * >( type2 )
711 ) {
712 #warning remove casts when `commonTypes` moved to new AST
713 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
714 if (
715 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
716 || widen.first )
717 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
718 || widen.second )
719 ) {
720 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
721 }
722 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
723 #warning remove casts when `commonTypes` moved to new AST
724 const ast::EnumDecl* enumDecl = enumInst->base;
725 if ( enumDecl->base ) {
726 result = enumDecl->base.get();
727 } else {
728 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
729 if (
730 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
731 || widen.first )
732 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
733 || widen.second )
734 ) {
735 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
736 }
737 }
738 }
739 }
740
741 private:
742 template< typename Pointer >
743 void getCommonWithVoidPointer( const Pointer * voidPtr, const Pointer * oPtr ) {
744 const ast::Type * base = oPtr->base;
745 if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) {
746 auto entry = open.find( *var );
747 if ( entry != open.end() ) {
748 ast::AssertionSet need, have;
749 if ( ! tenv.bindVar(
750 var, voidPtr->base, entry->second, need, have, open, widen )
751 ) return;
752 }
753 }
754 result = voidPtr;
755 add_qualifiers( result, oPtr->qualifiers );
756 }
757
758 // For a typed enum, we want to unify type1 with the base type of the enum
759 bool tryResolveWithTypedEnum( const ast::Type * type1 ) {
760 if (auto enumInst = dynamic_cast<const ast::EnumInstType *> (type2) ) {
761 ast::OpenVarSet newOpen{ open };
762 if (enumInst->base->base
763 && unifyExact(type1, enumInst->base->base, tenv, need, have, newOpen, widen)) {
764 result = type1;
765 return true;
766 }
767 }
768 return false;
769 }
770
771 public:
772 void postvisit( const ast::PointerType * pointer ) {
773 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
774 if (
775 widen.first
776 && pointer2->base.as< ast::VoidType >()
777 && ! ast::isFtype( pointer->base )
778 ) {
779 getCommonWithVoidPointer( pointer2, pointer );
780 } else if (
781 widen.second
782 && pointer->base.as< ast::VoidType >()
783 && ! ast::isFtype( pointer2->base )
784 ) {
785 getCommonWithVoidPointer( pointer, pointer2 );
786 } else if (
787 ( pointer->base->qualifiers >= pointer2->base->qualifiers || widen.first )
788 && ( pointer->base->qualifiers <= pointer2->base->qualifiers || widen.second )
789 ) {
790 ast::CV::Qualifiers q1 = pointer->base->qualifiers;
791 ast::CV::Qualifiers q2 = pointer2->base->qualifiers;
792
793 // force t{1,2} to be cloned if their qualifiers must be stripped, so that
794 // pointer{,2}->base are unchanged
795 ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base };
796 reset_qualifiers( t1 );
797 reset_qualifiers( t2 );
798
799 ast::OpenVarSet newOpen{ open };
800 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden() ) ) {
801 result = pointer;
802 if ( q1.val != q2.val ) {
803 // reset result->base->qualifiers to be union of two base qualifiers
804 strict_dynamic_cast< ast::PointerType * >(
805 result.get_and_mutate()
806 )->base.get_and_mutate()->qualifiers = q1 | q2;
807 }
808 }
809 else if ( isFtype (t1) && isFtype (t2) ) {
810 auto f1 = t1.as<ast::FunctionType>();
811 if (!f1) return;
812 auto f2 = t2.strict_as<ast::FunctionType>();
813
814 assertf(f1->returns.size() <= 1, "Function return should not be a list");
815 assertf(f2->returns.size() <= 1, "Function return should not be a list");
816
817 if (
818 ( f1->params.size() != f2->params.size() || f1->returns.size() != f2->returns.size() )
819 && ! f1->isTtype()
820 && ! f2->isTtype()
821 ) return;
822
823 auto params1 = flattenList( f1->params, tenv );
824 auto params2 = flattenList( f2->params, tenv );
825
826 auto crnt1 = params1.begin();
827 auto crnt2 = params2.begin();
828 auto end1 = params1.end();
829 auto end2 = params2.end();
830
831 while (crnt1 != end1 && crnt2 != end2 ) {
832 const ast::Type * arg1 = *crnt1;
833 const ast::Type * arg2 = *crnt2;
834
835 bool isTuple1 = Tuples::isTtype( t1 );
836 bool isTuple2 = Tuples::isTtype( t2 );
837
838 // assumes here that ttype *must* be last parameter
839 if ( isTuple1 && ! isTuple2 ) {
840 // combine remainder of list2, then unify
841 if (unifyExact(
842 arg1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open,
843 noWiden() )) {
844 break;
845
846 }
847 else return;
848 } else if ( ! isTuple1 && isTuple2 ) {
849 // combine remainder of list1, then unify
850 if (unifyExact(
851 tupleFromTypes( crnt1, end1 ), arg2, tenv, need, have, open,
852 noWiden() )) {
853 break;
854
855 }
856 else return;
857 }
858
859 // allow qualifiers of pointer and reference base to become more specific
860 if (auto ref1 = dynamic_cast<const ast::ReferenceType *> (arg1)) {
861 if (auto ref2 = dynamic_cast<const ast::ReferenceType *> (arg2)) {
862 ast::ptr<ast::Type> base1 = ref1->base;
863 ast::ptr<ast::Type> base2 = ref2->base;
864
865 // xxx - assume LHS is always the target type
866
867 if ( ! ((widen.second && ref2->qualifiers.is_mutex)
868 || (ref1->qualifiers.is_mutex == ref2->qualifiers.is_mutex ))) return;
869
870 if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) {
871
872 reset_qualifiers(base1);
873 reset_qualifiers(base2);
874
875 if ( ! unifyExact(
876 base1, base2, tenv, need, have, open, noWiden() )
877 ) return;
878 }
879 }
880 else return;
881 }
882 else if (auto ptr1 = dynamic_cast<const ast::PointerType *> (arg1)) {
883 if (auto ptr2 = dynamic_cast<const ast::PointerType *> (arg2)) {
884 ast::ptr<ast::Type> base1 = ptr1->base;
885 ast::ptr<ast::Type> base2 = ptr2->base;
886
887 // xxx - assume LHS is always the target type
888 // a function accepting const can always be called by non-const arg
889
890 if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) {
891
892 reset_qualifiers(base1);
893 reset_qualifiers(base2);
894
895 if ( ! unifyExact(
896 base1, base2, tenv, need, have, open, noWiden() )
897 ) return;
898 }
899 }
900 else return;
901
902 }
903 else if (! unifyExact(
904 arg1, arg2, tenv, need, have, open, noWiden() )) return;
905
906 ++crnt1; ++crnt2;
907 }
908 if ( crnt1 != end1 ) {
909 // try unifying empty tuple with ttype
910 const ast::Type * t1 = *crnt1;
911 if (! Tuples::isTtype( t1 ) ) return;
912 if (! unifyExact(
913 t1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open,
914 noWiden() )) return;
915 } else if ( crnt2 != end2 ) {
916 // try unifying empty tuple with ttype
917 const ast::Type * t2 = *crnt2;
918 if (! Tuples::isTtype( t2 ) ) return;
919 if (! unifyExact(
920 tupleFromTypes( crnt1, end1 ), t2, tenv, need, have, open,
921 noWiden() )) return;
922 }
923 if ((f1->returns.size() == 0 && f2->returns.size() == 0)
924 || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden()))) {
925 result = pointer;
926
927 for (auto & assn : f1->assertions) {
928 auto i = need.find(assn);
929 if (i != need.end()) i->second.isUsed = true;
930 auto j = have.find(assn);
931 if (j != have.end()) j->second.isUsed = true;
932 }
933
934 for (auto & assn : f2->assertions) {
935 auto i = need.find(assn);
936 if (i != need.end()) i->second.isUsed = true;
937 auto j = have.find(assn);
938 if (j != have.end()) j->second.isUsed = true;
939 }
940
941 }
942 } // if ftype
943
944 }
945 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
946 result = pointer;
947 add_qualifiers( result, type2->qualifiers );
948 } else {
949 tryResolveWithTypedEnum( pointer );
950 }
951 }
952
953 void postvisit( const ast::ArrayType * arr ) {
954 // xxx - does it make sense?
955 tryResolveWithTypedEnum( arr );
956 }
957
958 void postvisit( const ast::ReferenceType * ref ) {
959 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
960 if (
961 widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base )
962 ) {
963 getCommonWithVoidPointer( ref2, ref );
964 } else if (
965 widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base )
966 ) {
967 getCommonWithVoidPointer( ref, ref2 );
968 } else if (
969 ( ref->base->qualifiers >= ref2->base->qualifiers || widen.first )
970 && ( ref->base->qualifiers <= ref2->base->qualifiers || widen.second )
971 ) {
972 ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers;
973
974 // force t{1,2} to be cloned if their qualifiers must be stripped, so that
975 // ref{,2}->base are unchanged
976 ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base };
977 reset_qualifiers( t1 );
978 reset_qualifiers( t2 );
979
980 ast::OpenVarSet newOpen{ open };
981 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden() ) ) {
982 result = ref;
983 if ( q1.val != q2.val ) {
984 // reset result->base->qualifiers to be union of two base qualifiers
985 strict_dynamic_cast< ast::ReferenceType * >(
986 result.get_and_mutate()
987 )->base.get_and_mutate()->qualifiers = q1 | q2;
988 }
989 }
990 }
991 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
992 result = ref;
993 add_qualifiers( result, type2->qualifiers );
994 } else {
995 if (!dynamic_cast<const ast::EnumInstType *>(type2))
996 result = commonType( type2, ref, tenv, need, have, open, widen );
997 }
998 }
999
1000 void postvisit( const ast::FunctionType * func) {
1001 tryResolveWithTypedEnum( func );
1002 }
1003
1004 void postvisit( const ast::StructInstType * inst ) {
1005 tryResolveWithTypedEnum( inst );
1006 }
1007
1008 void postvisit( const ast::UnionInstType * inst ) {
1009 tryResolveWithTypedEnum( inst );
1010 }
1011
1012 void postvisit( const ast::EnumInstType * enumInst ) {
1013 if (!dynamic_cast<const ast::EnumInstType *>(type2))
1014 result = commonType( type2, enumInst, tenv, need, have, open, widen);
1015 }
1016
1017 void postvisit( const ast::TraitInstType * ) {}
1018
1019 void postvisit( const ast::TypeInstType * ) {}
1020
1021 void postvisit( const ast::TupleType * tuple ) {
1022 tryResolveWithTypedEnum( tuple );
1023 }
1024
1025 void postvisit( const ast::VarArgsType * ) {}
1026
1027 void postvisit( const ast::ZeroType * zero ) {
1028 if ( ! widen.first ) return;
1029 if ( dynamic_cast< const ast::BasicType * >( type2 )
1030 || dynamic_cast< const ast::PointerType * >( type2 ) ) {
1031 if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
1032 result = type2;
1033 add_qualifiers( result, zero->qualifiers );
1034 }
1035 } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
1036 result = new ast::BasicType{
1037 ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers };
1038 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
1039 const ast::EnumDecl * enumDecl = enumInst->base;
1040 if ( enumDecl->base ) {
1041 if ( tryResolveWithTypedEnum( zero ) )
1042 add_qualifiers( result, zero->qualifiers );
1043 } else {
1044 if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
1045 result = type2;
1046 add_qualifiers( result, zero->qualifiers );
1047 }
1048 }
1049 }
1050 }
1051
1052 void postvisit( const ast::OneType * one ) {
1053 if ( ! widen.first ) return;
1054 if ( dynamic_cast< const ast::BasicType * >( type2 ) ) {
1055 if ( widen.second || one->qualifiers <= type2->qualifiers ) {
1056 result = type2;
1057 add_qualifiers( result, one->qualifiers );
1058 }
1059 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
1060 result = new ast::BasicType{
1061 ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers };
1062 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
1063 const ast::EnumDecl * enumBase = enumInst->base;
1064 if ( enumBase->base ) {
1065 if ( tryResolveWithTypedEnum( one ))
1066 add_qualifiers( result, one->qualifiers );
1067 } else {
1068 if ( widen.second || one->qualifiers <= type2->qualifiers ) {
1069 result = type2;
1070 add_qualifiers( result, one->qualifiers );
1071 }
1072 }
1073 }
1074 }
1075
1076 };
1077
1078 // size_t CommonType_new::traceId = Stats::Heap::new_stacktrace_id("CommonType_new");
1079 namespace {
1080 ast::ptr< ast::Type > handleReference(
1081 const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
1082 ast::TypeEnvironment & env,
1083 const ast::OpenVarSet & open
1084 ) {
1085 ast::ptr<ast::Type> common;
1086 ast::AssertionSet have, need;
1087 ast::OpenVarSet newOpen{ open };
1088
1089 // need unify to bind type variables
1090 if ( unify( t1, t2, env, have, need, newOpen, common ) ) {
1091 ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers;
1092 PRINT(
1093 std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
1094 )
1095 if ( ( widen.first || q2 <= q1 ) && ( widen.second || q1 <= q2 ) ) {
1096 PRINT(
1097 std::cerr << "widen okay" << std::endl;
1098 )
1099 add_qualifiers( common, q1 | q2 );
1100 return common;
1101 }
1102 }
1103
1104 PRINT(
1105 std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
1106 )
1107 return { nullptr };
1108 }
1109 }
1110
1111 ast::ptr< ast::Type > commonType(
1112 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
1113 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
1114 const ast::OpenVarSet & open, WidenMode widen
1115 ) {
1116 unsigned depth1 = type1->referenceDepth();
1117 unsigned depth2 = type2->referenceDepth();
1118
1119 if ( depth1 != depth2 ) { // implies depth1 > 0 || depth2 > 0
1120 PRINT(
1121 std::cerr << "reference depth diff: " << (depth1-depth2) << std::endl;
1122 )
1123 ast::ptr< ast::Type > result;
1124 const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
1125 const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >();
1126
1127 if ( depth1 > depth2 ) {
1128 assert( ref1 );
1129 result = handleReference( ref1->base, type2, widen, env, open );
1130 } else { // implies depth1 < depth2
1131 assert( ref2 );
1132 result = handleReference( type1, ref2->base, widen, env, open );
1133 }
1134
1135 if ( result && ref1 ) {
1136 // formal is reference, so result should be reference
1137 PRINT(
1138 std::cerr << "formal is reference; result should be reference" << std::endl;
1139 )
1140 result = new ast::ReferenceType{ result, ref1->qualifiers };
1141 }
1142
1143 PRINT(
1144 std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is "
1145 "[" << result << "]" << std::endl;
1146 )
1147 return result;
1148 }
1149 // otherwise both are reference types of the same depth and this is handled by the visitor
1150 ast::Pass<CommonType_new> visitor{ type2, widen, env, open, need, have };
1151 type1->accept( visitor );
1152 // ast::ptr< ast::Type > result = visitor.core.result;
1153
1154 return visitor.core.result;
1155 }
1156
1157} // namespace ResolvExpr
1158
1159// Local Variables: //
1160// tab-width: 4 //
1161// mode: c++ //
1162// compile-command: "make install" //
1163// End: //
Note: See TracBrowser for help on using the repository browser.