Skip to content

Commit 7b317c0

Browse files
Merge pull request #63363 from nate-chandler/variadic-generics/irgen/open_pack_element
[IRGen] Lowered open_pack_element.
2 parents 4480d89 + a442245 commit 7b317c0

File tree

10 files changed

+514
-85
lines changed

10 files changed

+514
-85
lines changed

include/swift/IRGen/GenericRequirement.h

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,19 @@
1515

1616
#include "swift/AST/Decl.h"
1717
#include "swift/AST/Type.h"
18+
#include "swift/AST/Types.h"
1819
#include "llvm/Support/raw_ostream.h"
1920

21+
namespace llvm {
22+
class Type;
23+
}
24+
2025
namespace swift {
2126

2227
class ProtocolDecl;
28+
namespace irgen {
29+
class IRGenModule;
30+
}
2331

2432
/// The three kinds of entities passed in the runtime calling convention for
2533
/// generic code: pack shapes, type metadata, and witness tables.
@@ -34,10 +42,12 @@ class ProtocolDecl;
3442
/// generic signature.
3543
class GenericRequirement {
3644
public:
37-
enum class Kind: uint8_t {
45+
enum class Kind : uint8_t {
3846
Shape,
3947
Metadata,
40-
WitnessTable
48+
WitnessTable,
49+
MetadataPack,
50+
WitnessTablePack,
4151
};
4252

4353
private:
@@ -48,6 +58,16 @@ class GenericRequirement {
4858
GenericRequirement(Kind kind, CanType type, ProtocolDecl *proto)
4959
: kind(kind), type(type), proto(proto) {}
5060

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+
5171
public:
5272
Kind getKind() const {
5373
return kind;
@@ -74,17 +94,34 @@ class GenericRequirement {
7494
return kind == Kind::Metadata;
7595
}
7696

97+
static GenericRequirement forMetadata(CanType type, bool isPack) {
98+
auto kind = isPack ? Kind::MetadataPack : Kind::Metadata;
99+
return GenericRequirement(kind, type, nullptr);
100+
}
101+
77102
static GenericRequirement forMetadata(CanType type) {
78-
return GenericRequirement(Kind::Metadata, type, nullptr);
103+
return forMetadata(type, isPack(type));
79104
}
80105

81106
bool isWitnessTable() const {
82107
return kind == Kind::WitnessTable;
83108
}
84109

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+
85116
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());
88125
}
89126

90127
void dump(llvm::raw_ostream &out) const {
@@ -98,6 +135,12 @@ class GenericRequirement {
98135
case Kind::WitnessTable:
99136
out << "witness_table: " << type << " : " << proto->getName();
100137
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;
101144
}
102145
}
103146
};
@@ -109,10 +152,12 @@ template <> struct DenseMapInfo<swift::GenericRequirement> {
109152
using GenericRequirement = swift::GenericRequirement;
110153
using CanTypeInfo = llvm::DenseMapInfo<swift::CanType>;
111154
static GenericRequirement getEmptyKey() {
112-
return GenericRequirement::forMetadata(CanTypeInfo::getEmptyKey());
155+
return GenericRequirement::forMetadata(CanTypeInfo::getEmptyKey(),
156+
/*isPack=*/false);
113157
}
114158
static GenericRequirement getTombstoneKey() {
115-
return GenericRequirement::forMetadata(CanTypeInfo::getTombstoneKey());
159+
return GenericRequirement::forMetadata(CanTypeInfo::getTombstoneKey(),
160+
/*isPack=*/false);
116161
}
117162
static llvm::hash_code getHashValue(GenericRequirement req) {
118163
return hash_combine(CanTypeInfo::getHashValue(req.getTypeParameter()),

lib/IRGen/GenMeta.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3898,13 +3898,13 @@ namespace {
38983898
ClassDecl *forClass) {
38993899
switch (requirement.getKind()) {
39003900
case GenericRequirement::Kind::Shape:
3901-
B.addInt(IGM.SizeTy, 0);
3901+
B.addInt(cast<llvm::IntegerType>(requirement.getType(IGM)), 0);
39023902
break;
39033903
case GenericRequirement::Kind::Metadata:
3904-
B.addNullPointer(IGM.TypeMetadataPtrTy);
3905-
break;
39063904
case GenericRequirement::Kind::WitnessTable:
3907-
B.addNullPointer(IGM.WitnessTablePtrTy);
3905+
case GenericRequirement::Kind::MetadataPack:
3906+
case GenericRequirement::Kind::WitnessTablePack:
3907+
B.addNullPointer(cast<llvm::PointerType>(requirement.getType(IGM)));
39083908
break;
39093909
}
39103910
}

0 commit comments

Comments
 (0)