@@ -30,6 +30,38 @@ struct TargetProtocolConformanceDescriptor;
3030template <typename Runtime>
3131struct 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+
3365template <typename Runtime>
3466struct 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