source: src/ResolvExpr/CommonType.cc@ 4dbdd1d

Last change on this file since 4dbdd1d was 62d62db, checked in by caparsons <caparson@…>, 2 years ago

Merge branch 'master' into ast-experimental

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