source: src/ResolvExpr/CommonType.cc @ a5294af

ast-experimental
Last change on this file since a5294af was bccd70a, checked in by Andrew Beach <ajbeach@…>, 14 months ago

Removed internal code from TypeSubstitution? header. It caused a chain of include problems, which have been corrected.

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