source: src/ResolvExpr/CommonType.cpp @ 822332e

Last change on this file since 822332e was 822332e, checked in by Andrew Beach <ajbeach@…>, 8 weeks ago

It seems clang uses different scoping rules for the trailing return of a scoped runction declaration. This form seems compatable with clang and gcc. Since I switched over to clang for testing I also cleaned up all errors that clang or gcc mentioned.

  • Property mode set to 100644
File size: 49.8 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// CommonType.cpp --
8//
9// Author           : Richard C. Bilson
10// Created On       : Sun May 17 06:59:27 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu Feb 14 17:10:10 2019
13// Update Count     : 24
14//
15
16#include "CommonType.hpp"
17
18#include <cassert>                       // for strict_dynamic_cast
19#include <map>                           // for _Rb_tree_const_iterator
20#include <utility>                       // for pair
21
22#include "AST/Decl.hpp"
23#include "AST/Pass.hpp"
24#include "AST/Type.hpp"
25#include "Unify.hpp"                     // for unifyExact, WidenMode
26#include "Typeops.hpp"                   // for isFtype
27#include "Tuples/Tuples.hpp"
28
29// #define DEBUG
30#ifdef DEBUG
31#define PRINT(x) x
32#else
33#define PRINT(x)
34#endif
35
36namespace ResolvExpr {
37
38namespace {
39
40        // GENERATED START, DO NOT EDIT
41        // GENERATED BY BasicTypes-gen.cpp
42        #define BT ast::BasicKind::
43        static const ast::BasicKind commonTypes[BT NUMBER_OF_BASIC_TYPES][BT NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor
44                /*                                      B                       C                      SC                      UC                      SI                     SUI
45                                                        I                      UI                      LI                     LUI                     LLI                    LLUI
46                                                       IB                     UIB                     _FH                     _FH                      _F                     _FC
47                                                        F                      FC                     _FX                    _FXC                      FD                    _FDC
48                                                        D                      DC                    F80X                   _FDXC                     F80                     _FB
49                                                    _FLDC                      FB                      LD                     LDC                    _FBX                  _FLDXC
50                                 */
51                                  {
52                /*      B */                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
53                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
54                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
55                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
56                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
57                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
58                                  },
59                                  {
60                /*      C */                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
61                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
62                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
63                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
64                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
65                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
66                                  },
67                                  {
68                /*     SC */          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
69                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
70                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
71                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
72                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
73                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
74                                  },
75                                  {
76                /*     UC */        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
77                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
78                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
79                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
80                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
81                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
82                                  },
83                                  {
84                /*     SI */      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
85                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
86                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
87                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
88                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
89                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
90                                  },
91                                  {
92                /*    SUI */    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
93                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
94                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
95                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
96                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
97                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
98                                  },
99                                  {
100                /*      I */           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
101                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
102                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
103                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
104                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
105                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
106                                  },
107                                  {
108                /*     UI */         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
109                                           BT UnsignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
110                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
111                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
112                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
113                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
114                                  },
115                                  {
116                /*     LI */       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
117                                         BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
118                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
119                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
120                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
121                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
122                                  },
123                                  {
124                /*    LUI */     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
125                                       BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
126                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
127                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
128                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
129                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
130                                  },
131                                  {
132                /*    LLI */   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
133                                     BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
134                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
135                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
136                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
137                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
138                                  },
139                                  {
140                /*   LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
141                                   BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
142                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
143                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
144                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
145                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
146                                  },
147                                  {
148                /*     IB */        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
149                                          BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
150                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
151                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
152                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
153                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
154                                  },
155                                  {
156                /*    UIB */      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
157                                        BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
158                                        BT UnsignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
159                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
160                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
161                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
162                                  },
163                                  {
164                /*    _FH */            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
165                                              BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
166                                              BT uFloat16,            BT uFloat16,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
167                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
168                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
169                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
170                                  },
171                                  {
172                /*    _FH */     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
173                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
174                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat32Complex,     BT uFloat32Complex,
175                                          BT FloatComplex,        BT FloatComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
176                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
177                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
178                                  },
179                                  {
180                /*     _F */            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
181                                              BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
182                                              BT uFloat32,            BT uFloat32,            BT uFloat32,     BT uFloat32Complex,            BT uFloat32,     BT uFloat32Complex,
183                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
184                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
185                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
186                                  },
187                                  {
188                /*    _FC */     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
189                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
190                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
191                                          BT FloatComplex,        BT FloatComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
192                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
193                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
194                                  },
195                                  {
196                /*      F */               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
197                                                 BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
198                                                 BT Float,               BT Float,               BT Float,        BT FloatComplex,               BT Float,        BT FloatComplex,
199                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
200                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
201                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
202                                  },
203                                  {
204                /*     FC */        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
205                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
206                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
207                                          BT FloatComplex,        BT FloatComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
208                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
209                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
210                                  },
211                                  {
212                /*    _FX */           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
213                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
214                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,    BT uFloat32xComplex,           BT uFloat32x,    BT uFloat32xComplex,
215                                             BT uFloat32x,    BT uFloat32xComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
216                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
217                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
218                                  },
219                                  {
220                /*   _FXC */    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
221                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
222                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
223                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
224                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
225                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
226                                  },
227                                  {
228                /*     FD */            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
229                                              BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
230                                              BT uFloat64,            BT uFloat64,            BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,
231                                              BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,
232                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
233                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
234                                  },
235                                  {
236                /*   _FDC */     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
237                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
238                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
239                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
240                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
241                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
242                                  },
243                                  {
244                /*      D */              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
245                                                BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
246                                                BT Double,              BT Double,              BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,
247                                                BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,
248                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
249                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
250                                  },
251                                  {
252                /*     DC */       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
253                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
254                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
255                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
256                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
257                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
258                                  },
259                                  {
260                /*   F80X */           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
261                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
262                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,
263                                             BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,
264                                             BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
265                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
266                                  },
267                                  {
268                /*  _FDXC */    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
269                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
270                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
271                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
272                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
273                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
274                                  },
275                                  {
276                /*    F80 */           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,
277                                             BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,
278                                             BT uuFloat80,           BT uuFloat80,           BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,
279                                             BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,
280                                             BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
281                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
282                                  },
283                                  {
284                /*    _FB */           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
285                                             BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
286                                             BT uFloat128,           BT uFloat128,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,
287                                             BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,
288                                             BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,           BT uFloat128,
289                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
290                                  },
291                                  {
292                /*  _FLDC */    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
293                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
294                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
295                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
296                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
297                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
298                                  },
299                                  {
300                /*     FB */          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
301                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
302                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,
303                                            BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,
304                                            BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,          BT uuFloat128,
305                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
306                                  },
307                                  {
308                /*     LD */          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
309                                            BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
310                                            BT LongDouble,          BT LongDouble,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,
311                                            BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,
312                                            BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,          BT LongDouble,
313                                     BT LongDoubleComplex,          BT LongDouble,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
314                                  },
315                                  {
316                /*    LDC */   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
317                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
318                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
319                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
320                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
321                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
322                                  },
323                                  {
324                /*   _FBX */          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
325                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
326                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
327                                            BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
328                                            BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,          BT uFloat128x,
329                                     BT uFloat128xComplex,          BT uFloat128x,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
330                                  },
331                                  {
332                /* _FLDXC */   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
333                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
334                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
335                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
336                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
337                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
338                                  },
339        }; // commonTypes
340        #undef BT
341        // GENERATED END
342        static_assert(
343                sizeof(commonTypes)/sizeof(commonTypes[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
344                "Each basic type kind should have a corresponding row in the combined type matrix"
345        );
346
347class CommonType final : public ast::WithShortCircuiting {
348        const ast::Type * type2;
349        WidenMode widen;
350        ast::TypeEnvironment & tenv;
351        const ast::OpenVarSet & open;
352        ast::AssertionSet & need;
353        ast::AssertionSet & have;
354public:
355        ast::ptr< ast::Type > result;
356
357        CommonType(
358                const ast::Type * t2, WidenMode w,
359                ast::TypeEnvironment & env, const ast::OpenVarSet & o,
360                ast::AssertionSet & need, ast::AssertionSet & have )
361        : type2( t2 ), widen( w ), tenv( env ), open( o ), need (need), have (have) ,result() {}
362
363        void previsit( const ast::Node * ) { visit_children = false; }
364
365        void postvisit( const ast::VoidType * ) {}
366
367        void postvisit( const ast::BasicType * basic ) {
368                if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
369                        ast::BasicKind kind;
370                        if (basic->kind != basic2->kind && !widen.first && !widen.second) return;
371                        else if (!widen.first) kind = basic->kind; // widen.second
372                        else if (!widen.second) kind = basic2->kind;
373                        else kind = commonTypes[ basic->kind ][ basic2->kind ];
374                        // xxx - what does qualifiers even do here??
375                        if ( (basic->qualifiers >= basic2->qualifiers || widen.first)
376                                && (basic->qualifiers <= basic2->qualifiers || widen.second) ) {
377                                result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
378                        }
379                } else if (
380                        dynamic_cast< const ast::ZeroType * >( type2 )
381                        || dynamic_cast< const ast::OneType * >( type2 )
382                ) {
383                        if (widen.second) {
384                                result = new ast::BasicType{ basic->kind, basic->qualifiers | type2->qualifiers };
385                        }
386                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
387                        const ast::EnumDecl* enumDecl = enumInst->base;
388                        if ( !enumDecl->base ) {
389                                ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
390                                if (
391                                        ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
392                                                || widen.first )
393                                        && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
394                                                || widen.second )
395                                ) {
396                                        result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
397                                }
398                        }
399                }
400        }
401
402private:
403        template< typename Pointer >
404        void getCommonWithVoidPointer( const Pointer * voidPtr, const Pointer * oPtr ) {
405                const ast::Type * base = oPtr->base;
406                if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) {
407                        auto entry = open.find( *var );
408                        if ( entry != open.end() ) {
409                                ast::AssertionSet need, have;
410                                if ( ! tenv.bindVar(
411                                        var, voidPtr->base, entry->second, need, have, open, widen )
412                                ) return;
413                        }
414                }
415                result = voidPtr;
416                add_qualifiers( result, oPtr->qualifiers );
417        }
418
419public:
420        void postvisit( const ast::PointerType * pointer ) {
421                if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
422                        if (
423                                widen.first
424                                && pointer2->base.as< ast::VoidType >()
425                                && ! ast::isFtype( pointer->base )
426                        ) {
427                                getCommonWithVoidPointer( pointer2, pointer );
428                        } else if (
429                                widen.second
430                                && pointer->base.as< ast::VoidType >()
431                                && ! ast::isFtype( pointer2->base )
432                        ) {
433                                getCommonWithVoidPointer( pointer, pointer2 );
434                        } else if (
435                                ( pointer->base->qualifiers >= pointer2->base->qualifiers || widen.first )
436                                && ( pointer->base->qualifiers <= pointer2->base->qualifiers || widen.second )
437                        ) {
438                                ast::CV::Qualifiers q1 = pointer->base->qualifiers;
439                                ast::CV::Qualifiers q2 = pointer2->base->qualifiers;
440
441                                // force t{1,2} to be cloned if their qualifiers must be stripped, so that
442                                // pointer{,2}->base are unchanged
443                                ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base };
444                                reset_qualifiers( t1 );
445                                reset_qualifiers( t2 );
446
447                                ast::OpenVarSet newOpen{ open };
448                                if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden() ) ) {
449                                        result = pointer;
450                                        if ( q1.val != q2.val ) {
451                                                // reset result->base->qualifiers to be union of two base qualifiers
452                                                strict_dynamic_cast< ast::PointerType * >(
453                                                        result.get_and_mutate()
454                                                )->base.get_and_mutate()->qualifiers = q1 | q2;
455                                        }
456                                } else if ( isFtype (t1) && isFtype (t2) ) {
457                                        auto f1 = t1.as<ast::FunctionType>();
458                                        if (!f1) return;
459                                        auto f2 = t2.strict_as<ast::FunctionType>();
460
461                                        assertf(f1->returns.size() <= 1, "Function return should not be a list");
462                                        assertf(f2->returns.size() <= 1, "Function return should not be a list");
463
464                                        if (
465                                                ( f1->params.size() != f2->params.size() || f1->returns.size() != f2->returns.size() )
466                                                && ! f1->isTtype()
467                                                && ! f2->isTtype()
468                                        ) return;
469
470                                        auto params1 = flattenList( f1->params, tenv );
471                                        auto params2 = flattenList( f2->params, tenv );
472
473                                        auto crnt1 = params1.begin();
474                                        auto crnt2 = params2.begin();
475                                        auto end1 = params1.end();
476                                        auto end2 = params2.end();
477
478                                        while (crnt1 != end1 && crnt2 != end2 ) {
479                                                const ast::Type * arg1 = *crnt1;
480                                                const ast::Type * arg2 = *crnt2;
481
482                                                bool isTuple1 = Tuples::isTtype( t1 );
483                                                bool isTuple2 = Tuples::isTtype( t2 );
484
485                                                // assumes here that ttype *must* be last parameter
486                                                if ( isTuple1 && ! isTuple2 ) {
487                                                        // combine remainder of list2, then unify
488                                                        if (unifyExact(
489                                                                arg1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open,
490                                                                noWiden() )) {
491                                                                        break;
492                                                        } else return;
493                                                } else if ( ! isTuple1 && isTuple2 ) {
494                                                        // combine remainder of list1, then unify
495                                                        if (unifyExact(
496                                                                tupleFromTypes( crnt1, end1 ), arg2, tenv, need, have, open,
497                                                                noWiden() )) {
498                                                                        break;
499                                                        } else return;
500                                                }
501
502                                                // allow qualifiers of pointer and reference base to become more specific
503                                                if (auto ref1 = dynamic_cast<const ast::ReferenceType *> (arg1)) {
504                                                        if (auto ref2 = dynamic_cast<const ast::ReferenceType *> (arg2)) {
505                                                                ast::ptr<ast::Type> base1 = ref1->base;
506                                                                ast::ptr<ast::Type> base2 = ref2->base;
507
508                                                                // xxx - assume LHS is always the target type
509
510                                                                if ( ! ((widen.second && ref2->qualifiers.is_mutex)
511                                                                || (ref1->qualifiers.is_mutex == ref2->qualifiers.is_mutex ))) return;
512
513                                                                if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) {
514
515                                                                        reset_qualifiers(base1);
516                                                                        reset_qualifiers(base2);
517
518                                                                        if ( !unifyExact(
519                                                                                base1, base2, tenv, need, have, open, noWiden() )
520                                                                        ) return;
521                                                                }
522                                                        } else return;
523                                                } else if (auto ptr1 = dynamic_cast<const ast::PointerType *> (arg1)) {
524                                                        if (auto ptr2 = dynamic_cast<const ast::PointerType *> (arg2)) {
525                                                                ast::ptr<ast::Type> base1 = ptr1->base;
526                                                                ast::ptr<ast::Type> base2 = ptr2->base;
527
528                                                                // xxx - assume LHS is always the target type
529                                                                // a function accepting const can always be called by non-const arg
530
531                                                                if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) {
532
533                                                                        reset_qualifiers(base1);
534                                                                        reset_qualifiers(base2);
535
536                                                                        if ( ! unifyExact(
537                                                                                base1, base2, tenv, need, have, open, noWiden() )
538                                                                        ) return;
539                                                                }
540                                                        } else return;
541                                                } else if (! unifyExact(
542                                                                arg1, arg2, tenv, need, have, open, noWiden() )) {
543                                                        return;
544                                                }
545                                                ++crnt1; ++crnt2;
546                                        }
547                                        if ( crnt1 != end1 ) {
548                                                // try unifying empty tuple with ttype
549                                                const ast::Type * t1 = *crnt1;
550                                                if (! Tuples::isTtype( t1 ) ) return;
551                                                if (! unifyExact(
552                                                        t1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open,
553                                                        noWiden() )) return;
554                                        } else if ( crnt2 != end2 ) {
555                                                // try unifying empty tuple with ttype
556                                                const ast::Type * t2 = *crnt2;
557                                                if ( !Tuples::isTtype( t2 ) ) return;
558                                                if ( !unifyExact(
559                                                        tupleFromTypes( crnt1, end1 ), t2, tenv, need, have, open,
560                                                        noWiden() )) return;
561                                        }
562                                        if ((f1->returns.size() == 0 && f2->returns.size() == 0)
563                                          || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden()))) {
564                                                result = pointer;
565
566                                                for (auto & assn : f1->assertions) {
567                                                        auto i = need.find(assn);
568                                                        if (i != need.end()) i->second.isUsed = true;
569                                                        auto j = have.find(assn);
570                                                        if (j != have.end()) j->second.isUsed = true;
571                                                }
572
573                                                for (auto & assn : f2->assertions) {
574                                                        auto i = need.find(assn);
575                                                        if (i != need.end()) i->second.isUsed = true;
576                                                        auto j = have.find(assn);
577                                                        if (j != have.end()) j->second.isUsed = true;
578                                                }
579                                        }
580                                } // if ftype
581                        }
582                } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
583                        result = pointer;
584                        add_qualifiers( result, type2->qualifiers );
585                }
586        }
587
588        void postvisit( const ast::ArrayType * ) {}
589
590        void postvisit( const ast::ReferenceType * ref ) {
591                if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
592                        if (
593                                widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base )
594                        ) {
595                                getCommonWithVoidPointer( ref2, ref );
596                        } else if (
597                                widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base )
598                        ) {
599                                getCommonWithVoidPointer( ref, ref2 );
600                        } else if (
601                                ( ref->base->qualifiers >= ref2->base->qualifiers || widen.first )
602                                && ( ref->base->qualifiers <= ref2->base->qualifiers || widen.second )
603                        ) {
604                                ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers;
605
606                                // force t{1,2} to be cloned if their qualifiers must be stripped, so that
607                                // ref{,2}->base are unchanged
608                                ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base };
609                                reset_qualifiers( t1 );
610                                reset_qualifiers( t2 );
611
612                                ast::OpenVarSet newOpen{ open };
613                                if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden() ) ) {
614                                        result = ref;
615                                        if ( q1.val != q2.val ) {
616                                                // reset result->base->qualifiers to be union of two base qualifiers
617                                                strict_dynamic_cast< ast::ReferenceType * >(
618                                                        result.get_and_mutate()
619                                                )->base.get_and_mutate()->qualifiers = q1 | q2;
620                                        }
621                                }
622                        }
623                } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
624                        result = ref;
625                        add_qualifiers( result, type2->qualifiers );
626                } else {
627                        if (!dynamic_cast<const ast::EnumInstType *>(type2))
628                                result = commonType( type2, ref, tenv, need, have, open, widen );
629                }
630        }
631
632        void postvisit( const ast::FunctionType * ) {}
633
634        void postvisit( const ast::StructInstType * ) {}
635
636        void postvisit( const ast::UnionInstType * ) {}
637
638        void postvisit( const ast::EnumInstType * enumInst ) {
639                if ( enumInst->base && !enumInst->base->isTyped ) {
640                        auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
641                        result = commonType( basicType, type2, tenv, need, have, open, widen);
642                }
643        }
644
645        void postvisit( const ast::TraitInstType * ) {}
646
647        void postvisit( const ast::TypeInstType * ) {}
648
649        void postvisit( const ast::TupleType * ) {}
650
651        void postvisit( const ast::VarArgsType * ) {}
652
653        void postvisit( const ast::ZeroType * zero ) {
654                if ( !widen.first ) return;
655                if ( dynamic_cast< const ast::BasicType * >( type2 )
656                                || dynamic_cast< const ast::PointerType * >( type2 ) ) {
657                        if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
658                                result = type2;
659                                add_qualifiers( result, zero->qualifiers );
660                        }
661                } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
662                        result = new ast::BasicType{
663                                ast::BasicKind::SignedInt, zero->qualifiers | type2->qualifiers };
664                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
665                        const ast::EnumDecl * enumDecl = enumInst->base;
666                        if ( !enumDecl->base ) {
667                                if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
668                                        result = type2;
669                                        add_qualifiers( result, zero->qualifiers );
670                                }
671                        }
672                }
673        }
674
675        void postvisit( const ast::OneType * one ) {
676                if ( !widen.first ) return;
677                if ( dynamic_cast< const ast::BasicType * >( type2 ) ) {
678                        if ( widen.second || one->qualifiers <= type2->qualifiers ) {
679                                result = type2;
680                                add_qualifiers( result, one->qualifiers );
681                        }
682                } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
683                        result = new ast::BasicType{
684                                ast::BasicKind::SignedInt, one->qualifiers | type2->qualifiers };
685                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
686                        const ast::EnumDecl * enumDecl = enumInst->base;
687                        if ( !enumDecl->base ) {
688                                if ( widen.second || one->qualifiers <= type2->qualifiers ) {
689                                        result = type2;
690                                        add_qualifiers( result, one->qualifiers );
691                                }
692                        }
693                }
694        }
695};
696
697// size_t CommonType::traceId = Stats::Heap::new_stacktrace_id("CommonType");
698
699ast::ptr< ast::Type > handleReference(
700        const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
701        ast::TypeEnvironment & env,
702        const ast::OpenVarSet & open
703) {
704        ast::ptr<ast::Type> common;
705        ast::AssertionSet have, need;
706        ast::OpenVarSet newOpen( open );
707
708        // need unify to bind type variables
709        if ( unify( t1, t2, env, have, need, newOpen, common ) ) {
710                ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers;
711                PRINT(
712                        std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
713                )
714                if ( ( widen.first || q2 <= q1 ) && ( widen.second || q1 <= q2 ) ) {
715                        PRINT(
716                                std::cerr << "widen okay" << std::endl;
717                        )
718                        add_qualifiers( common, q1 | q2 );
719                        return common;
720                }
721        }
722
723        PRINT(
724                std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
725        )
726        return { nullptr };
727}
728
729} // namespace
730
731ast::ptr< ast::Type > commonType(
732        const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
733        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
734        const ast::OpenVarSet & open, WidenMode widen
735) {
736        unsigned depth1 = type1->referenceDepth();
737        unsigned depth2 = type2->referenceDepth();
738
739        if ( depth1 != depth2 ) {  // implies depth1 > 0 || depth2 > 0
740                PRINT(
741                        std::cerr << "reference depth diff: " << (depth1-depth2) << std::endl;
742                )
743                ast::ptr< ast::Type > result;
744                const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
745                const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >();
746
747                if ( depth1 > depth2 ) {
748                        assert( ref1 );
749                        result = handleReference( ref1->base, type2, widen, env, open );
750                } else {  // Implies depth1 < depth2
751                        assert( ref2 );
752                        result = handleReference( type1, ref2->base, widen, env, open );
753                }
754
755                if ( result && ref1 ) {
756                        // formal is reference, so result should be reference
757                        PRINT(
758                                std::cerr << "formal is reference; result should be reference" << std::endl;
759                        )
760                        result = new ast::ReferenceType{ result, ref1->qualifiers };
761                }
762
763                PRINT(
764                        std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is "
765                        "[" << result << "]" << std::endl;
766                )
767                return result;
768        }
769        // otherwise both are reference types of the same depth and this is handled by the visitor
770        return ast::Pass<CommonType>::read( type1.get(),
771                type2, widen, env, open, need, have );
772}
773
774} // namespace ResolvExpr
775
776// Local Variables: //
777// tab-width: 4 //
778// mode: c++ //
779// compile-command: "make install" //
780// End: //
Note: See TracBrowser for help on using the repository browser.