source: src/ResolvExpr/CommonType.cc @ 6e2b04e

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since 6e2b04e was fc134a48, checked in by JiadaL <j82liang@…>, 2 years ago

Implement the struct enum

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