source: src/ResolvExpr/CommonType.cc@ 678c540

ADT ast-experimental
Last change on this file since 678c540 was 5bf3976, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Header Clean-Up: Created new headers for new AST typeops and moved declarations.

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