source: src/ResolvExpr/CommonType.cc @ a0bd9a2

Last change on this file since a0bd9a2 was 918e4165, checked in by Andrew Beach <ajbeach@…>, 12 months ago

Removed some warnings.

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