Skip to content

Commit 2d15d1c

Browse files
committed
Runtime: Repurpose TargetGenericContextDescriptorHeader::NumExtraArguments for flags
For now, we have a single flag, which indicates that our generic context has generic parameter packs.
1 parent d764167 commit 2d15d1c

File tree

1 file changed

+46
-10
lines changed

1 file changed

+46
-10
lines changed

include/swift/ABI/GenericContext.h

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,38 @@ struct TargetProtocolConformanceDescriptor;
3030
template <typename Runtime>
3131
struct TargetGenericContext;
3232

33+
class GenericContextDescriptorFlags {
34+
uint16_t Value;
35+
36+
public:
37+
constexpr GenericContextDescriptorFlags() : Value(0) {}
38+
39+
explicit constexpr GenericContextDescriptorFlags(uint16_t value)
40+
: Value(value) {}
41+
42+
constexpr GenericContextDescriptorFlags(bool hasTypePacks)
43+
: GenericContextDescriptorFlags(
44+
GenericContextDescriptorFlags((uint16_t)0)
45+
.withHasTypePacks(hasTypePacks)) {}
46+
47+
/// Whether this generic context has at least one type parameter
48+
/// pack, in which case the generic context will have a trailing
49+
/// GenericParamPackShapeHeader.
50+
constexpr bool hasTypePacks() const {
51+
return (Value & 0x1) != 0;
52+
}
53+
54+
constexpr GenericContextDescriptorFlags
55+
withHasTypePacks(bool hasTypePacks) const {
56+
return GenericContextDescriptorFlags((uint16_t)(
57+
(Value & ~0x1) | (hasTypePacks ? 0x1 : 0)));
58+
}
59+
60+
constexpr uint16_t getIntValue() const {
61+
return Value;
62+
}
63+
};
64+
3365
template <typename Runtime>
3466
struct TargetGenericContextDescriptorHeader {
3567
/// The number of (source-written) generic parameters, and thus
@@ -39,8 +71,8 @@ struct TargetGenericContextDescriptorHeader {
3971
///
4072
/// A GenericParamDescriptor corresponds to a type metadata pointer
4173
/// in the arguments layout when isKeyArgument() is true.
42-
/// isKeyArgument() will be false if the parameter has been unified
43-
/// unified with a different parameter or an associated type.
74+
/// isKeyArgument() will be false if the parameter has been made
75+
/// equivalent to a different parameter or a concrete type.
4476
uint16_t NumParams;
4577

4678
/// The number of GenericRequirementDescriptors in this generic
@@ -66,18 +98,22 @@ struct TargetGenericContextDescriptorHeader {
6698
/// hasKeyArgument()).
6799
uint16_t NumKeyArguments;
68100

69-
/// In principle, the size of the "extra" area of the argument
101+
/// Originally this was the size of the "extra" area of the argument
70102
/// layout, in words. The idea was that extra arguments would
71103
/// include generic parameters and conformances that are not part
72104
/// of the identity of the context; however, it's unclear why we
73-
/// would ever want such a thing. As a result, this section is
74-
/// unused, and this field is always zero. It can be repurposed
75-
/// as long as it remains zero in code which must be compatible
76-
/// with existing Swift runtimes.
77-
uint16_t NumExtraArguments;
105+
/// would ever want such a thing. As a result, in pre-5.8 runtimes
106+
/// this field is always zero. New flags can only be added as long
107+
/// as they remains zero in code which must be compatible with
108+
/// older Swift runtimes.
109+
GenericContextDescriptorFlags Flags;
78110

79111
uint32_t getNumArguments() const {
80-
return NumKeyArguments + NumExtraArguments;
112+
// Note: this used to be NumKeyArguments + NumExtraArguments,
113+
// and flags was named NumExtraArguments, which is why Flags
114+
// must remain zero when backward deploying to Swift 5.7 or
115+
// earlier.
116+
return NumKeyArguments;
81117
}
82118

83119
/// Return the total size of the argument layout, in words.
@@ -163,7 +199,7 @@ class TargetGenericRequirementDescriptor {
163199
return offsetof(typename std::remove_reference<decltype(*this)>::type, Type);
164200
}
165201

166-
/// Retreive the offset to the Type field
202+
/// Retreive the offset to the Param field
167203
constexpr inline auto
168204
getParamOffset() const -> typename Runtime::StoredSize {
169205
return offsetof(typename std::remove_reference<decltype(*this)>::type, Param);

0 commit comments

Comments
 (0)