@@ -30,6 +30,38 @@ struct TargetProtocolConformanceDescriptor;
30
30
template <typename Runtime>
31
31
struct TargetGenericContext ;
32
32
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
+
33
65
template <typename Runtime>
34
66
struct TargetGenericContextDescriptorHeader {
35
67
// / The number of (source-written) generic parameters, and thus
@@ -39,8 +71,8 @@ struct TargetGenericContextDescriptorHeader {
39
71
// /
40
72
// / A GenericParamDescriptor corresponds to a type metadata pointer
41
73
// / 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.
44
76
uint16_t NumParams;
45
77
46
78
// / The number of GenericRequirementDescriptors in this generic
@@ -66,18 +98,22 @@ struct TargetGenericContextDescriptorHeader {
66
98
// / hasKeyArgument()).
67
99
uint16_t NumKeyArguments;
68
100
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
70
102
// / layout, in words. The idea was that extra arguments would
71
103
// / include generic parameters and conformances that are not part
72
104
// / 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 ;
78
110
79
111
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;
81
117
}
82
118
83
119
// / Return the total size of the argument layout, in words.
@@ -163,7 +199,7 @@ class TargetGenericRequirementDescriptor {
163
199
return offsetof (typename std::remove_reference<decltype (*this )>::type, Type);
164
200
}
165
201
166
- // / Retreive the offset to the Type field
202
+ // / Retreive the offset to the Param field
167
203
constexpr inline auto
168
204
getParamOffset () const -> typename Runtime::StoredSize {
169
205
return offsetof (typename std::remove_reference<decltype (*this )>::type, Param);
0 commit comments