source: src/ResolvExpr/CommonType.cc @ a757ba1

ADTast-experimental
Last change on this file since a757ba1 was e874605, checked in by JiadaL <j82liang@…>, 2 years ago

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

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