Skip to content

[IRGen] Lowered open_pack_element. #63363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 52 additions & 7 deletions include/swift/IRGen/GenericRequirement.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,19 @@

#include "swift/AST/Decl.h"
#include "swift/AST/Type.h"
#include "swift/AST/Types.h"
#include "llvm/Support/raw_ostream.h"

namespace llvm {
class Type;
}

namespace swift {

class ProtocolDecl;
namespace irgen {
class IRGenModule;
}

/// The three kinds of entities passed in the runtime calling convention for
/// generic code: pack shapes, type metadata, and witness tables.
Expand All @@ -34,10 +42,12 @@ class ProtocolDecl;
/// generic signature.
class GenericRequirement {
public:
enum class Kind: uint8_t {
enum class Kind : uint8_t {
Shape,
Metadata,
WitnessTable
WitnessTable,
MetadataPack,
WitnessTablePack,
};

private:
Expand All @@ -48,6 +58,16 @@ class GenericRequirement {
GenericRequirement(Kind kind, CanType type, ProtocolDecl *proto)
: kind(kind), type(type), proto(proto) {}

static bool isPack(CanType ty) {
if (auto gp = dyn_cast<GenericTypeParamType>(ty))
return gp->isParameterPack();
if (auto dm = dyn_cast<DependentMemberType>(ty))
if (auto gp =
dyn_cast<GenericTypeParamType>(dm->getBase()->getCanonicalType()))
return gp->isParameterPack();
return false;
}

public:
Kind getKind() const {
return kind;
Expand All @@ -74,17 +94,34 @@ class GenericRequirement {
return kind == Kind::Metadata;
}

static GenericRequirement forMetadata(CanType type, bool isPack) {
auto kind = isPack ? Kind::MetadataPack : Kind::Metadata;
return GenericRequirement(kind, type, nullptr);
}

static GenericRequirement forMetadata(CanType type) {
return GenericRequirement(Kind::Metadata, type, nullptr);
return forMetadata(type, isPack(type));
}

bool isWitnessTable() const {
return kind == Kind::WitnessTable;
}

static GenericRequirement forWitnessTable(CanType type, ProtocolDecl *proto,
bool isPack) {
auto kind = isPack ? Kind::WitnessTablePack : Kind::WitnessTable;
return GenericRequirement(kind, type, proto);
}

static GenericRequirement forWitnessTable(CanType type, ProtocolDecl *proto) {
assert(proto != nullptr);
return GenericRequirement(Kind::WitnessTable, type, proto);
return forWitnessTable(type, proto, isPack(type));
}

static llvm::Type *typeForKind(irgen::IRGenModule &IGM,
GenericRequirement::Kind kind);

llvm::Type *getType(irgen::IRGenModule &IGM) const {
return typeForKind(IGM, getKind());
}

void dump(llvm::raw_ostream &out) const {
Expand All @@ -98,6 +135,12 @@ class GenericRequirement {
case Kind::WitnessTable:
out << "witness_table: " << type << " : " << proto->getName();
break;
case Kind::MetadataPack:
out << "metadata_pack: " << type;
break;
case Kind::WitnessTablePack:
out << "witness_table_pack: " << type << " : " << proto->getName();
break;
}
}
};
Expand All @@ -109,10 +152,12 @@ template <> struct DenseMapInfo<swift::GenericRequirement> {
using GenericRequirement = swift::GenericRequirement;
using CanTypeInfo = llvm::DenseMapInfo<swift::CanType>;
static GenericRequirement getEmptyKey() {
return GenericRequirement::forMetadata(CanTypeInfo::getEmptyKey());
return GenericRequirement::forMetadata(CanTypeInfo::getEmptyKey(),
/*isPack=*/false);
}
static GenericRequirement getTombstoneKey() {
return GenericRequirement::forMetadata(CanTypeInfo::getTombstoneKey());
return GenericRequirement::forMetadata(CanTypeInfo::getTombstoneKey(),
/*isPack=*/false);
}
static llvm::hash_code getHashValue(GenericRequirement req) {
return hash_combine(CanTypeInfo::getHashValue(req.getTypeParameter()),
Expand Down
8 changes: 4 additions & 4 deletions lib/IRGen/GenMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3898,13 +3898,13 @@ namespace {
ClassDecl *forClass) {
switch (requirement.getKind()) {
case GenericRequirement::Kind::Shape:
B.addInt(IGM.SizeTy, 0);
B.addInt(cast<llvm::IntegerType>(requirement.getType(IGM)), 0);
break;
case GenericRequirement::Kind::Metadata:
B.addNullPointer(IGM.TypeMetadataPtrTy);
break;
case GenericRequirement::Kind::WitnessTable:
B.addNullPointer(IGM.WitnessTablePtrTy);
case GenericRequirement::Kind::MetadataPack:
case GenericRequirement::Kind::WitnessTablePack:
B.addNullPointer(cast<llvm::PointerType>(requirement.getType(IGM)));
break;
}
}
Expand Down
Loading