@@ -123,13 +123,60 @@ bool TuplePackMatcher::match() {
123
123
return false ;
124
124
}
125
125
126
- ParamPackMatcher::ParamPackMatcher (
127
- ArrayRef<AnyFunctionType::Param> lhsParams,
128
- ArrayRef<AnyFunctionType::Param> rhsParams,
129
- ASTContext &ctx)
130
- : lhsParams(lhsParams), rhsParams(rhsParams), ctx(ctx) {}
126
+ TypeListPackMatcher::Element
127
+ TypeListPackMatcher::Element::from (const TupleTypeElt &elt) {
128
+ return {elt.getName (), elt.getType ()};
129
+ }
130
+
131
+ TypeListPackMatcher::Element
132
+ TypeListPackMatcher::Element::from (const AnyFunctionType::Param ¶m) {
133
+ return {param.getLabel (), param.getPlainType (), param.getParameterFlags ()};
134
+ }
135
+
136
+ TypeListPackMatcher::Element TypeListPackMatcher::Element::from (Type type) {
137
+ return {/* label=*/ Identifier (), type};
138
+ }
139
+
140
+ TypeListPackMatcher::TypeListPackMatcher (ASTContext &ctx,
141
+ ArrayRef<TupleTypeElt> lhsParams,
142
+ ArrayRef<TupleTypeElt> rhsParams)
143
+ : ctx(ctx) {
144
+ llvm::transform (lhsParams, std::back_inserter (lhsElements),
145
+ [&](const auto &elt) { return Element::from (elt); });
146
+ llvm::transform (rhsParams, std::back_inserter (rhsElements),
147
+ [&](const auto &elt) { return Element::from (elt); });
148
+ }
149
+
150
+ TypeListPackMatcher::TypeListPackMatcher (
151
+ ASTContext &ctx, ArrayRef<AnyFunctionType::Param> lhsParams,
152
+ ArrayRef<AnyFunctionType::Param> rhsParams)
153
+ : ctx(ctx) {
154
+ llvm::transform (lhsParams, std::back_inserter (lhsElements),
155
+ [&](const auto &elt) {
156
+ assert (!elt.hasLabel ());
157
+ return Element::from (elt);
158
+ });
159
+ llvm::transform (rhsParams, std::back_inserter (rhsElements),
160
+ [&](const auto &elt) {
161
+ assert (!elt.hasLabel ());
162
+ return Element::from (elt);
163
+ });
164
+ }
165
+
166
+ TypeListPackMatcher::TypeListPackMatcher (ASTContext &ctx,
167
+ ArrayRef<Type> lhsParams,
168
+ ArrayRef<Type> rhsParams)
169
+ : ctx(ctx) {
170
+ llvm::transform (lhsParams, std::back_inserter (lhsElements),
171
+ [&](const auto &elt) { return Element::from (elt); });
172
+ llvm::transform (rhsParams, std::back_inserter (rhsElements),
173
+ [&](const auto &elt) { return Element::from (elt); });
174
+ }
175
+
176
+ bool TypeListPackMatcher::match () {
177
+ ArrayRef<Element> lhsParams (lhsElements);
178
+ ArrayRef<Element> rhsParams (rhsElements);
131
179
132
- bool ParamPackMatcher::match () {
133
180
unsigned minLength = std::min (lhsParams.size (), rhsParams.size ());
134
181
135
182
// Consume the longest possible prefix where neither type in
@@ -147,8 +194,8 @@ bool ParamPackMatcher::match() {
147
194
148
195
// FIXME: Check flags
149
196
150
- auto lhsType = lhsParam.getPlainType ();
151
- auto rhsType = rhsParam.getPlainType ();
197
+ auto lhsType = lhsParam.getType ();
198
+ auto rhsType = rhsParam.getType ();
152
199
153
200
if (lhsType->is <PackExpansionType>() ||
154
201
rhsType->is <PackExpansionType>()) {
@@ -176,8 +223,8 @@ bool ParamPackMatcher::match() {
176
223
if (lhsParam.getLabel () != rhsParam.getLabel ())
177
224
break ;
178
225
179
- auto lhsType = lhsParam.getPlainType ();
180
- auto rhsType = rhsParam.getPlainType ();
226
+ auto lhsType = lhsParam.getType ();
227
+ auto rhsType = rhsParam.getType ();
181
228
182
229
if (lhsType->is <PackExpansionType>() ||
183
230
rhsType->is <PackExpansionType>()) {
@@ -202,7 +249,7 @@ bool ParamPackMatcher::match() {
202
249
// If the left hand side is a single pack expansion type, bind it
203
250
// to what remains of the right hand side.
204
251
if (lhsParams.size () == 1 ) {
205
- auto lhsType = lhsParams[0 ].getPlainType ();
252
+ auto lhsType = lhsParams[0 ].getType ();
206
253
if (auto *lhsExpansion = lhsType->getAs <PackExpansionType>()) {
207
254
unsigned lhsIdx = prefixLength;
208
255
unsigned rhsIdx = prefixLength;
@@ -213,7 +260,7 @@ bool ParamPackMatcher::match() {
213
260
return true ;
214
261
215
262
// FIXME: Check rhs flags
216
- rhsTypes.push_back (rhsParam.getPlainType ());
263
+ rhsTypes.push_back (rhsParam.getType ());
217
264
}
218
265
auto rhs = createPackBinding (ctx, rhsTypes);
219
266
@@ -226,7 +273,7 @@ bool ParamPackMatcher::match() {
226
273
// If the right hand side is a single pack expansion type, bind it
227
274
// to what remains of the left hand side.
228
275
if (rhsParams.size () == 1 ) {
229
- auto rhsType = rhsParams[0 ].getPlainType ();
276
+ auto rhsType = rhsParams[0 ].getType ();
230
277
if (auto *rhsExpansion = rhsType->getAs <PackExpansionType>()) {
231
278
unsigned lhsIdx = prefixLength;
232
279
unsigned rhsIdx = prefixLength;
@@ -237,7 +284,7 @@ bool ParamPackMatcher::match() {
237
284
return true ;
238
285
239
286
// FIXME: Check lhs flags
240
- lhsTypes.push_back (lhsParam.getPlainType ());
287
+ lhsTypes.push_back (lhsParam.getType ());
241
288
}
242
289
auto lhs = createPackBinding (ctx, lhsTypes);
243
290
@@ -255,100 +302,3 @@ bool ParamPackMatcher::match() {
255
302
// like {T..., Int} vs {Float, U...}.
256
303
return true ;
257
304
}
258
-
259
- PackMatcher::PackMatcher (
260
- ArrayRef<Type> lhsTypes,
261
- ArrayRef<Type> rhsTypes,
262
- ASTContext &ctx)
263
- : lhsTypes(lhsTypes), rhsTypes(rhsTypes), ctx(ctx) {}
264
-
265
- bool PackMatcher::match () {
266
- unsigned minLength = std::min (lhsTypes.size (), rhsTypes.size ());
267
-
268
- // Consume the longest possible prefix where neither type in
269
- // the pair is a pack expansion type.
270
- unsigned prefixLength = 0 ;
271
- for (unsigned i = 0 ; i < minLength; ++i) {
272
- unsigned lhsIdx = i;
273
- unsigned rhsIdx = i;
274
-
275
- auto lhsType = lhsTypes[lhsIdx];
276
- auto rhsType = rhsTypes[rhsIdx];
277
-
278
- if (lhsType->is <PackExpansionType>() ||
279
- rhsType->is <PackExpansionType>()) {
280
- break ;
281
- }
282
-
283
- pairs.emplace_back (lhsType, rhsType, lhsIdx, rhsIdx);
284
- ++prefixLength;
285
- }
286
-
287
- // Consume the longest possible suffix where neither type in
288
- // the pair is a pack expansion type.
289
- unsigned suffixLength = 0 ;
290
- for (unsigned i = 0 ; i < minLength - prefixLength; ++i) {
291
- unsigned lhsIdx = lhsTypes.size () - i - 1 ;
292
- unsigned rhsIdx = rhsTypes.size () - i - 1 ;
293
-
294
- auto lhsType = lhsTypes[lhsIdx];
295
- auto rhsType = rhsTypes[rhsIdx];
296
-
297
- if (lhsType->is <PackExpansionType>() ||
298
- rhsType->is <PackExpansionType>()) {
299
- break ;
300
- }
301
-
302
- pairs.emplace_back (lhsType, rhsType, lhsIdx, rhsIdx);
303
- ++suffixLength;
304
- }
305
-
306
- assert (prefixLength + suffixLength <= lhsTypes.size ());
307
- assert (prefixLength + suffixLength <= rhsTypes.size ());
308
-
309
- // Drop the consumed prefix and suffix from each list of types.
310
- lhsTypes = lhsTypes.drop_front (prefixLength).drop_back (suffixLength);
311
- rhsTypes = rhsTypes.drop_front (prefixLength).drop_back (suffixLength);
312
-
313
- // If nothing remains, we're done.
314
- if (lhsTypes.empty () && rhsTypes.empty ())
315
- return false ;
316
-
317
- // If the left hand side is a single pack expansion type, bind it
318
- // to what remains of the right hand side.
319
- if (lhsTypes.size () == 1 ) {
320
- auto lhsType = lhsTypes[0 ];
321
- if (auto *lhsExpansion = lhsType->getAs <PackExpansionType>()) {
322
- unsigned lhsIdx = prefixLength;
323
- unsigned rhsIdx = prefixLength;
324
-
325
- auto rhs = createPackBinding (ctx, rhsTypes);
326
-
327
- pairs.emplace_back (lhsExpansion, rhs, lhsIdx, rhsIdx);
328
- return false ;
329
- }
330
- }
331
-
332
- // If the right hand side is a single pack expansion type, bind it
333
- // to what remains of the left hand side.
334
- if (rhsTypes.size () == 1 ) {
335
- auto rhsType = rhsTypes[0 ];
336
- if (auto *rhsExpansion = rhsType->getAs <PackExpansionType>()) {
337
- unsigned lhsIdx = prefixLength;
338
- unsigned rhsIdx = prefixLength;
339
-
340
- auto lhs = createPackBinding (ctx, lhsTypes);
341
-
342
- pairs.emplace_back (lhs, rhsExpansion, lhsIdx, rhsIdx);
343
- return false ;
344
- }
345
- }
346
-
347
- // Otherwise, all remaining possibilities are invalid:
348
- // - Neither side has any pack expansions, and they have different lengths.
349
- // - One side has a pack expansion but the other side is too short, eg
350
- // {Int, T..., Float} vs {Int}.
351
- // - The prefix and suffix are mismatched, so we're left with something
352
- // like {T..., Int} vs {Float, U...}.
353
- return true ;
354
- }
0 commit comments