source: src/ResolvExpr/CommonType.cc@ df00c78

ADT ast-experimental pthread-emulation
Last change on this file since df00c78 was fc134a48, checked in by JiadaL <j82liang@…>, 3 years ago

Implement the struct enum

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