@@ -1276,22 +1276,79 @@ class NameAliasType : public TypeBase {
12761276 }
12771277};
12781278
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+
12791329// / ParenType - A paren type is a type that's been written in parentheses.
12801330class ParenType : public TypeBase {
12811331 Type UnderlyingType;
1332+ ParameterTypeFlags parameterFlags;
12821333
12831334 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+
12871340public:
12881341 Type getUnderlyingType () const { return UnderlyingType; }
12891342
1290- static ParenType *get (const ASTContext &C, Type underlying);
1291-
1343+ static ParenType *get (const ASTContext &C, Type underlying,
1344+ ParameterTypeFlags flags = {});
1345+
12921346 // / Remove one level of top-level sugar from this type.
12931347 TypeBase *getSinglyDesugaredType ();
12941348
1349+ // / Get the parameter flags
1350+ ParameterTypeFlags getParameterFlags () const { return parameterFlags; }
1351+
12951352 // Implement isa/cast/dyncast/etc.
12961353 static bool classof (const TypeBase *T) {
12971354 return T->getKind () == TypeKind::Paren;
@@ -1300,33 +1357,45 @@ class ParenType : public TypeBase {
13001357
13011358// / TupleTypeElt - This represents a single element of a tuple.
13021359class 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;
13061362
13071363 // / \brief This is the type of the field.
13081364 Type ElementType;
13091365
1366+ // / Flags that are specific to and relevant for parameter types
1367+ ParameterTypeFlags Flags;
1368+
13101369 friend class TupleType ;
13111370
13121371public:
13131372 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) {}
13171380
13181381 /* implicit*/ TupleTypeElt(TypeBase *Ty)
1319- : NameAndVariadic (Identifier(), false ), ElementType(Ty) { }
1382+ : Name (Identifier()), ElementType(Ty), Flags( ) { }
13201383
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 ; }
13231386
13241387 Type getType () const { return ElementType.getPointer (); }
13251388
1389+ ParameterTypeFlags getParameterFlags () const { return Flags; }
1390+
13261391 // / 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 (); }
13301399
13311400 static inline Type getVarargBaseTy (Type VarArgT);
13321401
@@ -1339,8 +1408,16 @@ class TupleTypeElt {
13391408
13401409 // / Retrieve a copy of this tuple type element with the type replaced.
13411410 TupleTypeElt getWithType (Type T) const {
1342- return TupleTypeElt (T, getName (), isVararg ());
1411+ return TupleTypeElt (T, getName (), getParameterFlags ());
13431412 }
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 ()); }
13441421};
13451422
13461423inline Type getTupleEltType (const TupleTypeElt &elt) {
@@ -2357,11 +2434,20 @@ struct CallArgParam {
23572434 // / Whether the parameter has a default argument. Not valid for arguments.
23582435 bool HasDefaultArgument = false ;
23592436
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 = {} ;
23622439
23632440 // / Whether the argument or parameter has a label.
23642441 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 (); }
23652451};
23662452
23672453// / Break an argument type into an array of \c CallArgParams.
@@ -4445,16 +4531,19 @@ inline bool TypeBase::mayHaveSuperclass() {
44454531 return is<DynamicSelfType>();
44464532}
44474533
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) {
44534538 assert (!isVariadic ||
44544539 isa<ErrorType>(ty.getPointer ()) ||
44554540 isa<ArraySliceType>(ty.getPointer ()) ||
44564541 (isa<BoundGenericType>(ty.getPointer ()) &&
44574542 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 ()));
44584547}
44594548
44604549inline Type TupleTypeElt::getVarargBaseTy (Type VarArgT) {
@@ -4469,6 +4558,16 @@ inline Type TupleTypeElt::getVarargBaseTy(Type VarArgT) {
44694558 return T;
44704559}
44714560
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+
44724571inline Identifier SubstitutableType::getName () const {
44734572 if (auto Archetype = dyn_cast<ArchetypeType>(this ))
44744573 return Archetype->getName ();
0 commit comments