source: src/ResolvExpr/CommonType.cc@ fe293bf

Last change on this file since fe293bf was 4ac402d, checked in by Andrew Beach <ajbeach@…>, 23 months ago

Added a missing include (not sure how that slipped through) and did some other replacements so the new ast is the source of constants.

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