source: src/ResolvExpr/CommonType.cc@ a01faa98

ast-experimental
Last change on this file since a01faa98 was bccd70a, checked in by Andrew Beach <ajbeach@…>, 2 years ago

Removed internal code from TypeSubstitution header. It caused a chain of include problems, which have been corrected.

  • Property mode set to 100644
File size: 67.8 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 const ast::SymbolTable & symtab;
679 ast::TypeEnvironment & tenv;
680 const ast::OpenVarSet & open;
681 ast::AssertionSet & need;
682 ast::AssertionSet & have;
683 public:
684 static size_t traceId;
685 ast::ptr< ast::Type > result;
686
687 CommonType_new(
688 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st,
689 ast::TypeEnvironment & env, const ast::OpenVarSet & o,
690 ast::AssertionSet & need, ast::AssertionSet & have )
691 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), need (need), have (have) ,result() {}
692
693 void previsit( const ast::Node * ) { visit_children = false; }
694
695 void postvisit( const ast::VoidType * ) {}
696
697 void postvisit( const ast::BasicType * basic ) {
698 if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
699 #warning remove casts when `commonTypes` moved to new AST
700 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
701 if (
702 ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
703 || widen.first )
704 && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
705 || widen.second )
706 ) {
707 result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
708 }
709 } else if (
710 dynamic_cast< const ast::ZeroType * >( type2 )
711 || dynamic_cast< const ast::OneType * >( type2 )
712 ) {
713 #warning remove casts when `commonTypes` moved to new AST
714 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
715 if (
716 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
717 || widen.first )
718 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
719 || widen.second )
720 ) {
721 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
722 }
723 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
724 #warning remove casts when `commonTypes` moved to new AST
725 const ast::EnumDecl* enumDecl = enumInst->base;
726 if ( enumDecl->base ) {
727 result = enumDecl->base.get();
728 } else {
729 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
730 if (
731 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
732 || widen.first )
733 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
734 || widen.second )
735 ) {
736 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
737 }
738 }
739 }
740 }
741
742 private:
743 template< typename Pointer >
744 void getCommonWithVoidPointer( const Pointer * voidPtr, const Pointer * oPtr ) {
745 const ast::Type * base = oPtr->base;
746 if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) {
747 auto entry = open.find( *var );
748 if ( entry != open.end() ) {
749 ast::AssertionSet need, have;
750 if ( ! tenv.bindVar(
751 var, voidPtr->base, entry->second, need, have, open, widen, symtab )
752 ) return;
753 }
754 }
755 result = voidPtr;
756 add_qualifiers( result, oPtr->qualifiers );
757 }
758
759 // For a typed enum, we want to unify type1 with the base type of the enum
760 bool tryResolveWithTypedEnum( const ast::Type * type1 ) {
761 if (auto enumInst = dynamic_cast<const ast::EnumInstType *> (type2) ) {
762 ast::OpenVarSet newOpen{ open };
763 if (enumInst->base->base
764 && unifyExact(type1, enumInst->base->base, tenv, need, have, newOpen, widen, symtab)) {
765 result = type1;
766 return true;
767 }
768 }
769 return false;
770 }
771
772 public:
773 void postvisit( const ast::PointerType * pointer ) {
774 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
775 if (
776 widen.first
777 && pointer2->base.as< ast::VoidType >()
778 && ! ast::isFtype( pointer->base )
779 ) {
780 getCommonWithVoidPointer( pointer2, pointer );
781 } else if (
782 widen.second
783 && pointer->base.as< ast::VoidType >()
784 && ! ast::isFtype( pointer2->base )
785 ) {
786 getCommonWithVoidPointer( pointer, pointer2 );
787 } else if (
788 ( pointer->base->qualifiers >= pointer2->base->qualifiers || widen.first )
789 && ( pointer->base->qualifiers <= pointer2->base->qualifiers || widen.second )
790 ) {
791 ast::CV::Qualifiers q1 = pointer->base->qualifiers;
792 ast::CV::Qualifiers q2 = pointer2->base->qualifiers;
793
794 // force t{1,2} to be cloned if their qualifiers must be stripped, so that
795 // pointer{,2}->base are unchanged
796 ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base };
797 reset_qualifiers( t1 );
798 reset_qualifiers( t2 );
799
800 ast::OpenVarSet newOpen{ open };
801 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
802 result = pointer;
803 if ( q1.val != q2.val ) {
804 // reset result->base->qualifiers to be union of two base qualifiers
805 strict_dynamic_cast< ast::PointerType * >(
806 result.get_and_mutate()
807 )->base.get_and_mutate()->qualifiers = q1 | q2;
808 }
809 }
810 else if ( isFtype (t1) && isFtype (t2) ) {
811 auto f1 = t1.as<ast::FunctionType>();
812 if (!f1) return;
813 auto f2 = t2.strict_as<ast::FunctionType>();
814
815 assertf(f1->returns.size() <= 1, "Function return should not be a list");
816 assertf(f2->returns.size() <= 1, "Function return should not be a list");
817
818 if (
819 ( f1->params.size() != f2->params.size() || f1->returns.size() != f2->returns.size() )
820 && ! f1->isTtype()
821 && ! f2->isTtype()
822 ) return;
823
824 auto params1 = flattenList( f1->params, tenv );
825 auto params2 = flattenList( f2->params, tenv );
826
827 auto crnt1 = params1.begin();
828 auto crnt2 = params2.begin();
829 auto end1 = params1.end();
830 auto end2 = params2.end();
831
832 while (crnt1 != end1 && crnt2 != end2 ) {
833 const ast::Type * arg1 = *crnt1;
834 const ast::Type * arg2 = *crnt2;
835
836 bool isTuple1 = Tuples::isTtype( t1 );
837 bool isTuple2 = Tuples::isTtype( t2 );
838
839 // assumes here that ttype *must* be last parameter
840 if ( isTuple1 && ! isTuple2 ) {
841 // combine remainder of list2, then unify
842 if (unifyExact(
843 arg1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open,
844 noWiden(), symtab )) {
845 break;
846
847 }
848 else return;
849 } else if ( ! isTuple1 && isTuple2 ) {
850 // combine remainder of list1, then unify
851 if (unifyExact(
852 tupleFromTypes( crnt1, end1 ), arg2, tenv, need, have, open,
853 noWiden(), symtab )) {
854 break;
855
856 }
857 else return;
858 }
859
860 // allow qualifiers of pointer and reference base to become more specific
861 if (auto ref1 = dynamic_cast<const ast::ReferenceType *> (arg1)) {
862 if (auto ref2 = dynamic_cast<const ast::ReferenceType *> (arg2)) {
863 ast::ptr<ast::Type> base1 = ref1->base;
864 ast::ptr<ast::Type> base2 = ref2->base;
865
866 // xxx - assume LHS is always the target type
867
868 if ( ! ((widen.second && ref2->qualifiers.is_mutex)
869 || (ref1->qualifiers.is_mutex == ref2->qualifiers.is_mutex ))) return;
870
871 if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) {
872
873 reset_qualifiers(base1);
874 reset_qualifiers(base2);
875
876 if ( ! unifyExact(
877 base1, base2, tenv, need, have, open, noWiden(), symtab )
878 ) return;
879 }
880 }
881 else return;
882 }
883 else if (auto ptr1 = dynamic_cast<const ast::PointerType *> (arg1)) {
884 if (auto ptr2 = dynamic_cast<const ast::PointerType *> (arg2)) {
885 ast::ptr<ast::Type> base1 = ptr1->base;
886 ast::ptr<ast::Type> base2 = ptr2->base;
887
888 // xxx - assume LHS is always the target type
889 // a function accepting const can always be called by non-const arg
890
891 if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) {
892
893 reset_qualifiers(base1);
894 reset_qualifiers(base2);
895
896 if ( ! unifyExact(
897 base1, base2, tenv, need, have, open, noWiden(), symtab )
898 ) return;
899 }
900 }
901 else return;
902
903 }
904 else if (! unifyExact(
905 arg1, arg2, tenv, need, have, open, noWiden(), symtab )) return;
906
907 ++crnt1; ++crnt2;
908 }
909 if ( crnt1 != end1 ) {
910 // try unifying empty tuple with ttype
911 const ast::Type * t1 = *crnt1;
912 if (! Tuples::isTtype( t1 ) ) return;
913 if (! unifyExact(
914 t1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open,
915 noWiden(), symtab )) return;
916 } else if ( crnt2 != end2 ) {
917 // try unifying empty tuple with ttype
918 const ast::Type * t2 = *crnt2;
919 if (! Tuples::isTtype( t2 ) ) return;
920 if (! unifyExact(
921 tupleFromTypes( crnt1, end1 ), t2, tenv, need, have, open,
922 noWiden(), symtab )) return;
923 }
924 if ((f1->returns.size() == 0 && f2->returns.size() == 0)
925 || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden(), symtab))) {
926 result = pointer;
927
928 for (auto & assn : f1->assertions) {
929 auto i = need.find(assn);
930 if (i != need.end()) i->second.isUsed = true;
931 auto j = have.find(assn);
932 if (j != have.end()) j->second.isUsed = true;
933 }
934
935 for (auto & assn : f2->assertions) {
936 auto i = need.find(assn);
937 if (i != need.end()) i->second.isUsed = true;
938 auto j = have.find(assn);
939 if (j != have.end()) j->second.isUsed = true;
940 }
941
942 }
943 } // if ftype
944
945 }
946 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
947 result = pointer;
948 add_qualifiers( result, type2->qualifiers );
949 } else {
950 tryResolveWithTypedEnum( pointer );
951 }
952 }
953
954 void postvisit( const ast::ArrayType * arr ) {
955 // xxx - does it make sense?
956 tryResolveWithTypedEnum( arr );
957 }
958
959 void postvisit( const ast::ReferenceType * ref ) {
960 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
961 if (
962 widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base )
963 ) {
964 getCommonWithVoidPointer( ref2, ref );
965 } else if (
966 widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base )
967 ) {
968 getCommonWithVoidPointer( ref, ref2 );
969 } else if (
970 ( ref->base->qualifiers >= ref2->base->qualifiers || widen.first )
971 && ( ref->base->qualifiers <= ref2->base->qualifiers || widen.second )
972 ) {
973 ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers;
974
975 // force t{1,2} to be cloned if their qualifiers must be stripped, so that
976 // ref{,2}->base are unchanged
977 ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base };
978 reset_qualifiers( t1 );
979 reset_qualifiers( t2 );
980
981 ast::OpenVarSet newOpen{ open };
982 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
983 result = ref;
984 if ( q1.val != q2.val ) {
985 // reset result->base->qualifiers to be union of two base qualifiers
986 strict_dynamic_cast< ast::ReferenceType * >(
987 result.get_and_mutate()
988 )->base.get_and_mutate()->qualifiers = q1 | q2;
989 }
990 }
991 }
992 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
993 result = ref;
994 add_qualifiers( result, type2->qualifiers );
995 } else {
996 if (!dynamic_cast<const ast::EnumInstType *>(type2))
997 result = commonType( type2, ref, tenv, need, have, open, widen, symtab );
998 }
999 }
1000
1001 void postvisit( const ast::FunctionType * func) {
1002 tryResolveWithTypedEnum( func );
1003 }
1004
1005 void postvisit( const ast::StructInstType * inst ) {
1006 tryResolveWithTypedEnum( inst );
1007 }
1008
1009 void postvisit( const ast::UnionInstType * inst ) {
1010 tryResolveWithTypedEnum( inst );
1011 }
1012
1013 void postvisit( const ast::EnumInstType * enumInst ) {
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.