source: src/ResolvExpr/CommonType.cc @ e37db112

ADTast-experimentalenumforall-pointer-decayjacob/cs343-translationpthread-emulationqualifiedEnum
Last change on this file since e37db112 was 3e5dd913, checked in by Fangren Yu <f37yu@…>, 4 years ago

reimplement function type and eliminate deep copy

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