@@ -1288,22 +1288,79 @@ class NameAliasType : public TypeBase {
1288
1288
}
1289
1289
};
1290
1290
1291
+ // TODO: As part of AST modernization, replace with a proper
1292
+ // 'ParameterTypeElt' or similar, and have FunctionTypes only have a list
1293
+ // of 'ParameterTypeElt's. Then, this information can be removed from
1294
+ // TupleTypeElt.
1295
+ //
1296
+ // / Provide parameter type relevant flags, i.e. variadic, autoclosure, and
1297
+ // / escaping.
1298
+ class ParameterTypeFlags {
1299
+ enum ParameterFlags : uint8_t {
1300
+ None = 0 ,
1301
+ Variadic = 1 << 0 ,
1302
+ AutoClosure = 1 << 1 ,
1303
+ Escaping = 1 << 2 ,
1304
+
1305
+ NumBits = 3
1306
+ };
1307
+ OptionSet<ParameterFlags> value;
1308
+ static_assert (NumBits < 8 *sizeof (value), " overflowed" );
1309
+
1310
+ ParameterTypeFlags (OptionSet<ParameterFlags, uint8_t > val) : value(val) {}
1311
+
1312
+ public:
1313
+ ParameterTypeFlags () = default ;
1314
+
1315
+ ParameterTypeFlags (bool variadic, bool autoclosure, bool escaping)
1316
+ : value((variadic ? Variadic : 0 ) |
1317
+ (autoclosure ? AutoClosure : 0 ) |
1318
+ (escaping ? Escaping : 0 )) {}
1319
+
1320
+ // / Create one from what's present in the parameter type
1321
+ inline static ParameterTypeFlags fromParameterType (Type paramTy,
1322
+ bool isVariadic);
1323
+
1324
+ bool isNone () const { return !value; }
1325
+ bool isVariadic () const { return value.contains (Variadic); }
1326
+ bool isAutoClosure () const { return value.contains (AutoClosure); }
1327
+ bool isEscaping () const { return value.contains (Escaping); }
1328
+
1329
+ ParameterTypeFlags withEscaping (bool escaping) const {
1330
+ return ParameterTypeFlags (escaping ? value | ParameterTypeFlags::Escaping
1331
+ : value - ParameterTypeFlags::Escaping);
1332
+ }
1333
+
1334
+ bool operator ==(const ParameterTypeFlags &other) const {
1335
+ return value.toRaw () == other.value .toRaw ();
1336
+ }
1337
+
1338
+ uint8_t toRaw () const { return value.toRaw (); }
1339
+ };
1340
+
1291
1341
// / ParenType - A paren type is a type that's been written in parentheses.
1292
1342
class ParenType : public TypeBase {
1293
1343
Type UnderlyingType;
1344
+ ParameterTypeFlags parameterFlags;
1294
1345
1295
1346
friend class ASTContext ;
1296
- ParenType (Type UnderlyingType, RecursiveTypeProperties properties)
1297
- : TypeBase(TypeKind::Paren, nullptr , properties),
1298
- UnderlyingType (UnderlyingType) {}
1347
+ ParenType (Type UnderlyingType, RecursiveTypeProperties properties,
1348
+ ParameterTypeFlags flags)
1349
+ : TypeBase(TypeKind::Paren, nullptr , properties),
1350
+ UnderlyingType (UnderlyingType), parameterFlags(flags) {}
1351
+
1299
1352
public:
1300
1353
Type getUnderlyingType () const { return UnderlyingType; }
1301
1354
1302
- static ParenType *get (const ASTContext &C, Type underlying);
1303
-
1355
+ static ParenType *get (const ASTContext &C, Type underlying,
1356
+ ParameterTypeFlags flags = {});
1357
+
1304
1358
// / Remove one level of top-level sugar from this type.
1305
1359
TypeBase *getSinglyDesugaredType ();
1306
1360
1361
+ // / Get the parameter flags
1362
+ ParameterTypeFlags getParameterFlags () const { return parameterFlags; }
1363
+
1307
1364
// Implement isa/cast/dyncast/etc.
1308
1365
static bool classof (const TypeBase *T) {
1309
1366
return T->getKind () == TypeKind::Paren;
@@ -1312,33 +1369,45 @@ class ParenType : public TypeBase {
1312
1369
1313
1370
// / TupleTypeElt - This represents a single element of a tuple.
1314
1371
class TupleTypeElt {
1315
- // / An optional name for the field, along with a bit indicating whether it
1316
- // / is variadic.
1317
- llvm::PointerIntPair<Identifier, 1 , bool > NameAndVariadic;
1372
+ // / An optional name for the field.
1373
+ Identifier Name;
1318
1374
1319
1375
// / \brief This is the type of the field.
1320
1376
Type ElementType;
1321
1377
1378
+ // / Flags that are specific to and relevant for parameter types
1379
+ ParameterTypeFlags Flags;
1380
+
1322
1381
friend class TupleType ;
1323
1382
1324
1383
public:
1325
1384
TupleTypeElt () = default ;
1326
- inline /* implicit*/ TupleTypeElt(Type ty,
1327
- Identifier name = Identifier(),
1328
- bool isVariadic = false );
1385
+ inline /* implicit*/ TupleTypeElt(Type ty, Identifier name,
1386
+ bool isVariadic, bool isAutoClosure,
1387
+ bool isEscaping);
1388
+
1389
+ TupleTypeElt (Type ty, Identifier name = Identifier(),
1390
+ ParameterTypeFlags PTFlags = {})
1391
+ : Name(name), ElementType(ty), Flags(PTFlags) {}
1329
1392
1330
1393
/* implicit*/ TupleTypeElt(TypeBase *Ty)
1331
- : NameAndVariadic (Identifier(), false ), ElementType(Ty) { }
1394
+ : Name (Identifier()), ElementType(Ty), Flags( ) { }
1332
1395
1333
- bool hasName () const { return !NameAndVariadic. getPointer () .empty (); }
1334
- Identifier getName () const { return NameAndVariadic. getPointer () ; }
1396
+ bool hasName () const { return !Name .empty (); }
1397
+ Identifier getName () const { return Name ; }
1335
1398
1336
1399
Type getType () const { return ElementType.getPointer (); }
1337
1400
1401
+ ParameterTypeFlags getParameterFlags () const { return Flags; }
1402
+
1338
1403
// / Determine whether this field is variadic.
1339
- bool isVararg () const {
1340
- return NameAndVariadic.getInt ();
1341
- }
1404
+ bool isVararg () const { return Flags.isVariadic (); }
1405
+
1406
+ // / Determine whether this field is an autoclosure parameter closure.
1407
+ bool isAutoClosure () const { return Flags.isAutoClosure (); }
1408
+
1409
+ // / Determine whether this field is an escaping parameter closure.
1410
+ bool isEscaping () const { return Flags.isEscaping (); }
1342
1411
1343
1412
static inline Type getVarargBaseTy (Type VarArgT);
1344
1413
@@ -1351,8 +1420,16 @@ class TupleTypeElt {
1351
1420
1352
1421
// / Retrieve a copy of this tuple type element with the type replaced.
1353
1422
TupleTypeElt getWithType (Type T) const {
1354
- return TupleTypeElt (T, getName (), isVararg ());
1423
+ return TupleTypeElt (T, getName (), getParameterFlags ());
1355
1424
}
1425
+
1426
+ // / Retrieve a copy of this tuple type element with the name replaced.
1427
+ TupleTypeElt getWithName (Identifier name) const {
1428
+ return TupleTypeElt (getType (), name, getParameterFlags ());
1429
+ }
1430
+
1431
+ // / Retrieve a copy of this tuple type element with no name
1432
+ TupleTypeElt getWithoutName () const { return getWithName (Identifier ()); }
1356
1433
};
1357
1434
1358
1435
inline Type getTupleEltType (const TupleTypeElt &elt) {
@@ -2369,11 +2446,20 @@ struct CallArgParam {
2369
2446
// / Whether the parameter has a default argument. Not valid for arguments.
2370
2447
bool HasDefaultArgument = false ;
2371
2448
2372
- // / Whether the parameter is variadic. Not valid for arguments.
2373
- bool Variadic = false ;
2449
+ // / Parameter specific flags, not valid for arguments
2450
+ ParameterTypeFlags parameterFlags = {} ;
2374
2451
2375
2452
// / Whether the argument or parameter has a label.
2376
2453
bool hasLabel () const { return !Label.empty (); }
2454
+
2455
+ // / Whether the parameter is varargs
2456
+ bool isVariadic () const { return parameterFlags.isVariadic (); }
2457
+
2458
+ // / Whether the parameter is autoclosure
2459
+ bool isAutoClosure () const { return parameterFlags.isAutoClosure (); }
2460
+
2461
+ // / Whether the parameter is escaping
2462
+ bool isEscaping () const { return parameterFlags.isEscaping (); }
2377
2463
};
2378
2464
2379
2465
// / Break an argument type into an array of \c CallArgParams.
@@ -4454,16 +4540,19 @@ inline bool TypeBase::mayHaveSuperclass() {
4454
4540
return is<DynamicSelfType>();
4455
4541
}
4456
4542
4457
- inline TupleTypeElt::TupleTypeElt (Type ty,
4458
- Identifier name,
4459
- bool isVariadic)
4460
- : NameAndVariadic(name, isVariadic), ElementType(ty)
4461
- {
4543
+ inline TupleTypeElt::TupleTypeElt (Type ty, Identifier name, bool isVariadic,
4544
+ bool isAutoClosure, bool isEscaping)
4545
+ : Name(name), ElementType(ty),
4546
+ Flags(isVariadic, isAutoClosure, isEscaping) {
4462
4547
assert (!isVariadic ||
4463
4548
isa<ErrorType>(ty.getPointer ()) ||
4464
4549
isa<ArraySliceType>(ty.getPointer ()) ||
4465
4550
(isa<BoundGenericType>(ty.getPointer ()) &&
4466
4551
ty->castTo <BoundGenericType>()->getGenericArgs ().size () == 1 ));
4552
+ assert (!isAutoClosure || (ty->is <AnyFunctionType>() &&
4553
+ ty->castTo <AnyFunctionType>()->isAutoClosure ()));
4554
+ assert (!isEscaping || (ty->is <AnyFunctionType>() &&
4555
+ !ty->castTo <AnyFunctionType>()->isNoEscape ()));
4467
4556
}
4468
4557
4469
4558
inline Type TupleTypeElt::getVarargBaseTy (Type VarArgT) {
@@ -4478,6 +4567,16 @@ inline Type TupleTypeElt::getVarargBaseTy(Type VarArgT) {
4478
4567
return T;
4479
4568
}
4480
4569
4570
+ // / Create one from what's present in the parameter decl and type
4571
+ inline ParameterTypeFlags
4572
+ ParameterTypeFlags::fromParameterType (Type paramTy, bool isVariadic) {
4573
+ bool autoclosure = paramTy->is <AnyFunctionType>() &&
4574
+ paramTy->castTo <AnyFunctionType>()->isAutoClosure ();
4575
+ bool escaping = paramTy->is <AnyFunctionType>() &&
4576
+ !paramTy->castTo <AnyFunctionType>()->isNoEscape ();
4577
+ return {isVariadic, autoclosure, escaping};
4578
+ }
4579
+
4481
4580
inline Identifier SubstitutableType::getName () const {
4482
4581
if (auto Archetype = dyn_cast<ArchetypeType>(this ))
4483
4582
return Archetype->getName ();
0 commit comments