source: src/ResolvExpr/CommonType.cc@ 033ff37

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 033ff37 was ef5b828, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Indexer now has const lookup by default

  • Property mode set to 100644
File size: 60.2 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< EnumInstType * > ( type2 ) || 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 } // if
506 }
507
508 template< typename Pointer >
509 void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ) {
510 if ( TypeInstType * var = dynamic_cast< TypeInstType * >( otherPointer->get_base() ) ) {
511 OpenVarSet::const_iterator entry = openVars.find( var->get_name() );
512 if ( entry != openVars.end() ) {
513 AssertionSet need, have;
514 WidenMode widen( widenFirst, widenSecond );
515 if ( entry != openVars.end() && ! env.bindVar(var, voidPointer->get_base(), entry->second, need, have, openVars, widen, indexer ) ) return;
516 }
517 }
518 result = voidPointer->clone();
519 result->tq |= otherPointer->tq;
520 }
521
522 void CommonType_old::postvisit( PointerType * pointerType ) {
523 if ( PointerType * otherPointer = dynamic_cast< PointerType * >( type2 ) ) {
524 // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl;
525 if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
526 getCommonWithVoidPointer( otherPointer, pointerType );
527 } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
528 getCommonWithVoidPointer( pointerType, otherPointer );
529 } else if ( ( pointerType->get_base()->tq >= otherPointer->get_base()->tq || widenFirst )
530 && ( pointerType->get_base()->tq <= otherPointer->get_base()->tq || widenSecond ) ) {
531 // std::cerr << "middle case" << std::endl;
532 Type::Qualifiers tq1 = pointerType->get_base()->tq, tq2 = otherPointer->get_base()->tq;
533 pointerType->get_base()->tq = Type::Qualifiers();
534 otherPointer->get_base()->tq = Type::Qualifiers();
535 AssertionSet have, need;
536 OpenVarSet newOpen( openVars );
537 if ( unifyExact( pointerType->get_base(), otherPointer->get_base(), env, have, need, newOpen, indexer ) ) {
538 // std::cerr << "unifyExact success" << std::endl;
539 if ( tq1 < tq2 ) {
540 result = pointerType->clone();
541 } else {
542 result = otherPointer->clone();
543 } // if
544 strict_dynamic_cast<PointerType *>(result)->base->tq = tq1 | tq2;
545 } else {
546 /// std::cerr << "place for ptr-to-type" << std::endl;
547 } // if
548 pointerType->get_base()->tq = tq1;
549 otherPointer->get_base()->tq = tq2;
550 } // if
551 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
552 result = pointerType->clone();
553 result->tq |= type2->tq;
554 } // if
555 }
556
557 void CommonType_old::postvisit( ArrayType * ) {}
558
559 void CommonType_old::postvisit( ReferenceType * refType ) {
560 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( type2 ) ) {
561 // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl;
562 // std::cerr << ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) << (refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond) << std::endl;
563 if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
564 getCommonWithVoidPointer( otherRef, refType );
565 } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
566 getCommonWithVoidPointer( refType, otherRef );
567 } else if ( ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst )
568 && ( refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond ) ) {
569 // std::cerr << "middle case" << std::endl;
570 Type::Qualifiers tq1 = refType->get_base()->tq, tq2 = otherRef->get_base()->tq;
571 refType->get_base()->tq = Type::Qualifiers();
572 otherRef->get_base()->tq = Type::Qualifiers();
573 AssertionSet have, need;
574 OpenVarSet newOpen( openVars );
575 if ( unifyExact( refType->get_base(), otherRef->get_base(), env, have, need, newOpen, indexer ) ) {
576 if ( tq1 < tq2 ) {
577 result = refType->clone();
578 } else {
579 result = otherRef->clone();
580 } // if
581 strict_dynamic_cast<ReferenceType *>(result)->base->tq = tq1 | tq2;
582 } else {
583 /// std::cerr << "place for ptr-to-type" << std::endl;
584 } // if
585 refType->get_base()->tq = tq1;
586 otherRef->get_base()->tq = tq2;
587 } // if
588 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
589 result = refType->clone();
590 result->tq |= type2->tq;
591 } // if
592 }
593
594 void CommonType_old::postvisit( FunctionType * ) {}
595 void CommonType_old::postvisit( StructInstType * ) {}
596 void CommonType_old::postvisit( UnionInstType * ) {}
597
598 void CommonType_old::postvisit( EnumInstType * enumInstType ) {
599 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
600 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType
601 result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars );
602 } // if
603 }
604
605 void CommonType_old::postvisit( TraitInstType * ) {
606 }
607
608 void CommonType_old::postvisit( TypeInstType * inst ) {
609 if ( widenFirst ) {
610 const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() );
611 if ( nt ) {
612 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
613 if ( type->get_base() ) {
614 Type::Qualifiers tq1 = inst->tq, tq2 = type2->tq;
615 AssertionSet have, need;
616 OpenVarSet newOpen( openVars );
617 type2->tq = Type::Qualifiers();
618 type->get_base()->tq = tq1;
619 if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) {
620 result = type2->clone();
621 result->tq = tq1 | tq2;
622 } // if
623 type2->tq = tq2;
624 type->get_base()->tq = Type::Qualifiers();
625 } // if
626 } // if
627 } // if
628 }
629
630 void CommonType_old::postvisit( TupleType * ) {}
631 void CommonType_old::postvisit( VarArgsType * ) {}
632
633 void CommonType_old::postvisit( ZeroType * zeroType ) {
634 if ( widenFirst ) {
635 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
636 if ( widenSecond || zeroType->tq <= type2->tq ) {
637 result = type2->clone();
638 result->tq |= zeroType->tq;
639 }
640 } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) {
641 result = new BasicType( zeroType->tq, BasicType::SignedInt );
642 result->tq |= type2->tq;
643 }
644 }
645 }
646
647 void CommonType_old::postvisit( OneType * oneType ) {
648 if ( widenFirst ) {
649 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
650 if ( widenSecond || oneType->tq <= type2->tq ) {
651 result = type2->clone();
652 result->tq |= oneType->tq;
653 }
654 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
655 result = new BasicType( oneType->tq, BasicType::SignedInt );
656 result->tq |= type2->tq;
657 }
658 }
659 }
660
661 class CommonType_new final : public ast::WithShortCircuiting {
662 const ast::Type * type2;
663 WidenMode widen;
664 const ast::SymbolTable & symtab;
665 ast::TypeEnvironment & tenv;
666 const ast::OpenVarSet & open;
667 public:
668 ast::ptr< ast::Type > result;
669
670 CommonType_new(
671 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st,
672 ast::TypeEnvironment & env, const ast::OpenVarSet & o )
673 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {}
674
675 void previsit( const ast::Node * ) { visit_children = false; }
676
677 void postvisit( const ast::VoidType * ) {}
678
679 void postvisit( const ast::BasicType * basic ) {
680 if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
681 #warning remove casts when `commonTypes` moved to new AST
682 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
683 if (
684 ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
685 || widen.first )
686 && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
687 || widen.second )
688 ) {
689 result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
690 }
691 } else if (
692 dynamic_cast< const ast::EnumInstType * >( type2 )
693 || dynamic_cast< const ast::ZeroType * >( type2 )
694 || dynamic_cast< const ast::OneType * >( type2 )
695 ) {
696 #warning remove casts when `commonTypes` moved to new AST
697 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
698 if (
699 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
700 || widen.first )
701 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
702 || widen.second )
703 ) {
704 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
705 }
706 }
707 }
708
709 private:
710 template< typename Pointer >
711 void getCommonWithVoidPointer( const Pointer * voidPtr, const Pointer * oPtr ) {
712 const ast::Type * base = oPtr->base;
713 if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) {
714 auto entry = open.find( var->name );
715 if ( entry != open.end() ) {
716 ast::AssertionSet need, have;
717 if ( ! tenv.bindVar(
718 var, voidPtr->base, entry->second, need, have, open, widen, symtab )
719 ) return;
720 }
721 }
722 result = voidPtr;
723 add_qualifiers( result, oPtr->qualifiers );
724 }
725
726 public:
727 void postvisit( const ast::PointerType * pointer ) {
728 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
729 if (
730 widen.first
731 && pointer2->base.as< ast::VoidType >()
732 && ! ast::isFtype( pointer->base )
733 ) {
734 getCommonWithVoidPointer( pointer2, pointer );
735 } else if (
736 widen.second
737 && pointer->base.as< ast::VoidType >()
738 && ! ast::isFtype( pointer2->base )
739 ) {
740 getCommonWithVoidPointer( pointer, pointer2 );
741 } else if (
742 ( pointer->base->qualifiers >= pointer2->base->qualifiers || widen.first )
743 && ( pointer->base->qualifiers <= pointer2->base->qualifiers || widen.second )
744 ) {
745 ast::CV::Qualifiers q1 = pointer->base->qualifiers;
746 ast::CV::Qualifiers q2 = pointer2->base->qualifiers;
747
748 // force t{1,2} to be cloned if their qualifiers must be stripped, so that
749 // pointer{,2}->base are unchanged
750 ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base };
751 reset_qualifiers( t1 );
752 reset_qualifiers( t2 );
753
754 ast::AssertionSet have, need;
755 ast::OpenVarSet newOpen{ open };
756 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
757 result = pointer;
758 if ( q1.val != q2.val ) {
759 // reset result->base->qualifiers to be union of two base qualifiers
760 strict_dynamic_cast< ast::PointerType * >(
761 result.get_and_mutate()
762 )->base.get_and_mutate()->qualifiers = q1 | q2;
763 }
764 }
765 }
766 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
767 result = pointer;
768 add_qualifiers( result, type2->qualifiers );
769 }
770 }
771
772 void postvisit( const ast::ArrayType * ) {}
773
774 void postvisit( const ast::ReferenceType * ref ) {
775 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
776 if (
777 widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base )
778 ) {
779 getCommonWithVoidPointer( ref2, ref );
780 } else if (
781 widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base )
782 ) {
783 getCommonWithVoidPointer( ref, ref2 );
784 } else if (
785 ( ref->base->qualifiers >= ref2->base->qualifiers || widen.first )
786 && ( ref->base->qualifiers <= ref2->base->qualifiers || widen.second )
787 ) {
788 ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers;
789
790 // force t{1,2} to be cloned if their qualifiers must be stripped, so that
791 // ref{,2}->base are unchanged
792 ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base };
793 reset_qualifiers( t1 );
794 reset_qualifiers( t2 );
795
796 ast::AssertionSet have, need;
797 ast::OpenVarSet newOpen{ open };
798 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
799 result = ref;
800 if ( q1.val != q2.val ) {
801 // reset result->base->qualifiers to be union of two base qualifiers
802 strict_dynamic_cast< ast::ReferenceType * >(
803 result.get_and_mutate()
804 )->base.get_and_mutate()->qualifiers = q1 | q2;
805 }
806 }
807 }
808 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
809 result = ref;
810 add_qualifiers( result, type2->qualifiers );
811 }
812 }
813
814 void postvisit( const ast::FunctionType * ) {}
815
816 void postvisit( const ast::StructInstType * ) {}
817
818 void postvisit( const ast::UnionInstType * ) {}
819
820 void postvisit( const ast::EnumInstType * enumInst ) {
821 if (
822 dynamic_cast< const ast::BasicType * >( type2 )
823 || dynamic_cast< const ast::ZeroType * >( type2 )
824 || dynamic_cast< const ast::OneType * >( type2 )
825 ) {
826 // reuse BasicType/EnumInstType common type by swapping
827 result = commonType( type2, enumInst, widen, symtab, tenv, open );
828 }
829 }
830
831 void postvisit( const ast::TraitInstType * ) {}
832
833 void postvisit( const ast::TypeInstType * inst ) {
834 if ( ! widen.first ) return;
835 if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
836 if ( const ast::Type * base =
837 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base
838 ) {
839 ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers;
840
841 // force t{1,2} to be cloned if their qualifiers must be mutated
842 ast::ptr< ast::Type > t1{ base }, t2{ type2 };
843 reset_qualifiers( t1, q1 );
844 reset_qualifiers( t2 );
845
846 ast::AssertionSet have, need;
847 ast::OpenVarSet newOpen{ open };
848 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
849 result = type2;
850 reset_qualifiers( result, q1 | q2 );
851 }
852 }
853 }
854 }
855
856 void postvisit( const ast::TupleType * ) {}
857
858 void postvisit( const ast::VarArgsType * ) {}
859
860 void postvisit( const ast::ZeroType * zero ) {
861 if ( ! widen.first ) return;
862 if (
863 dynamic_cast< const ast::BasicType * >( type2 )
864 || dynamic_cast< const ast::PointerType * >( type2 )
865 || dynamic_cast< const ast::EnumInstType * >( type2 )
866 ) {
867 if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
868 result = type2;
869 add_qualifiers( result, zero->qualifiers );
870 }
871 } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
872 result = new ast::BasicType{
873 ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers };
874 }
875 }
876
877 void postvisit( const ast::OneType * one ) {
878 if ( ! widen.first ) return;
879 if (
880 dynamic_cast< const ast::BasicType * >( type2 )
881 || dynamic_cast< const ast::EnumInstType * >( type2 )
882 ) {
883 if ( widen.second || one->qualifiers <= type2->qualifiers ) {
884 result = type2;
885 add_qualifiers( result, one->qualifiers );
886 }
887 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
888 result = new ast::BasicType{
889 ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers };
890 }
891 }
892
893 };
894
895 namespace {
896 ast::ptr< ast::Type > handleReference(
897 const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
898 const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
899 const ast::OpenVarSet & open
900 ) {
901 ast::ptr<ast::Type> common;
902 ast::AssertionSet have, need;
903 ast::OpenVarSet newOpen{ open };
904
905 // need unify to bind type variables
906 if ( unify( t1, t2, env, have, need, newOpen, symtab, common ) ) {
907 ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers;
908 PRINT(
909 std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
910 )
911 if ( ( widen.first || q2 <= q1 ) && ( widen.second || q1 <= q2 ) ) {
912 PRINT(
913 std::cerr << "widen okay" << std::endl;
914 )
915 add_qualifiers( common, q1 | q2 );
916 return common;
917 }
918 }
919
920 PRINT(
921 std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
922 )
923 return { nullptr };
924 }
925 }
926
927 ast::ptr< ast::Type > commonType(
928 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
929 WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
930 const ast::OpenVarSet & open
931 ) {
932 unsigned depth1 = type1->referenceDepth();
933 unsigned depth2 = type2->referenceDepth();
934
935 if ( depth1 != depth2 ) { // implies depth1 > 0 || depth2 > 0
936 PRINT(
937 std::cerr << "reference depth diff: " << (depth1-depth2) << std::endl;
938 )
939 ast::ptr< ast::Type > result;
940 const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
941 const ast::ReferenceType * ref2 = type1.as< ast::ReferenceType >();
942
943 if ( depth1 > depth2 ) {
944 assert( ref1 );
945 result = handleReference( ref1->base, type2, widen, symtab, env, open );
946 } else { // implies depth1 < depth2
947 assert( ref2 );
948 result = handleReference( type1, ref2->base, widen, symtab, env, open );
949 }
950
951 if ( result && ref1 ) {
952 // formal is reference, so result should be reference
953 PRINT(
954 std::cerr << "formal is reference; result should be reference" << std::endl;
955 )
956 result = new ast::ReferenceType{ result, ref1->qualifiers };
957 }
958
959 PRINT(
960 std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is "
961 "[" << result << "]" << std::endl;
962 )
963 return result;
964 }
965 // otherwise both are reference types of the same depth and this is handled by the visitor
966 ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open };
967 type1->accept( visitor );
968 ast::ptr< ast::Type > result = visitor.pass.result;
969
970 // handling for opaque type declarations (?)
971 if ( ! result && widen.second ) {
972 if ( const ast::TypeInstType * inst = type2.as< ast::TypeInstType >() ) {
973 if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
974 auto type = strict_dynamic_cast< const ast::TypeDecl * >( nt );
975 if ( type->base ) {
976 ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
977 ast::AssertionSet have, need;
978 ast::OpenVarSet newOpen{ open };
979
980 // force t{1,2} to be cloned if its qualifiers must be stripped, so that
981 // type1 and type->base are left unchanged; calling convention forces
982 // {type1,type->base}->strong_ref >= 1
983 ast::ptr<ast::Type> t1{ type1 }, t2{ type->base };
984 reset_qualifiers( t1 );
985 reset_qualifiers( t2, q1 );
986
987 if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) {
988 result = t1;
989 reset_qualifiers( result, q1 | q2 );
990 }
991 }
992 }
993 }
994 }
995
996 return result;
997 }
998
999} // namespace ResolvExpr
1000
1001// Local Variables: //
1002// tab-width: 4 //
1003// mode: c++ //
1004// compile-command: "make install" //
1005// End: //
Note: See TracBrowser for help on using the repository browser.