source: src/ResolvExpr/CommonType.cc@ 38cc59f

ADT ast-experimental
Last change on this file since 38cc59f was ef1da0e2, checked in by Fangren Yu <f37yu@…>, 3 years ago

try to make parameter qualifier conversion work for assertions

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