@@ -1276,22 +1276,79 @@ class NameAliasType : public TypeBase {
1276
1276
}
1277
1277
};
1278
1278
1279
+ // TODO: As part of AST modernization, replace with a proper
1280
+ // 'ParameterTypeElt' or similar, and have FunctionTypes only have a list
1281
+ // of 'ParameterTypeElt's. Then, this information can be removed from
1282
+ // TupleTypeElt.
1283
+ //
1284
+ // / Provide parameter type relevant flags, i.e. variadic, autoclosure, and
1285
+ // / escaping.
1286
+ class ParameterTypeFlags {
1287
+ enum ParameterFlags : uint8_t {
1288
+ None = 0 ,
1289
+ Variadic = 1 << 0 ,
1290
+ AutoClosure = 1 << 1 ,
1291
+ Escaping = 1 << 2 ,
1292
+
1293
+ NumBits = 3
1294
+ };
1295
+ OptionSet<ParameterFlags> value;
1296
+ static_assert (NumBits < 8 *sizeof (value), " overflowed" );
1297
+
1298
+ ParameterTypeFlags (OptionSet<ParameterFlags, uint8_t > val) : value(val) {}
1299
+
1300
+ public:
1301
+ ParameterTypeFlags () = default ;
1302
+
1303
+ ParameterTypeFlags (bool variadic, bool autoclosure, bool escaping)
1304
+ : value((variadic ? Variadic : 0 ) |
1305
+ (autoclosure ? AutoClosure : 0 ) |
1306
+ (escaping ? Escaping : 0 )) {}
1307
+
1308
+ // / Create one from what's present in the parameter type
1309
+ inline static ParameterTypeFlags fromParameterType (Type paramTy,
1310
+ bool isVariadic);
1311
+
1312
+ bool isNone () const { return !value; }
1313
+ bool isVariadic () const { return value.contains (Variadic); }
1314
+ bool isAutoClosure () const { return value.contains (AutoClosure); }
1315
+ bool isEscaping () const { return value.contains (Escaping); }
1316
+
1317
+ ParameterTypeFlags withEscaping (bool escaping) const {
1318
+ return ParameterTypeFlags (escaping ? value | ParameterTypeFlags::Escaping
1319
+ : value - ParameterTypeFlags::Escaping);
1320
+ }
1321
+
1322
+ bool operator ==(const ParameterTypeFlags &other) const {
1323
+ return value.toRaw () == other.value .toRaw ();
1324
+ }
1325
+
1326
+ uint8_t toRaw () const { return value.toRaw (); }
1327
+ };
1328
+
1279
1329
// / ParenType - A paren type is a type that's been written in parentheses.
1280
1330
class ParenType : public TypeBase {
1281
1331
Type UnderlyingType;
1332
+ ParameterTypeFlags parameterFlags;
1282
1333
1283
1334
friend class ASTContext ;
1284
- ParenType (Type UnderlyingType, RecursiveTypeProperties properties)
1285
- : TypeBase(TypeKind::Paren, nullptr , properties),
1286
- UnderlyingType (UnderlyingType) {}
1335
+ ParenType (Type UnderlyingType, RecursiveTypeProperties properties,
1336
+ ParameterTypeFlags flags)
1337
+ : TypeBase(TypeKind::Paren, nullptr , properties),
1338
+ UnderlyingType (UnderlyingType), parameterFlags(flags) {}
1339
+
1287
1340
public:
1288
1341
Type getUnderlyingType () const { return UnderlyingType; }
1289
1342
1290
- static ParenType *get (const ASTContext &C, Type underlying);
1291
-
1343
+ static ParenType *get (const ASTContext &C, Type underlying,
1344
+ ParameterTypeFlags flags = {});
1345
+
1292
1346
// / Remove one level of top-level sugar from this type.
1293
1347
TypeBase *getSinglyDesugaredType ();
1294
1348
1349
+ // / Get the parameter flags
1350
+ ParameterTypeFlags getParameterFlags () const { return parameterFlags; }
1351
+
1295
1352
// Implement isa/cast/dyncast/etc.
1296
1353
static bool classof (const TypeBase *T) {
1297
1354
return T->getKind () == TypeKind::Paren;
@@ -1300,33 +1357,45 @@ class ParenType : public TypeBase {
1300
1357
1301
1358
// / TupleTypeElt - This represents a single element of a tuple.
1302
1359
class TupleTypeElt {
1303
- // / An optional name for the field, along with a bit indicating whether it
1304
- // / is variadic.
1305
- llvm::PointerIntPair<Identifier, 1 , bool > NameAndVariadic;
1360
+ // / An optional name for the field.
1361
+ Identifier Name;
1306
1362
1307
1363
// / \brief This is the type of the field.
1308
1364
Type ElementType;
1309
1365
1366
+ // / Flags that are specific to and relevant for parameter types
1367
+ ParameterTypeFlags Flags;
1368
+
1310
1369
friend class TupleType ;
1311
1370
1312
1371
public:
1313
1372
TupleTypeElt () = default ;
1314
- inline /* implicit*/ TupleTypeElt(Type ty,
1315
- Identifier name = Identifier(),
1316
- bool isVariadic = false );
1373
+ inline /* implicit*/ TupleTypeElt(Type ty, Identifier name,
1374
+ bool isVariadic, bool isAutoClosure,
1375
+ bool isEscaping);
1376
+
1377
+ TupleTypeElt (Type ty, Identifier name = Identifier(),
1378
+ ParameterTypeFlags PTFlags = {})
1379
+ : Name(name), ElementType(ty), Flags(PTFlags) {}
1317
1380
1318
1381
/* implicit*/ TupleTypeElt(TypeBase *Ty)
1319
- : NameAndVariadic (Identifier(), false ), ElementType(Ty) { }
1382
+ : Name (Identifier()), ElementType(Ty), Flags( ) { }
1320
1383
1321
- bool hasName () const { return !NameAndVariadic. getPointer () .empty (); }
1322
- Identifier getName () const { return NameAndVariadic. getPointer () ; }
1384
+ bool hasName () const { return !Name .empty (); }
1385
+ Identifier getName () const { return Name ; }
1323
1386
1324
1387
Type getType () const { return ElementType.getPointer (); }
1325
1388
1389
+ ParameterTypeFlags getParameterFlags () const { return Flags; }
1390
+
1326
1391
// / Determine whether this field is variadic.
1327
- bool isVararg () const {
1328
- return NameAndVariadic.getInt ();
1329
- }
1392
+ bool isVararg () const { return Flags.isVariadic (); }
1393
+
1394
+ // / Determine whether this field is an autoclosure parameter closure.
1395
+ bool isAutoClosure () const { return Flags.isAutoClosure (); }
1396
+
1397
+ // / Determine whether this field is an escaping parameter closure.
1398
+ bool isEscaping () const { return Flags.isEscaping (); }
1330
1399
1331
1400
static inline Type getVarargBaseTy (Type VarArgT);
1332
1401
@@ -1339,8 +1408,16 @@ class TupleTypeElt {
1339
1408
1340
1409
// / Retrieve a copy of this tuple type element with the type replaced.
1341
1410
TupleTypeElt getWithType (Type T) const {
1342
- return TupleTypeElt (T, getName (), isVararg ());
1411
+ return TupleTypeElt (T, getName (), getParameterFlags ());
1343
1412
}
1413
+
1414
+ // / Retrieve a copy of this tuple type element with the name replaced.
1415
+ TupleTypeElt getWithName (Identifier name) const {
1416
+ return TupleTypeElt (getType (), name, getParameterFlags ());
1417
+ }
1418
+
1419
+ // / Retrieve a copy of this tuple type element with no name
1420
+ TupleTypeElt getWithoutName () const { return getWithName (Identifier ()); }
1344
1421
};
1345
1422
1346
1423
inline Type getTupleEltType (const TupleTypeElt &elt) {
@@ -2357,11 +2434,20 @@ struct CallArgParam {
2357
2434
// / Whether the parameter has a default argument. Not valid for arguments.
2358
2435
bool HasDefaultArgument = false ;
2359
2436
2360
- // / Whether the parameter is variadic. Not valid for arguments.
2361
- bool Variadic = false ;
2437
+ // / Parameter specific flags, not valid for arguments
2438
+ ParameterTypeFlags parameterFlags = {} ;
2362
2439
2363
2440
// / Whether the argument or parameter has a label.
2364
2441
bool hasLabel () const { return !Label.empty (); }
2442
+
2443
+ // / Whether the parameter is varargs
2444
+ bool isVariadic () const { return parameterFlags.isVariadic (); }
2445
+
2446
+ // / Whether the parameter is autoclosure
2447
+ bool isAutoClosure () const { return parameterFlags.isAutoClosure (); }
2448
+
2449
+ // / Whether the parameter is escaping
2450
+ bool isEscaping () const { return parameterFlags.isEscaping (); }
2365
2451
};
2366
2452
2367
2453
// / Break an argument type into an array of \c CallArgParams.
@@ -4445,16 +4531,19 @@ inline bool TypeBase::mayHaveSuperclass() {
4445
4531
return is<DynamicSelfType>();
4446
4532
}
4447
4533
4448
- inline TupleTypeElt::TupleTypeElt (Type ty,
4449
- Identifier name,
4450
- bool isVariadic)
4451
- : NameAndVariadic(name, isVariadic), ElementType(ty)
4452
- {
4534
+ inline TupleTypeElt::TupleTypeElt (Type ty, Identifier name, bool isVariadic,
4535
+ bool isAutoClosure, bool isEscaping)
4536
+ : Name(name), ElementType(ty),
4537
+ Flags(isVariadic, isAutoClosure, isEscaping) {
4453
4538
assert (!isVariadic ||
4454
4539
isa<ErrorType>(ty.getPointer ()) ||
4455
4540
isa<ArraySliceType>(ty.getPointer ()) ||
4456
4541
(isa<BoundGenericType>(ty.getPointer ()) &&
4457
4542
ty->castTo <BoundGenericType>()->getGenericArgs ().size () == 1 ));
4543
+ assert (!isAutoClosure || (ty->is <AnyFunctionType>() &&
4544
+ ty->castTo <AnyFunctionType>()->isAutoClosure ()));
4545
+ assert (!isEscaping || (ty->is <AnyFunctionType>() &&
4546
+ !ty->castTo <AnyFunctionType>()->isNoEscape ()));
4458
4547
}
4459
4548
4460
4549
inline Type TupleTypeElt::getVarargBaseTy (Type VarArgT) {
@@ -4469,6 +4558,16 @@ inline Type TupleTypeElt::getVarargBaseTy(Type VarArgT) {
4469
4558
return T;
4470
4559
}
4471
4560
4561
+ // / Create one from what's present in the parameter decl and type
4562
+ inline ParameterTypeFlags
4563
+ ParameterTypeFlags::fromParameterType (Type paramTy, bool isVariadic) {
4564
+ bool autoclosure = paramTy->is <AnyFunctionType>() &&
4565
+ paramTy->castTo <AnyFunctionType>()->isAutoClosure ();
4566
+ bool escaping = paramTy->is <AnyFunctionType>() &&
4567
+ !paramTy->castTo <AnyFunctionType>()->isNoEscape ();
4568
+ return {isVariadic, autoclosure, escaping};
4569
+ }
4570
+
4472
4571
inline Identifier SubstitutableType::getName () const {
4473
4572
if (auto Archetype = dyn_cast<ArchetypeType>(this ))
4474
4573
return Archetype->getName ();
0 commit comments