source: src/ResolvExpr/CommonType.cc @ 9e63a2b

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 9e63a2b was 3a55d9f, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

adjust column spacing in generated output

  • Property mode set to 100644
File size: 60.3 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                ast::ptr< ast::Type > result;
669
670                CommonType_new(
671                        const ast::Type * t2, WidenMode w, const ast::SymbolTable & st,
672                        ast::TypeEnvironment & env, const ast::OpenVarSet & o )
673                : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {}
674
675                void previsit( const ast::Node * ) { visit_children = false; }
676
677                void postvisit( const ast::VoidType * ) {}
678
679                void postvisit( const ast::BasicType * basic ) {
680                        if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
681                                #warning remove casts when `commonTypes` moved to new AST
682                                ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
683                                if (
684                                        ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
685                                                || widen.first )
686                                        && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
687                                                || widen.second )
688                                ) {
689                                        result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
690                                }
691                        } else if (
692                                dynamic_cast< const ast::EnumInstType * >( type2 )
693                                || dynamic_cast< const ast::ZeroType * >( type2 )
694                                || dynamic_cast< const ast::OneType * >( type2 )
695                        ) {
696                                #warning remove casts when `commonTypes` moved to new AST
697                                ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
698                                if (
699                                        ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
700                                                || widen.first )
701                                        && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
702                                                || widen.second )
703                                ) {
704                                        result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
705                                }
706                        }
707                }
708
709        private:
710                template< typename Pointer >
711                void getCommonWithVoidPointer( const Pointer * voidPtr, const Pointer * oPtr ) {
712                        const ast::Type * base = oPtr->base;
713                        if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) {
714                                auto entry = open.find( var->name );
715                                if ( entry != open.end() ) {
716                                        ast::AssertionSet need, have;
717                                        if ( ! tenv.bindVar(
718                                                var, voidPtr->base, entry->second, need, have, open, widen, symtab )
719                                        ) return;
720                                }
721                        }
722                        result = voidPtr;
723                        add_qualifiers( result, oPtr->qualifiers );
724                }
725
726        public:
727                void postvisit( const ast::PointerType * pointer ) {
728                        if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
729                                if (
730                                        widen.first
731                                        && pointer2->base.as< ast::VoidType >()
732                                        && ! ast::isFtype( pointer->base )
733                                ) {
734                                        getCommonWithVoidPointer( pointer2, pointer );
735                                } else if (
736                                        widen.second
737                                        && pointer->base.as< ast::VoidType >()
738                                        && ! ast::isFtype( pointer2->base )
739                                ) {
740                                        getCommonWithVoidPointer( pointer, pointer2 );
741                                } else if (
742                                        ( pointer->base->qualifiers >= pointer2->base->qualifiers || widen.first )
743                                        && ( pointer->base->qualifiers <= pointer2->base->qualifiers || widen.second )
744                                ) {
745                                        ast::CV::Qualifiers q1 = pointer->base->qualifiers;
746                                        ast::CV::Qualifiers q2 = pointer2->base->qualifiers;
747
748                                        // force t{1,2} to be cloned if their qualifiers must be stripped, so that
749                                        // pointer{,2}->base are unchanged
750                                        ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base };
751                                        reset_qualifiers( t1 );
752                                        reset_qualifiers( t2 );
753
754                                        ast::AssertionSet have, need;
755                                        ast::OpenVarSet newOpen{ open };
756                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
757                                                result = pointer;
758                                                if ( q1.val != q2.val ) {
759                                                        // reset result->base->qualifiers to be union of two base qualifiers
760                                                        strict_dynamic_cast< ast::PointerType * >(
761                                                                result.get_and_mutate()
762                                                        )->base.get_and_mutate()->qualifiers = q1 | q2;
763                                                }
764                                        }
765                                }
766                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
767                                result = pointer;
768                                add_qualifiers( result, type2->qualifiers );
769                        }
770                }
771
772                void postvisit( const ast::ArrayType * ) {}
773
774                void postvisit( const ast::ReferenceType * ref ) {
775                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
776                                if (
777                                        widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base )
778                                ) {
779                                        getCommonWithVoidPointer( ref2, ref );
780                                } else if (
781                                        widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base )
782                                ) {
783                                        getCommonWithVoidPointer( ref, ref2 );
784                                } else if (
785                                        ( ref->base->qualifiers >= ref2->base->qualifiers || widen.first )
786                                        && ( ref->base->qualifiers <= ref2->base->qualifiers || widen.second )
787                                ) {
788                                        ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers;
789
790                                        // force t{1,2} to be cloned if their qualifiers must be stripped, so that
791                                        // ref{,2}->base are unchanged
792                                        ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base };
793                                        reset_qualifiers( t1 );
794                                        reset_qualifiers( t2 );
795
796                                        ast::AssertionSet have, need;
797                                        ast::OpenVarSet newOpen{ open };
798                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
799                                                result = ref;
800                                                if ( q1.val != q2.val ) {
801                                                        // reset result->base->qualifiers to be union of two base qualifiers
802                                                        strict_dynamic_cast< ast::ReferenceType * >(
803                                                                result.get_and_mutate()
804                                                        )->base.get_and_mutate()->qualifiers = q1 | q2;
805                                                }
806                                        }
807                                }
808                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
809                                result = ref;
810                                add_qualifiers( result, type2->qualifiers );
811                        }
812                }
813
814                void postvisit( const ast::FunctionType * ) {}
815
816                void postvisit( const ast::StructInstType * ) {}
817
818                void postvisit( const ast::UnionInstType * ) {}
819
820                void postvisit( const ast::EnumInstType * enumInst ) {
821                        if (
822                                dynamic_cast< const ast::BasicType * >( type2 )
823                                || dynamic_cast< const ast::ZeroType * >( type2 )
824                                || dynamic_cast< const ast::OneType * >( type2 )
825                        ) {
826                                // reuse BasicType/EnumInstType common type by swapping
827                                result = commonType( type2, enumInst, widen, symtab, tenv, open );
828                        }
829                }
830
831                void postvisit( const ast::TraitInstType * ) {}
832
833                void postvisit( const ast::TypeInstType * inst ) {
834                        if ( ! widen.first ) return;
835                        if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
836                                if ( const ast::Type * base =
837                                                strict_dynamic_cast< const ast::TypeDecl * >( nt )->base
838                                ) {
839                                        ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers;
840
841                                        // force t{1,2} to be cloned if their qualifiers must be mutated
842                                        ast::ptr< ast::Type > t1{ base }, t2{ type2 };
843                                        reset_qualifiers( t1, q1 );
844                                        reset_qualifiers( t2 );
845
846                                        ast::AssertionSet have, need;
847                                        ast::OpenVarSet newOpen{ open };
848                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
849                                                result = type2;
850                                                reset_qualifiers( result, q1 | q2 );
851                                        }
852                                }
853                        }
854                }
855
856                void postvisit( const ast::TupleType * ) {}
857
858                void postvisit( const ast::VarArgsType * ) {}
859
860                void postvisit( const ast::ZeroType * zero ) {
861                        if ( ! widen.first ) return;
862                        if (
863                                dynamic_cast< const ast::BasicType * >( type2 )
864                                || dynamic_cast< const ast::PointerType * >( type2 )
865                                || dynamic_cast< const ast::EnumInstType * >( type2 )
866                        ) {
867                                if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
868                                        result = type2;
869                                        add_qualifiers( result, zero->qualifiers );
870                                }
871                        } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
872                                result = new ast::BasicType{
873                                        ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers };
874                        }
875                }
876
877                void postvisit( const ast::OneType * one ) {
878                        if ( ! widen.first ) return;
879                        if (
880                                dynamic_cast< const ast::BasicType * >( type2 )
881                                || dynamic_cast< const ast::EnumInstType * >( type2 )
882                        ) {
883                                if ( widen.second || one->qualifiers <= type2->qualifiers ) {
884                                        result = type2;
885                                        add_qualifiers( result, one->qualifiers );
886                                }
887                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
888                                result = new ast::BasicType{
889                                        ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers };
890                        }
891                }
892
893        };
894
895        namespace {
896                ast::ptr< ast::Type > handleReference(
897                        const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
898                        const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
899                        const ast::OpenVarSet & open
900                ) {
901                        ast::ptr<ast::Type> common;
902                        ast::AssertionSet have, need;
903                        ast::OpenVarSet newOpen{ open };
904
905                        // need unify to bind type variables
906                        if ( unify( t1, t2, env, have, need, newOpen, symtab, common ) ) {
907                                ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers;
908                                PRINT(
909                                        std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
910                                )
911                                if ( ( widen.first || q2 <= q1 ) && ( widen.second || q1 <= q2 ) ) {
912                                        PRINT(
913                                                std::cerr << "widen okay" << std::endl;
914                                        )
915                                        add_qualifiers( common, q1 | q2 );
916                                        return common;
917                                }
918                        }
919
920                        PRINT(
921                                std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
922                        )
923                        return { nullptr };
924                }
925        }
926
927        ast::ptr< ast::Type > commonType(
928                        const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
929                        WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
930                        const ast::OpenVarSet & open
931        ) {
932                unsigned depth1 = type1->referenceDepth();
933                unsigned depth2 = type2->referenceDepth();
934
935                if ( depth1 != depth2 ) {  // implies depth1 > 0 || depth2 > 0
936                        PRINT(
937                                std::cerr << "reference depth diff: " << (depth1-depth2) << std::endl;
938                        )
939                        ast::ptr< ast::Type > result;
940                        const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
941                        const ast::ReferenceType * ref2 = type1.as< ast::ReferenceType >();
942
943                        if ( depth1 > depth2 ) {
944                                assert( ref1 );
945                                result = handleReference( ref1->base, type2, widen, symtab, env, open );
946                        } else {  // implies depth1 < depth2
947                                assert( ref2 );
948                                result = handleReference( type1, ref2->base, widen, symtab, env, open );
949                        }
950
951                        if ( result && ref1 ) {
952                                // formal is reference, so result should be reference
953                                PRINT(
954                                        std::cerr << "formal is reference; result should be reference" << std::endl;
955                                )
956                                result = new ast::ReferenceType{ result, ref1->qualifiers };
957                        }
958
959                        PRINT(
960                                std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is "
961                                "[" << result << "]" << std::endl;
962                        )
963                        return result;
964                }
965                // otherwise both are reference types of the same depth and this is handled by the visitor
966                ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open };
967                type1->accept( visitor );
968                ast::ptr< ast::Type > result = visitor.pass.result;
969
970                // handling for opaque type declarations (?)
971                if ( ! result && widen.second ) {
972                        if ( const ast::TypeInstType * inst = type2.as< ast::TypeInstType >() ) {
973                                if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
974                                        auto type = strict_dynamic_cast< const ast::TypeDecl * >( nt );
975                                        if ( type->base ) {
976                                                ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
977                                                ast::AssertionSet have, need;
978                                                ast::OpenVarSet newOpen{ open };
979
980                                                // force t{1,2} to be cloned if its qualifiers must be stripped, so that
981                                                // type1 and type->base are left unchanged; calling convention forces
982                                                // {type1,type->base}->strong_ref >= 1
983                                                ast::ptr<ast::Type> t1{ type1 }, t2{ type->base };
984                                                reset_qualifiers( t1 );
985                                                reset_qualifiers( t2, q1 );
986
987                                                if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) {
988                                                        result = t1;
989                                                        reset_qualifiers( result, q1 | q2 );
990                                                }
991                                        }
992                                }
993                        }
994                }
995
996                return result;
997        }
998
999} // namespace ResolvExpr
1000
1001// Local Variables: //
1002// tab-width: 4 //
1003// mode: c++ //
1004// compile-command: "make install" //
1005// End: //
Note: See TracBrowser for help on using the repository browser.