source: src/ResolvExpr/CommonType.cc@ be1d00c

ADT ast-experimental
Last change on this file since be1d00c was e874605, checked in by JiadaL <j82liang@…>, 3 years ago

Add class InlineValueDecl, which is a Declaration class that works as a placeholder for aggregration value inherited from other aggregration. Disable inline value overwrite.

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