source: src/ResolvExpr/CommonType.cpp @ 508cff0

Last change on this file since 508cff0 was 5ccc733, checked in by JiadaL <j82liang@…>, 5 months ago

Fix the bug that C style enum cannot to use as an lvalue

  • Property mode set to 100644
File size: 50.1 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->isCfa  ) {
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 * param ) {
639                auto argAsEnumInst = dynamic_cast<const ast::EnumInstType *>(type2);
640                if ( argAsEnumInst ) {
641                        const ast::EnumDecl* paramDecl = param->base;
642                        const ast::EnumDecl* argDecl = argAsEnumInst->base;
643                        if (argDecl->isSubTypeOf(paramDecl)) result = param;
644                } else if ( param->base && !param->base->isCfa ) {
645                        auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
646                        result = commonType( basicType, type2, tenv, need, have, open, widen);
647                }
648        }
649
650        void postvisit( const ast::TraitInstType * ) {}
651
652        void postvisit( const ast::TypeInstType * ) {}
653
654        void postvisit( const ast::TupleType * ) {}
655
656        void postvisit( const ast::VarArgsType * ) {}
657
658        void postvisit( const ast::ZeroType * zero ) {
659                if ( !widen.first ) return;
660                if ( dynamic_cast< const ast::BasicType * >( type2 )
661                                || dynamic_cast< const ast::PointerType * >( type2 ) ) {
662                        if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
663                                result = type2;
664                                add_qualifiers( result, zero->qualifiers );
665                        }
666                } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
667                        result = new ast::BasicType{
668                                ast::BasicKind::SignedInt, zero->qualifiers | type2->qualifiers };
669                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
670                        const ast::EnumDecl * enumDecl = enumInst->base;
671                        if ( !enumDecl->base ) {
672                                if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
673                                        result = type2;
674                                        add_qualifiers( result, zero->qualifiers );
675                                }
676                        }
677                }
678        }
679
680        void postvisit( const ast::OneType * one ) {
681                if ( !widen.first ) return;
682                if ( dynamic_cast< const ast::BasicType * >( type2 ) ) {
683                        if ( widen.second || one->qualifiers <= type2->qualifiers ) {
684                                result = type2;
685                                add_qualifiers( result, one->qualifiers );
686                        }
687                } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
688                        result = new ast::BasicType{
689                                ast::BasicKind::SignedInt, one->qualifiers | type2->qualifiers };
690                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
691                        const ast::EnumDecl * enumDecl = enumInst->base;
692                        if ( !enumDecl->base ) {
693                                if ( widen.second || one->qualifiers <= type2->qualifiers ) {
694                                        result = type2;
695                                        add_qualifiers( result, one->qualifiers );
696                                }
697                        }
698                }
699        }
700};
701
702// size_t CommonType::traceId = Stats::Heap::new_stacktrace_id("CommonType");
703
704ast::ptr< ast::Type > handleReference(
705        const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
706        ast::TypeEnvironment & env,
707        const ast::OpenVarSet & open
708) {
709        ast::ptr<ast::Type> common;
710        ast::AssertionSet have, need;
711        ast::OpenVarSet newOpen( open );
712
713        // need unify to bind type variables
714        if ( unify( t1, t2, env, have, need, newOpen, common ) ) {
715                ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers;
716                PRINT(
717                        std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
718                )
719                if ( ( widen.first || q2 <= q1 ) && ( widen.second || q1 <= q2 ) ) {
720                        PRINT(
721                                std::cerr << "widen okay" << std::endl;
722                        )
723                        add_qualifiers( common, q1 | q2 );
724                        return common;
725                }
726        }
727
728        PRINT(
729                std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
730        )
731        return { nullptr };
732}
733
734} // namespace
735
736ast::ptr< ast::Type > commonType(
737        const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
738        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
739        const ast::OpenVarSet & open, WidenMode widen
740) {
741        unsigned depth1 = type1->referenceDepth();
742        unsigned depth2 = type2->referenceDepth();
743
744        if ( depth1 != depth2 ) {  // implies depth1 > 0 || depth2 > 0
745                PRINT(
746                        std::cerr << "reference depth diff: " << (depth1-depth2) << std::endl;
747                )
748                ast::ptr< ast::Type > result;
749                const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
750                const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >();
751
752                if ( depth1 > depth2 ) {
753                        assert( ref1 );
754                        result = handleReference( ref1->base, type2, widen, env, open );
755                } else {  // Implies depth1 < depth2
756                        assert( ref2 );
757                        result = handleReference( type1, ref2->base, widen, env, open );
758                }
759
760                if ( result && ref1 ) {
761                        // formal is reference, so result should be reference
762                        PRINT(
763                                std::cerr << "formal is reference; result should be reference" << std::endl;
764                        )
765                        result = new ast::ReferenceType{ result, ref1->qualifiers };
766                }
767
768                PRINT(
769                        std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is "
770                        "[" << result << "]" << std::endl;
771                )
772                return result;
773        }
774        // otherwise both are reference types of the same depth and this is handled by the visitor
775        return ast::Pass<CommonType>::read( type1.get(),
776                type2, widen, env, open, need, have );
777}
778
779} // namespace ResolvExpr
780
781// Local Variables: //
782// tab-width: 4 //
783// mode: c++ //
784// compile-command: "make install" //
785// End: //
Note: See TracBrowser for help on using the repository browser.