@@ -1276,22 +1276,70 @@ 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
+ struct ParameterTypeFlags {
1287
+ uint8_t value;
1288
+ enum : uint8_t {
1289
+ None = 0 ,
1290
+ Variadic = 1 << 0 ,
1291
+ AutoClosure = 1 << 1 ,
1292
+ Escaping = 1 << 2 ,
1293
+
1294
+ NumBits = 3
1295
+ };
1296
+ static_assert (NumBits < 8 *sizeof (value), " overflowed" );
1297
+
1298
+ ParameterTypeFlags () : value(None) {}
1299
+
1300
+ ParameterTypeFlags (uint8_t val) : value(val) {}
1301
+
1302
+ ParameterTypeFlags (bool variadic, bool autoclosure, bool escaping)
1303
+ : value((variadic ? Variadic : 0 ) |
1304
+ (autoclosure ? AutoClosure : 0 ) |
1305
+ (escaping ? Escaping : 0 )) {}
1306
+
1307
+ // / Create one from what's present in the parameter type
1308
+ inline static ParameterTypeFlags fromParameterType (Type paramTy,
1309
+ bool isVariadic);
1310
+
1311
+ bool isVariadic () const { return 0 != (value & Variadic); }
1312
+ bool isAutoClosure () const { return 0 != (value & AutoClosure); }
1313
+ bool isEscaping () const { return 0 != (value & Escaping); }
1314
+
1315
+ bool operator ==(const ParameterTypeFlags &other) {
1316
+ return value == other.value ;
1317
+ }
1318
+ };
1319
+
1279
1320
// / ParenType - A paren type is a type that's been written in parentheses.
1280
1321
class ParenType : public TypeBase {
1281
1322
Type UnderlyingType;
1323
+ ParameterTypeFlags parameterFlags;
1282
1324
1283
1325
friend class ASTContext ;
1284
- ParenType (Type UnderlyingType, RecursiveTypeProperties properties)
1285
- : TypeBase(TypeKind::Paren, nullptr , properties),
1286
- UnderlyingType (UnderlyingType) {}
1326
+ ParenType (Type UnderlyingType, RecursiveTypeProperties properties,
1327
+ ParameterTypeFlags flags)
1328
+ : TypeBase(TypeKind::Paren, nullptr , properties),
1329
+ UnderlyingType (UnderlyingType), parameterFlags(flags) {}
1330
+
1287
1331
public:
1288
1332
Type getUnderlyingType () const { return UnderlyingType; }
1289
1333
1290
- static ParenType *get (const ASTContext &C, Type underlying);
1291
-
1334
+ static ParenType *get (const ASTContext &C, Type underlying,
1335
+ ParameterTypeFlags flags = {});
1336
+
1292
1337
// / Remove one level of top-level sugar from this type.
1293
1338
TypeBase *getSinglyDesugaredType ();
1294
1339
1340
+ // / Get the parameter flags
1341
+ ParameterTypeFlags getParameterFlags () const { return parameterFlags; }
1342
+
1295
1343
// Implement isa/cast/dyncast/etc.
1296
1344
static bool classof (const TypeBase *T) {
1297
1345
return T->getKind () == TypeKind::Paren;
@@ -1300,33 +1348,45 @@ class ParenType : public TypeBase {
1300
1348
1301
1349
// / TupleTypeElt - This represents a single element of a tuple.
1302
1350
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;
1351
+ // / An optional name for the field.
1352
+ Identifier Name;
1306
1353
1307
1354
// / \brief This is the type of the field.
1308
1355
Type ElementType;
1309
1356
1357
+ // / Flags that are specific to and relevant for parameter types
1358
+ ParameterTypeFlags Flags;
1359
+
1310
1360
friend class TupleType ;
1311
1361
1312
1362
public:
1313
1363
TupleTypeElt () = default ;
1314
- inline /* implicit*/ TupleTypeElt(Type ty,
1315
- Identifier name = Identifier(),
1316
- bool isVariadic = false );
1364
+ inline /* implicit*/ TupleTypeElt(Type ty, Identifier name,
1365
+ bool isVariadic, bool isAutoClosure,
1366
+ bool isEscaping);
1367
+
1368
+ TupleTypeElt (Type ty, Identifier name = Identifier(),
1369
+ ParameterTypeFlags PTFlags = {})
1370
+ : Name(name), ElementType(ty), Flags(PTFlags) {}
1317
1371
1318
1372
/* implicit*/ TupleTypeElt(TypeBase *Ty)
1319
- : NameAndVariadic (Identifier(), false ), ElementType(Ty) { }
1373
+ : Name (Identifier()), ElementType(Ty), Flags( ) { }
1320
1374
1321
- bool hasName () const { return !NameAndVariadic. getPointer () .empty (); }
1322
- Identifier getName () const { return NameAndVariadic. getPointer () ; }
1375
+ bool hasName () const { return !Name .empty (); }
1376
+ Identifier getName () const { return Name ; }
1323
1377
1324
1378
Type getType () const { return ElementType.getPointer (); }
1325
1379
1380
+ ParameterTypeFlags getParameterFlags () const { return Flags; }
1381
+
1326
1382
// / Determine whether this field is variadic.
1327
- bool isVararg () const {
1328
- return NameAndVariadic.getInt ();
1329
- }
1383
+ bool isVararg () const { return Flags.isVariadic (); }
1384
+
1385
+ // / Determine whether this field is an autoclosure parameter closure.
1386
+ bool isAutoClosure () const { return Flags.isAutoClosure (); }
1387
+
1388
+ // / Determine whether this field is an escaping parameter closure.
1389
+ bool isEscaping () const { return Flags.isEscaping (); }
1330
1390
1331
1391
static inline Type getVarargBaseTy (Type VarArgT);
1332
1392
@@ -1339,12 +1399,20 @@ class TupleTypeElt {
1339
1399
1340
1400
// / Retrieve a copy of this tuple type element with the type replaced.
1341
1401
TupleTypeElt getWithType (Type T) const {
1342
- return TupleTypeElt (T, getName (), isVararg ());
1402
+ return TupleTypeElt (T, getName (), isVararg (), isAutoClosure (),
1403
+ isEscaping ());
1343
1404
}
1344
1405
1345
1406
// / Retrieve a copy of this tuple type element with the name replaced.
1346
1407
TupleTypeElt getWithName (Identifier name = Identifier()) const {
1347
- return TupleTypeElt (getType (), name, isVararg ());
1408
+ return TupleTypeElt (getType (), name, isVararg (), isAutoClosure (),
1409
+ isEscaping ());
1410
+ }
1411
+
1412
+ // / Retrieve a copy of this tuple type element with the type and name
1413
+ // / replaced.
1414
+ TupleTypeElt getWithTypeAndName (Type T, Identifier name) const {
1415
+ return TupleTypeElt (T, name, isVararg (), isAutoClosure (), isEscaping ());
1348
1416
}
1349
1417
};
1350
1418
@@ -2362,11 +2430,20 @@ struct CallArgParam {
2362
2430
// / Whether the parameter has a default argument. Not valid for arguments.
2363
2431
bool HasDefaultArgument = false ;
2364
2432
2365
- // / Whether the parameter is variadic. Not valid for arguments.
2366
- bool Variadic = false ;
2433
+ // / Parameter specific flags, not valid for arguments
2434
+ ParameterTypeFlags parameterFlags = {} ;
2367
2435
2368
2436
// / Whether the argument or parameter has a label.
2369
2437
bool hasLabel () const { return !Label.empty (); }
2438
+
2439
+ // / Whether the parameter is varargs
2440
+ bool isVariadic () const { return parameterFlags.isVariadic (); }
2441
+
2442
+ // / Whether the parameter is autoclosure
2443
+ bool isAutoClosure () const { return parameterFlags.isAutoClosure (); }
2444
+
2445
+ // / Whether the parameter is escaping
2446
+ bool isEscaping () const { return parameterFlags.isEscaping (); }
2370
2447
};
2371
2448
2372
2449
// / Break an argument type into an array of \c CallArgParams.
@@ -4450,16 +4527,19 @@ inline bool TypeBase::mayHaveSuperclass() {
4450
4527
return is<DynamicSelfType>();
4451
4528
}
4452
4529
4453
- inline TupleTypeElt::TupleTypeElt (Type ty,
4454
- Identifier name,
4455
- bool isVariadic)
4456
- : NameAndVariadic(name, isVariadic), ElementType(ty)
4457
- {
4530
+ inline TupleTypeElt::TupleTypeElt (Type ty, Identifier name, bool isVariadic,
4531
+ bool isAutoClosure, bool isEscaping)
4532
+ : Name(name), ElementType(ty),
4533
+ Flags(isVariadic, isAutoClosure, isEscaping) {
4458
4534
assert (!isVariadic ||
4459
4535
isa<ErrorType>(ty.getPointer ()) ||
4460
4536
isa<ArraySliceType>(ty.getPointer ()) ||
4461
4537
(isa<BoundGenericType>(ty.getPointer ()) &&
4462
4538
ty->castTo <BoundGenericType>()->getGenericArgs ().size () == 1 ));
4539
+ assert (!isAutoClosure || (ty->is <AnyFunctionType>() &&
4540
+ ty->castTo <AnyFunctionType>()->isAutoClosure ()));
4541
+ assert (!isEscaping || (ty->is <AnyFunctionType>() &&
4542
+ !ty->castTo <AnyFunctionType>()->isNoEscape ()));
4463
4543
}
4464
4544
4465
4545
inline Type TupleTypeElt::getVarargBaseTy (Type VarArgT) {
@@ -4474,6 +4554,16 @@ inline Type TupleTypeElt::getVarargBaseTy(Type VarArgT) {
4474
4554
return T;
4475
4555
}
4476
4556
4557
+ // / Create one from what's present in the parameter decl and type
4558
+ inline ParameterTypeFlags
4559
+ ParameterTypeFlags::fromParameterType (Type paramTy, bool isVariadic) {
4560
+ bool autoclosure = paramTy->is <AnyFunctionType>() &&
4561
+ paramTy->castTo <AnyFunctionType>()->isAutoClosure ();
4562
+ bool escaping = paramTy->is <AnyFunctionType>() &&
4563
+ !paramTy->castTo <AnyFunctionType>()->isNoEscape ();
4564
+ return {isVariadic, autoclosure, escaping};
4565
+ }
4566
+
4477
4567
inline Identifier SubstitutableType::getName () const {
4478
4568
if (auto Archetype = dyn_cast<ArchetypeType>(this ))
4479
4569
return Archetype->getName ();
0 commit comments