Skip to content

Commit d710b52

Browse files
committed
Add Substitution Machinery to Builders
Add requirements to the Builder concept to construct generic signatures and substitution maps. Then introduce a `subst` requirement that uses the substitution map to call through to the builder's notion of type (ref) substitution. This infrastructure is sufficient to model the notion of a RuntimeGenericSignature.
1 parent a410d1a commit d710b52

File tree

7 files changed

+137
-7
lines changed

7 files changed

+137
-7
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,11 @@ class ASTBuilder {
5959
using BuiltType = swift::Type;
6060
using BuiltTypeDecl = swift::GenericTypeDecl *; // nominal or type alias
6161
using BuiltProtocolDecl = swift::ProtocolDecl *;
62+
using BuiltGenericSignature = swift::GenericSignature;
6263
using BuiltGenericTypeParam = swift::GenericTypeParamType *;
6364
using BuiltRequirement = swift::Requirement;
65+
using BuiltSubstitutionMap = swift::SubstitutionMap;
66+
6467
explicit ASTBuilder(ASTContext &ctx) : Ctx(ctx) {}
6568

6669
ASTContext &getASTContext() { return Ctx; }
@@ -114,6 +117,8 @@ class ASTBuilder {
114117
bool isClassBound,
115118
bool forRequirement = true);
116119

120+
Type createProtocolTypeFromDecl(ProtocolDecl *protocol);
121+
117122
Type createParameterizedProtocolType(Type base, ArrayRef<Type> args);
118123

119124
Type createExistentialMetatypeType(Type instance,
@@ -168,6 +173,15 @@ class ASTBuilder {
168173

169174
Type createParenType(Type base);
170175

176+
BuiltGenericSignature
177+
createGenericSignature(ArrayRef<BuiltType> params,
178+
ArrayRef<BuiltRequirement> requirements);
179+
180+
BuiltSubstitutionMap createSubstitutionMap(BuiltGenericSignature sig,
181+
ArrayRef<BuiltType> replacements);
182+
183+
Type subst(Type subject, const BuiltSubstitutionMap &Subs) const;
184+
171185
LayoutConstraint getLayoutConstraint(LayoutConstraintKind kind);
172186
LayoutConstraint getLayoutConstraintWithSizeAlign(LayoutConstraintKind kind,
173187
unsigned size,

include/swift/Demangling/TypeDecoder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,8 @@ class TypeDecoder {
465465
using BuiltRequirement = typename BuilderType::BuiltRequirement;
466466
using BuiltLayoutConstraint = typename BuilderType::BuiltLayoutConstraint;
467467
using BuiltGenericTypeParam = typename BuilderType::BuiltGenericTypeParam;
468+
using BuiltGenericSignature = typename BuilderType::BuiltGenericSignature;
469+
using BuiltSubstitutionMap = typename BuilderType::BuiltSubstitutionMap;
468470
using NodeKind = Demangle::Node::Kind;
469471

470472
BuilderType &Builder;

include/swift/Reflection/TypeRef.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,37 @@ class DependentMemberTypeRef final : public TypeRef {
741741
}
742742
};
743743

744+
/// A representation of a dynamically-constructed generic signature.
745+
///
746+
/// \note This class is not a \c TypeRef.
747+
class GenericSignatureRef final {
748+
std::vector<const GenericTypeParameterTypeRef *> Params;
749+
std::vector<TypeRefRequirement> Requirements;
750+
751+
public:
752+
GenericSignatureRef(
753+
llvm::ArrayRef<const GenericTypeParameterTypeRef *> Params,
754+
llvm::ArrayRef<TypeRefRequirement> Requirements)
755+
: Params(Params.begin(), Params.end()),
756+
Requirements(Requirements.begin(), Requirements.end()) {}
757+
758+
template <typename Allocator>
759+
static const GenericSignatureRef *
760+
create(Allocator &A,
761+
llvm::ArrayRef<const GenericTypeParameterTypeRef *> Params,
762+
llvm::ArrayRef<TypeRefRequirement> Requirements) {
763+
return A.template makeGenericSignatureRef(Params, Requirements);
764+
}
765+
766+
const llvm::ArrayRef<const GenericTypeParameterTypeRef *> getParams() const {
767+
return Params;
768+
}
769+
770+
const llvm::ArrayRef<TypeRefRequirement> getRequirements() const {
771+
return Requirements;
772+
}
773+
};
774+
744775
class ForeignClassTypeRef final : public TypeRef {
745776
std::string Name;
746777

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,8 @@ class TypeRefBuilder {
360360
using BuiltRequirement = TypeRefRequirement;
361361
using BuiltLayoutConstraint = TypeRefLayoutConstraint;
362362
using BuiltGenericTypeParam = const GenericTypeParameterTypeRef *;
363+
using BuiltGenericSignature = const GenericSignatureRef *;
364+
using BuiltSubstitutionMap = llvm::DenseMap<DepthAndIndex, const TypeRef *>;
363365

364366
TypeRefBuilder(const TypeRefBuilder &other) = delete;
365367
TypeRefBuilder &operator=(const TypeRefBuilder &other) = delete;
@@ -378,6 +380,8 @@ class TypeRefBuilder {
378380
/// Cache for field info lookups.
379381
std::unordered_map<std::string, RemoteRef<FieldDescriptor>> FieldTypeInfoCache;
380382

383+
std::vector<std::unique_ptr<const GenericSignatureRef>> SignatureRefPool;
384+
381385
TypeConverter TC;
382386
MetadataSourceBuilder MSB;
383387

@@ -394,6 +398,13 @@ class TypeRefBuilder {
394398
return TR;
395399
}
396400

401+
template <typename... Args>
402+
const GenericSignatureRef *makeGenericSignatureRef(Args... args) {
403+
const auto TR = new GenericSignatureRef(::std::forward<Args>(args)...);
404+
SignatureRefPool.push_back(std::unique_ptr<const GenericSignatureRef>(TR));
405+
return TR;
406+
}
407+
397408
Demangle::NodeFactory &getNodeFactory() { return Dem; }
398409

399410
void clearNodeFactory() { Dem.clear(); }
@@ -599,6 +610,14 @@ class TypeRefBuilder {
599610
*this, {}, result, funcFlags, diffKind, nullptr);
600611
}
601612

613+
BuiltType createProtocolTypeFromDecl(BuiltProtocolDecl protocol) {
614+
if (protocol->second) {
615+
return llvm::cast<TypeRef>(createObjCProtocolType(protocol->first));
616+
} else {
617+
return llvm::cast<TypeRef>(createNominalType(protocol->first));
618+
}
619+
}
620+
602621
const ProtocolCompositionTypeRef *
603622
createProtocolCompositionType(llvm::ArrayRef<BuiltProtocolDecl> protocols,
604623
BuiltType superclass, bool isClassBound,
@@ -608,10 +627,10 @@ class TypeRefBuilder {
608627
if (!protocol)
609628
continue;
610629

611-
if (protocol->second)
612-
protocolRefs.push_back(createObjCProtocolType(protocol->first));
613-
else
614-
protocolRefs.push_back(createNominalType(protocol->first));
630+
auto protocolType = createProtocolTypeFromDecl(*protocol);
631+
if (!protocolType)
632+
continue;
633+
protocolRefs.push_back(protocolType);
615634
}
616635

617636
return ProtocolCompositionTypeRef::create(*this, protocolRefs, superclass,
@@ -720,8 +739,7 @@ class TypeRefBuilder {
720739
return createObjCClassType(name);
721740
}
722741

723-
const ObjCProtocolTypeRef *
724-
createObjCProtocolType(const std::string &name) {
742+
const ObjCProtocolTypeRef *createObjCProtocolType(const std::string &name) {
725743
return ObjCProtocolTypeRef::create(*this, name);
726744
}
727745

@@ -739,6 +757,41 @@ class TypeRefBuilder {
739757
return OpaqueTypeRef::get();
740758
}
741759

760+
BuiltGenericSignature
761+
createGenericSignature(llvm::ArrayRef<BuiltType> builtParams,
762+
llvm::ArrayRef<BuiltRequirement> requirements) {
763+
std::vector<BuiltGenericTypeParam> params;
764+
for (auto &builtParam : builtParams) {
765+
auto *genericRef =
766+
llvm::dyn_cast<GenericTypeParameterTypeRef>(builtParam);
767+
if (!genericRef)
768+
return nullptr;
769+
params.push_back(genericRef);
770+
}
771+
return GenericSignatureRef::create(*this, params, requirements);
772+
}
773+
774+
BuiltSubstitutionMap
775+
createSubstitutionMap(BuiltGenericSignature sig,
776+
llvm::ArrayRef<BuiltType> replacements) {
777+
assert(sig->getParams().size() == replacements.size() &&
778+
"Not enough replacement parameters!");
779+
if (sig->getParams().size() != replacements.size())
780+
return BuiltSubstitutionMap{};
781+
782+
BuiltSubstitutionMap map{};
783+
for (unsigned paramIdx : indices(sig->getParams())) {
784+
const auto *param = sig->getParams()[paramIdx];
785+
auto replacement = replacements[paramIdx];
786+
map[{param->getDepth(), param->getIndex()}] = replacement;
787+
}
788+
return map;
789+
}
790+
791+
BuiltType subst(BuiltType subject, const BuiltSubstitutionMap &Subs) {
792+
return subject->subst(*this, Subs);
793+
}
794+
742795
///
743796
/// Parsing reflection metadata
744797
///

include/swift/Remote/MetadataReader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ class MetadataReader {
166166
using BuiltProtocolDecl = typename BuilderType::BuiltProtocolDecl;
167167
using BuiltRequirement = typename BuilderType::BuiltRequirement;
168168
using BuiltSubstitution = typename BuilderType::BuiltSubstitution;
169+
using BuiltSubstitutionMap = typename BuilderType::BuiltSubstitutionMap;
169170
using BuiltGenericTypeParam = typename BuilderType::BuiltGenericTypeParam;
171+
using BuiltGenericSignature = typename BuilderType::BuiltGenericSignature;
170172
using StoredPointer = typename Runtime::StoredPointer;
171173
using StoredSignedPointer = typename Runtime::StoredSignedPointer;
172174
using StoredSize = typename Runtime::StoredSize;

lib/AST/ASTDemangler.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,10 @@ Type ASTBuilder::createProtocolCompositionType(
595595
return ExistentialType::get(composition);
596596
}
597597

598+
Type ASTBuilder::createProtocolTypeFromDecl(ProtocolDecl *protocol) {
599+
return protocol->getDeclaredInterfaceType();
600+
}
601+
598602
static MetatypeRepresentation
599603
getMetatypeRepresentation(ImplMetatypeRepresentation repr) {
600604
switch (repr) {
@@ -794,6 +798,29 @@ Type ASTBuilder::createParenType(Type base) {
794798
return ParenType::get(Ctx, base);
795799
}
796800

801+
GenericSignature
802+
ASTBuilder::createGenericSignature(ArrayRef<BuiltType> builtParams,
803+
ArrayRef<BuiltRequirement> requirements) {
804+
std::vector<BuiltGenericTypeParam> params;
805+
for (auto &param : builtParams) {
806+
auto paramTy = param->getAs<GenericTypeParamType>();
807+
if (!paramTy)
808+
return GenericSignature();
809+
params.push_back(paramTy);
810+
}
811+
return GenericSignature::get(params, requirements);
812+
}
813+
814+
SubstitutionMap
815+
ASTBuilder::createSubstitutionMap(BuiltGenericSignature sig,
816+
ArrayRef<BuiltType> replacements) {
817+
return SubstitutionMap::get(sig, replacements, {});
818+
}
819+
820+
Type ASTBuilder::subst(Type subject, const BuiltSubstitutionMap &Subs) const {
821+
return subject.subst(Subs);
822+
}
823+
797824
bool ASTBuilder::validateParentType(TypeDecl *decl, Type parent) {
798825
auto parentDecl = decl->getDeclContext()->getSelfNominalTypeDecl();
799826

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,9 @@ class DecodedMetadataBuilder {
13341334
using BuiltType = const Metadata *;
13351335
using BuiltTypeDecl = const ContextDescriptor *;
13361336
using BuiltProtocolDecl = ProtocolDescriptorRef;
1337+
using BuiltGenericSignature = const Metadata *;
13371338
using BuiltSubstitution = std::pair<BuiltType, BuiltType>;
1339+
using BuiltSubstitutionMap = llvm::ArrayRef<BuiltSubstitution>;
13381340
using BuiltGenericTypeParam = const Metadata *;
13391341

13401342
BuiltType decodeMangledType(NodePointer node,
@@ -1659,7 +1661,6 @@ class DecodedMetadataBuilder {
16591661
}
16601662

16611663
using BuiltSILBoxField = llvm::PointerIntPair<BuiltType, 1>;
1662-
using BuiltSubstitution = std::pair<BuiltType, BuiltType>;
16631664
struct BuiltLayoutConstraint {
16641665
bool operator==(BuiltLayoutConstraint rhs) const { return true; }
16651666
operator bool() const { return true; }

0 commit comments

Comments
 (0)