Skip to content

Commit 3619738

Browse files
authored
Merge pull request #4905 from milseman/escaping_printing_fix_clean
Fix @escaping printing
2 parents 1f46c56 + 4324d8f commit 3619738

29 files changed

+1560
-1413
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ struct PrintOptions {
245245
/// protocol requirements.
246246
bool SkipOverrides = false;
247247

248+
/// Whether to skip parameter type attributes
249+
bool SkipParameterTypeAttributes = false;
250+
248251
/// Whether to print a long attribute like '\@available' on a separate line
249252
/// from the declaration or other attributes.
250253
bool PrintLongAttrsOnSeparateLines = false;

include/swift/AST/Types.h

Lines changed: 124 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,22 +1288,79 @@ class NameAliasType : public TypeBase {
12881288
}
12891289
};
12901290

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+
12911341
/// ParenType - A paren type is a type that's been written in parentheses.
12921342
class ParenType : public TypeBase {
12931343
Type UnderlyingType;
1344+
ParameterTypeFlags parameterFlags;
12941345

12951346
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+
12991352
public:
13001353
Type getUnderlyingType() const { return UnderlyingType; }
13011354

1302-
static ParenType *get(const ASTContext &C, Type underlying);
1303-
1355+
static ParenType *get(const ASTContext &C, Type underlying,
1356+
ParameterTypeFlags flags = {});
1357+
13041358
/// Remove one level of top-level sugar from this type.
13051359
TypeBase *getSinglyDesugaredType();
13061360

1361+
/// Get the parameter flags
1362+
ParameterTypeFlags getParameterFlags() const { return parameterFlags; }
1363+
13071364
// Implement isa/cast/dyncast/etc.
13081365
static bool classof(const TypeBase *T) {
13091366
return T->getKind() == TypeKind::Paren;
@@ -1312,33 +1369,45 @@ class ParenType : public TypeBase {
13121369

13131370
/// TupleTypeElt - This represents a single element of a tuple.
13141371
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;
13181374

13191375
/// \brief This is the type of the field.
13201376
Type ElementType;
13211377

1378+
/// Flags that are specific to and relevant for parameter types
1379+
ParameterTypeFlags Flags;
1380+
13221381
friend class TupleType;
13231382

13241383
public:
13251384
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) {}
13291392

13301393
/*implicit*/ TupleTypeElt(TypeBase *Ty)
1331-
: NameAndVariadic(Identifier(), false), ElementType(Ty) { }
1394+
: Name(Identifier()), ElementType(Ty), Flags() { }
13321395

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; }
13351398

13361399
Type getType() const { return ElementType.getPointer(); }
13371400

1401+
ParameterTypeFlags getParameterFlags() const { return Flags; }
1402+
13381403
/// 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(); }
13421411

13431412
static inline Type getVarargBaseTy(Type VarArgT);
13441413

@@ -1351,8 +1420,16 @@ class TupleTypeElt {
13511420

13521421
/// Retrieve a copy of this tuple type element with the type replaced.
13531422
TupleTypeElt getWithType(Type T) const {
1354-
return TupleTypeElt(T, getName(), isVararg());
1423+
return TupleTypeElt(T, getName(), getParameterFlags());
13551424
}
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()); }
13561433
};
13571434

13581435
inline Type getTupleEltType(const TupleTypeElt &elt) {
@@ -2369,11 +2446,20 @@ struct CallArgParam {
23692446
/// Whether the parameter has a default argument. Not valid for arguments.
23702447
bool HasDefaultArgument = false;
23712448

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 = {};
23742451

23752452
/// Whether the argument or parameter has a label.
23762453
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(); }
23772463
};
23782464

23792465
/// Break an argument type into an array of \c CallArgParams.
@@ -4454,16 +4540,19 @@ inline bool TypeBase::mayHaveSuperclass() {
44544540
return is<DynamicSelfType>();
44554541
}
44564542

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) {
44624547
assert(!isVariadic ||
44634548
isa<ErrorType>(ty.getPointer()) ||
44644549
isa<ArraySliceType>(ty.getPointer()) ||
44654550
(isa<BoundGenericType>(ty.getPointer()) &&
44664551
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()));
44674556
}
44684557

44694558
inline Type TupleTypeElt::getVarargBaseTy(Type VarArgT) {
@@ -4478,6 +4567,16 @@ inline Type TupleTypeElt::getVarargBaseTy(Type VarArgT) {
44784567
return T;
44794568
}
44804569

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+
44814580
inline Identifier SubstitutableType::getName() const {
44824581
if (auto Archetype = dyn_cast<ArchetypeType>(this))
44834582
return Archetype->getName();

include/swift/Serialization/ModuleFormat.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define SWIFT_SERIALIZATION_MODULEFORMAT_H
2121

2222
#include "swift/AST/Decl.h"
23+
#include "swift/AST/Types.h"
2324
#include "llvm/Bitcode/RecordLayout.h"
2425
#include "llvm/Bitcode/BitCodes.h"
2526
#include "llvm/ADT/PointerEmbeddedInt.h"
@@ -53,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
5354
/// in source control, you should also update the comment to briefly
5455
/// describe what change you made. The content of this comment isn't important;
5556
/// it just ensures a conflict if two people change the module format.
56-
const uint16_t VERSION_MINOR = 267; // Last change: tail-alloc instructions
57+
const uint16_t VERSION_MINOR = 269; // Last change: parameter type flags
5758

5859
using DeclID = PointerEmbeddedInt<unsigned, 31>;
5960
using DeclIDField = BCFixed<31>;
@@ -570,7 +571,10 @@ namespace decls_block {
570571

571572
using ParenTypeLayout = BCRecordLayout<
572573
PAREN_TYPE,
573-
TypeIDField // inner type
574+
TypeIDField, // inner type
575+
BCFixed<1>, // vararg?
576+
BCFixed<1>, // autoclosure?
577+
BCFixed<1> // escaping?
574578
>;
575579

576580
using TupleTypeLayout = BCRecordLayout<
@@ -579,9 +583,11 @@ namespace decls_block {
579583

580584
using TupleTypeEltLayout = BCRecordLayout<
581585
TUPLE_TYPE_ELT,
582-
IdentifierIDField, // name
583-
TypeIDField, // type
584-
BCFixed<1> // vararg?
586+
IdentifierIDField, // name
587+
TypeIDField, // type
588+
BCFixed<1>, // vararg?
589+
BCFixed<1>, // autoclosure?
590+
BCFixed<1> // escaping?
585591
>;
586592

587593
using FunctionTypeLayout = BCRecordLayout<

lib/AST/ASTContext.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ struct ASTContext::Implementation {
293293
llvm::DenseMap<std::pair<Type, Type>, DictionaryType *> DictionaryTypes;
294294
llvm::DenseMap<Type, OptionalType*> OptionalTypes;
295295
llvm::DenseMap<Type, ImplicitlyUnwrappedOptionalType*> ImplicitlyUnwrappedOptionalTypes;
296-
llvm::DenseMap<Type, ParenType*> ParenTypes;
296+
llvm::DenseMap<std::pair<Type, unsigned>, ParenType*> ParenTypes;
297297
llvm::DenseMap<uintptr_t, ReferenceStorageType*> ReferenceStorageTypes;
298298
llvm::DenseMap<Type, LValueType*> LValueTypes;
299299
llvm::DenseMap<Type, InOutType*> InOutTypes;
@@ -2597,13 +2597,14 @@ BuiltinVectorType *BuiltinVectorType::get(const ASTContext &context,
25972597
return vecTy;
25982598
}
25992599

2600-
2601-
ParenType *ParenType::get(const ASTContext &C, Type underlying) {
2600+
ParenType *ParenType::get(const ASTContext &C, Type underlying,
2601+
ParameterTypeFlags flags) {
26022602
auto properties = underlying->getRecursiveProperties();
26032603
auto arena = getArena(properties);
2604-
ParenType *&Result = C.Impl.getArena(arena).ParenTypes[underlying];
2604+
ParenType *&Result =
2605+
C.Impl.getArena(arena).ParenTypes[{underlying, flags.toRaw()}];
26052606
if (Result == 0) {
2606-
Result = new (C, arena) ParenType(underlying, properties);
2607+
Result = new (C, arena) ParenType(underlying, properties, flags);
26072608
}
26082609
return Result;
26092610
}
@@ -2616,15 +2617,17 @@ void TupleType::Profile(llvm::FoldingSetNodeID &ID,
26162617
ArrayRef<TupleTypeElt> Fields) {
26172618
ID.AddInteger(Fields.size());
26182619
for (const TupleTypeElt &Elt : Fields) {
2619-
ID.AddPointer(Elt.NameAndVariadic.getOpaqueValue());
2620+
ID.AddPointer(Elt.Name.get());
26202621
ID.AddPointer(Elt.getType().getPointer());
2622+
ID.AddInteger(Elt.Flags.toRaw());
26212623
}
26222624
}
26232625

26242626
/// getTupleType - Return the uniqued tuple type with the specified elements.
26252627
Type TupleType::get(ArrayRef<TupleTypeElt> Fields, const ASTContext &C) {
26262628
if (Fields.size() == 1 && !Fields[0].isVararg() && !Fields[0].hasName())
2627-
return ParenType::get(C, Fields[0].getType());
2629+
return ParenType::get(C, Fields[0].getType(),
2630+
Fields[0].getParameterFlags());
26282631

26292632
RecursiveTypeProperties properties;
26302633
for (const TupleTypeElt &Elt : Fields) {

lib/AST/ASTDumper.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2628,6 +2628,15 @@ namespace {
26282628
return OS;
26292629
}
26302630

2631+
void dumpParameterFlags(ParameterTypeFlags paramFlags) {
2632+
if (paramFlags.isVariadic())
2633+
printFlag("vararg");
2634+
if (paramFlags.isAutoClosure())
2635+
printFlag("autoclosure");
2636+
if (paramFlags.isEscaping())
2637+
printFlag("escaping");
2638+
}
2639+
26312640
public:
26322641
PrintType(raw_ostream &os, unsigned indent) : OS(os), Indent(indent) { }
26332642

@@ -2691,6 +2700,7 @@ namespace {
26912700

26922701
void visitParenType(ParenType *T, StringRef label) {
26932702
printCommon(T, label, "paren_type");
2703+
dumpParameterFlags(T->getParameterFlags());
26942704
printRec(T->getUnderlyingType());
26952705
OS << ")";
26962706
}
@@ -2705,9 +2715,7 @@ namespace {
27052715
PrintWithColorRAII(OS, TypeFieldColor) << "tuple_type_elt";
27062716
if (elt.hasName())
27072717
printField("name", elt.getName().str());
2708-
if (elt.isVararg())
2709-
printFlag("vararg");
2710-
2718+
dumpParameterFlags(elt.getParameterFlags());
27112719
printRec(elt.getType());
27122720
OS << ")";
27132721
}
@@ -2918,10 +2926,7 @@ namespace {
29182926
}
29192927

29202928
printFlag(T->isAutoClosure(), "autoclosure");
2921-
2922-
// Dump out either @noescape or @escaping
2923-
printFlag(!T->isNoEscape(), "@escaping");
2924-
2929+
printFlag(!T->isNoEscape(), "escaping");
29252930
printFlag(T->throws(), "throws");
29262931

29272932
printRec("input", T->getInput());

0 commit comments

Comments
 (0)