15
15
16
16
#include " swift/AST/Decl.h"
17
17
#include " swift/AST/Type.h"
18
+ #include " swift/AST/Types.h"
18
19
#include " llvm/Support/raw_ostream.h"
19
20
21
+ namespace llvm {
22
+ class Type ;
23
+ }
24
+
20
25
namespace swift {
21
26
22
27
class ProtocolDecl ;
28
+ namespace irgen {
29
+ class IRGenModule ;
30
+ }
23
31
24
32
// / The three kinds of entities passed in the runtime calling convention for
25
33
// / generic code: pack shapes, type metadata, and witness tables.
@@ -34,10 +42,12 @@ class ProtocolDecl;
34
42
// / generic signature.
35
43
class GenericRequirement {
36
44
public:
37
- enum class Kind : uint8_t {
45
+ enum class Kind : uint8_t {
38
46
Shape,
39
47
Metadata,
40
- WitnessTable
48
+ WitnessTable,
49
+ MetadataPack,
50
+ WitnessTablePack,
41
51
};
42
52
43
53
private:
@@ -48,6 +58,16 @@ class GenericRequirement {
48
58
GenericRequirement (Kind kind, CanType type, ProtocolDecl *proto)
49
59
: kind(kind), type(type), proto(proto) {}
50
60
61
+ static bool isPack (CanType ty) {
62
+ if (auto gp = dyn_cast<GenericTypeParamType>(ty))
63
+ return gp->isParameterPack ();
64
+ if (auto dm = dyn_cast<DependentMemberType>(ty))
65
+ if (auto gp =
66
+ dyn_cast<GenericTypeParamType>(dm->getBase ()->getCanonicalType ()))
67
+ return gp->isParameterPack ();
68
+ return false ;
69
+ }
70
+
51
71
public:
52
72
Kind getKind () const {
53
73
return kind;
@@ -74,17 +94,34 @@ class GenericRequirement {
74
94
return kind == Kind::Metadata;
75
95
}
76
96
97
+ static GenericRequirement forMetadata (CanType type, bool isPack) {
98
+ auto kind = isPack ? Kind::MetadataPack : Kind::Metadata;
99
+ return GenericRequirement (kind, type, nullptr );
100
+ }
101
+
77
102
static GenericRequirement forMetadata (CanType type) {
78
- return GenericRequirement (Kind::Metadata, type, nullptr );
103
+ return forMetadata ( type, isPack (type) );
79
104
}
80
105
81
106
bool isWitnessTable () const {
82
107
return kind == Kind::WitnessTable;
83
108
}
84
109
110
+ static GenericRequirement forWitnessTable (CanType type, ProtocolDecl *proto,
111
+ bool isPack) {
112
+ auto kind = isPack ? Kind::WitnessTablePack : Kind::WitnessTable;
113
+ return GenericRequirement (kind, type, proto);
114
+ }
115
+
85
116
static GenericRequirement forWitnessTable (CanType type, ProtocolDecl *proto) {
86
- assert (proto != nullptr );
87
- return GenericRequirement (Kind::WitnessTable, type, proto);
117
+ return forWitnessTable (type, proto, isPack (type));
118
+ }
119
+
120
+ static llvm::Type *typeForKind (irgen::IRGenModule &IGM,
121
+ GenericRequirement::Kind kind);
122
+
123
+ llvm::Type *getType (irgen::IRGenModule &IGM) const {
124
+ return typeForKind (IGM, getKind ());
88
125
}
89
126
90
127
void dump (llvm::raw_ostream &out) const {
@@ -98,6 +135,12 @@ class GenericRequirement {
98
135
case Kind::WitnessTable:
99
136
out << " witness_table: " << type << " : " << proto->getName ();
100
137
break ;
138
+ case Kind::MetadataPack:
139
+ out << " metadata_pack: " << type;
140
+ break ;
141
+ case Kind::WitnessTablePack:
142
+ out << " witness_table_pack: " << type << " : " << proto->getName ();
143
+ break ;
101
144
}
102
145
}
103
146
};
@@ -109,10 +152,12 @@ template <> struct DenseMapInfo<swift::GenericRequirement> {
109
152
using GenericRequirement = swift::GenericRequirement;
110
153
using CanTypeInfo = llvm::DenseMapInfo<swift::CanType>;
111
154
static GenericRequirement getEmptyKey () {
112
- return GenericRequirement::forMetadata (CanTypeInfo::getEmptyKey ());
155
+ return GenericRequirement::forMetadata (CanTypeInfo::getEmptyKey (),
156
+ /* isPack=*/ false );
113
157
}
114
158
static GenericRequirement getTombstoneKey () {
115
- return GenericRequirement::forMetadata (CanTypeInfo::getTombstoneKey ());
159
+ return GenericRequirement::forMetadata (CanTypeInfo::getTombstoneKey (),
160
+ /* isPack=*/ false );
116
161
}
117
162
static llvm::hash_code getHashValue (GenericRequirement req) {
118
163
return hash_combine (CanTypeInfo::getHashValue (req.getTypeParameter ()),
0 commit comments