source: src/ResolvExpr/CommonType.cc @ 8c91088

ADTast-experimental
Last change on this file since 8c91088 was ef1da0e2, checked in by Fangren Yu <f37yu@…>, 20 months ago

try to make parameter qualifier conversion work for assertions

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