source: src/ResolvExpr/CommonType.cc @ a22d148

Last change on this file since a22d148 was 2908f08, checked in by Andrew Beach <ajbeach@…>, 12 months ago

Most of ResolvExpr? was written before the new style standard. Some files updated, focus on headers.

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