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

ADT
Last change on this file since 6ece306 was 5bf3976, checked in by Andrew Beach <ajbeach@…>, 22 months ago

Header Clean-Up: Created new headers for new AST typeops and moved declarations.

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