source: src/ResolvExpr/CommonType.cc @ 7d55e4d

Last change on this file since 7d55e4d was 7d55e4d, checked in by Andrew Beach <ajbeach@…>, 8 months ago

Simple rework to BasicTypes?-gen.cc to avoid refering to the old ast. No larger rework at this time.

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