Skip to content

Commit 65d2d4d

Browse files
committed
IRGen: Encapsulate fields of GenericRequirement better
1 parent 1ca373a commit 65d2d4d

21 files changed

+219
-125
lines changed

include/swift/AST/GenericRequirement.h

Lines changed: 0 additions & 51 deletions
This file was deleted.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
//===--- GenericRequirement.h - Generic requirement -------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_AST_GENERIC_REQUIREMENT_H
14+
#define SWIFT_AST_GENERIC_REQUIREMENT_H
15+
16+
#include "swift/AST/Type.h"
17+
18+
namespace swift {
19+
20+
class ProtocolDecl;
21+
22+
/// The three kinds of entities passed in the runtime calling convention for
23+
/// generic code: pack shapes, type metadata, and witness tables.
24+
///
25+
/// A pack shape describes an equivalence class of type parameter packs; the
26+
/// runtime value is a single integer, which is the length of the pack.
27+
///
28+
/// Type metadata is emitted for each reduced generic parameter (that is,
29+
/// not same-type constrained to another generic parameter or concrete type).
30+
///
31+
/// A witness table is emitted for each conformance requirement in the
32+
/// generic signature.
33+
class GenericRequirement {
34+
public:
35+
enum class Kind: uint8_t {
36+
Shape,
37+
Metadata,
38+
WitnessTable
39+
};
40+
41+
private:
42+
Kind kind;
43+
CanType type;
44+
ProtocolDecl *proto;
45+
46+
GenericRequirement(Kind kind, CanType type, ProtocolDecl *proto)
47+
: kind(kind), type(type), proto(proto) {}
48+
49+
public:
50+
Kind getKind() const {
51+
return kind;
52+
}
53+
54+
CanType getTypeParameter() const {
55+
return type;
56+
}
57+
58+
ProtocolDecl *getProtocol() const {
59+
return proto;
60+
}
61+
62+
bool isShape() const {
63+
return kind == Kind::Shape;
64+
}
65+
66+
static GenericRequirement forShape(CanType type) {
67+
return GenericRequirement(Kind::Shape, type, nullptr);
68+
}
69+
70+
bool isMetadata() const {
71+
return kind == Kind::Metadata;
72+
}
73+
74+
static GenericRequirement forMetadata(CanType type) {
75+
return GenericRequirement(Kind::Metadata, type, nullptr);
76+
}
77+
78+
bool isWitnessTable() const {
79+
return kind == Kind::WitnessTable;
80+
}
81+
82+
static GenericRequirement forWitnessTable(CanType type, ProtocolDecl *proto) {
83+
assert(proto != nullptr);
84+
return GenericRequirement(Kind::WitnessTable, type, proto);
85+
}
86+
};
87+
88+
} // end namespace swift
89+
90+
namespace llvm {
91+
template <> struct DenseMapInfo<swift::GenericRequirement> {
92+
using GenericRequirement = swift::GenericRequirement;
93+
using CanTypeInfo = llvm::DenseMapInfo<swift::CanType>;
94+
static GenericRequirement getEmptyKey() {
95+
return GenericRequirement::forMetadata(CanTypeInfo::getEmptyKey());
96+
}
97+
static GenericRequirement getTombstoneKey() {
98+
return GenericRequirement::forMetadata(CanTypeInfo::getTombstoneKey());
99+
}
100+
static llvm::hash_code getHashValue(GenericRequirement req) {
101+
return hash_combine(CanTypeInfo::getHashValue(req.getTypeParameter()),
102+
hash_value(req.getProtocol()));
103+
}
104+
static bool isEqual(GenericRequirement lhs, GenericRequirement rhs) {
105+
return (lhs.getKind() == rhs.getKind() &&
106+
lhs.getTypeParameter() == rhs.getTypeParameter() &&
107+
lhs.getProtocol() == rhs.getProtocol());
108+
}
109+
};
110+
} // end namespace llvm
111+
112+
#endif // SWIFT_AST_GENERIC_REQUIREMENT_H

include/swift/IRGen/IRABIDetailsProvider.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
#define SWIFT_IRGEN_IRABIDETAILSPROVIDER_H
1515

1616
#include "swift/AST/Decl.h"
17-
#include "swift/AST/GenericRequirement.h"
1817
#include "swift/AST/Type.h"
1918
#include "swift/AST/Types.h"
19+
#include "swift/IRGen/GenericRequirement.h"
2020
#include "clang/AST/CharUnits.h"
2121
#include "llvm/ADT/MapVector.h"
2222
#include "llvm/ADT/Optional.h"

lib/IRGen/EntryPointArgumentEmission.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Value;
1818

1919
namespace swift {
2020

21-
struct GenericRequirement;
21+
class GenericRequirement;
2222
class SILArgument;
2323

2424
namespace irgen {

lib/IRGen/GenArchetype.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -435,14 +435,15 @@ withOpaqueTypeGenericArgs(IRGenFunction &IGF,
435435
enumerateGenericSignatureRequirements(
436436
opaqueDecl->getGenericSignature().getCanonicalSignature(),
437437
[&](GenericRequirement reqt) {
438-
auto ty = reqt.TypeParameter.subst(archetype->getSubstitutions())
438+
auto ty = reqt.getTypeParameter().subst(archetype->getSubstitutions())
439439
->getReducedType(opaqueDecl->getGenericSignature());
440-
if (reqt.Protocol) {
440+
if (reqt.isWitnessTable()) {
441441
auto ref =
442-
ProtocolConformanceRef(reqt.Protocol)
443-
.subst(reqt.TypeParameter, archetype->getSubstitutions());
442+
ProtocolConformanceRef(reqt.getProtocol())
443+
.subst(reqt.getTypeParameter(), archetype->getSubstitutions());
444444
args.push_back(emitWitnessTableRef(IGF, ty, ref));
445445
} else {
446+
assert(reqt.isMetadata());
446447
args.push_back(IGF.emitAbstractTypeMetadataRef(ty));
447448
}
448449
types.push_back(args.back()->getType());

lib/IRGen/GenKeyPath.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ emitKeyPathComponent(IRGenModule &IGM,
886886
enumerateGenericSignatureRequirements(
887887
componentCanSig, [&](GenericRequirement reqt) {
888888
auto substType =
889-
reqt.TypeParameter.subst(subs)->getCanonicalType();
889+
reqt.getTypeParameter().subst(subs)->getCanonicalType();
890890

891891
// FIXME: This seems wrong. We used to just mangle opened archetypes as
892892
// their interface type. Let's make that explicit now.
@@ -896,14 +896,17 @@ emitKeyPathComponent(IRGenModule &IGM,
896896
return None;
897897
})->getCanonicalType();
898898

899-
if (!reqt.Protocol) {
899+
if (reqt.isMetadata()) {
900900
// Type requirement.
901901
externalSubArgs.push_back(emitMetadataTypeRefForKeyPath(
902902
IGM, substType, componentCanSig));
903903
} else {
904+
assert(reqt.isWitnessTable());
905+
904906
// Protocol requirement.
905907
auto conformance = subs.lookupConformance(
906-
reqt.TypeParameter->getCanonicalType(), reqt.Protocol);
908+
reqt.getTypeParameter()->getCanonicalType(),
909+
reqt.getProtocol());
907910
externalSubArgs.push_back(IGM.emitWitnessTableRefString(
908911
substType, conformance,
909912
genericEnv ? genericEnv->getGenericSignature() : nullptr,

lib/IRGen/GenMeta.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4250,20 +4250,21 @@ namespace {
42504250
}
42514251

42524252
void addGenericArgument(GenericRequirement requirement) {
4253-
auto t = requirement.TypeParameter.subst(genericSubstitutions());
4253+
auto t = requirement.getTypeParameter().subst(genericSubstitutions());
42544254
ConstantReference ref = IGM.getAddrOfTypeMetadata(
42554255
CanType(t), SymbolReferenceKind::Relative_Direct);
42564256
this->B.add(ref.getDirectValue());
42574257
}
42584258

42594259
void addGenericWitnessTable(GenericRequirement requirement) {
42604260
auto conformance = genericSubstitutions().lookupConformance(
4261-
requirement.TypeParameter->getCanonicalType(), requirement.Protocol);
4261+
requirement.getTypeParameter()->getCanonicalType(),
4262+
requirement.getProtocol());
42624263
ProtocolConformance *concreteConformance = conformance.getConcrete();
42634264

42644265
llvm::Constant *addr;
42654266

4266-
Type argument = requirement.TypeParameter.subst(genericSubstitutions());
4267+
Type argument = requirement.getTypeParameter().subst(genericSubstitutions());
42674268
auto argumentNominal = argument->getAnyNominal();
42684269
if (argumentNominal && argumentNominal->isGenericContext()) {
42694270
// TODO: Statically specialize the witness table pattern for t's

0 commit comments

Comments
 (0)