source: src/ResolvExpr/CommonType.cc @ 46da46b

ast-experimental
Last change on this file since 46da46b was 46da46b, checked in by Fangren Yu <f37yu@…>, 13 months ago

current progress

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