Skip to content

Commit d184122

Browse files
committed
Reflection: Move field and associated type metadata parsing from ReflectionContext to TypeRefBuilder, NFC
ReflectionContext is now solely concerned with converting runtime metadata in a remote address space into a TypeRef. TypeRefBuilder now knows how to parse reflection metadata, and in particular look up associated type witnesses. This decouples the TypeRef substitution code from the ReflectionContext. Now substitution only needs a TypeRefBuilder, which means the code is no longer templated, and can be moved from TypeRef.h to TypeRef.cpp. This also allows the upcoming TypeRef lowering code to live in a source file instead of headers.
1 parent a24e95f commit d184122

File tree

5 files changed

+352
-326
lines changed

5 files changed

+352
-326
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 4 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -41,54 +41,10 @@ class ReflectionContext
4141
using super = remote::MetadataReader<Runtime, TypeRefBuilder>;
4242

4343
public:
44-
using super::decodeMangledType;
44+
using super::getBuilder;
4545
using super::readTypeFromMetadata;
4646
using typename super::StoredPointer;
4747

48-
private:
49-
50-
std::vector<ReflectionInfo> ReflectionInfos;
51-
52-
void dumpTypeRef(const std::string &MangledName,
53-
std::ostream &OS, bool printTypeName = false) {
54-
auto TypeName = Demangle::demangleTypeAsString(MangledName);
55-
OS << TypeName << '\n';
56-
57-
auto DemangleTree = Demangle::demangleTypeAsNode(MangledName);
58-
auto TR = decodeMangledType(DemangleTree);
59-
if (!TR) {
60-
OS << "!!! Invalid typeref: " << MangledName << '\n';
61-
return;
62-
}
63-
TR->dump(OS);
64-
OS << '\n';
65-
}
66-
67-
const AssociatedTypeDescriptor *
68-
lookupAssociatedTypes(const std::string &MangledTypeName,
69-
const DependentMemberTypeRef *DependentMember) {
70-
// Cache missed - we need to look through all of the assocty sections
71-
// for all images that we've been notified about.
72-
for (auto &Info : ReflectionInfos) {
73-
for (const auto &AssocTyDescriptor : Info.assocty) {
74-
std::string ConformingTypeName(AssocTyDescriptor.ConformingTypeName);
75-
if (ConformingTypeName.compare(MangledTypeName) != 0)
76-
continue;
77-
std::string ProtocolMangledName(AssocTyDescriptor.ProtocolTypeName);
78-
auto DemangledProto = Demangle::demangleTypeAsNode(ProtocolMangledName);
79-
auto TR = decodeMangledType(DemangledProto);
80-
81-
auto &Conformance = *DependentMember->getProtocol();
82-
if (auto Protocol = dyn_cast<ProtocolTypeRef>(TR)) {
83-
if (*Protocol != Conformance)
84-
continue;
85-
return &AssocTyDescriptor;
86-
}
87-
}
88-
}
89-
return nullptr;
90-
}
91-
9248
public:
9349

9450
explicit ReflectionContext(std::shared_ptr<MemoryReader> reader)
@@ -101,137 +57,13 @@ class ReflectionContext
10157
return *this->Reader;
10258
}
10359

104-
void dumpFieldSection(std::ostream &OS) {
105-
for (const auto &sections : ReflectionInfos) {
106-
for (const auto &descriptor : sections.fieldmd) {
107-
auto TypeName
108-
= Demangle::demangleTypeAsString(descriptor.getMangledTypeName());
109-
OS << TypeName << '\n';
110-
for (size_t i = 0; i < TypeName.size(); ++i)
111-
OS << '-';
112-
OS << '\n';
113-
for (auto &field : descriptor) {
114-
OS << field.getFieldName();
115-
if (field.hasMangledTypeName()) {
116-
OS << ": ";
117-
dumpTypeRef(field.getMangledTypeName(), OS);
118-
} else {
119-
OS << "\n\n";
120-
}
121-
}
122-
}
123-
}
124-
}
125-
126-
void dumpAssociatedTypeSection(std::ostream &OS) {
127-
for (const auto &sections : ReflectionInfos) {
128-
for (const auto &descriptor : sections.assocty) {
129-
auto conformingTypeName = Demangle::demangleTypeAsString(
130-
descriptor.getMangledConformingTypeName());
131-
auto protocolName = Demangle::demangleTypeAsString(
132-
descriptor.getMangledProtocolTypeName());
133-
134-
OS << "- " << conformingTypeName << " : " << protocolName;
135-
OS << '\n';
136-
137-
for (const auto &associatedType : descriptor) {
138-
OS << "typealias " << associatedType.getName() << " = ";
139-
dumpTypeRef(associatedType.getMangledSubstitutedTypeName(), OS);
140-
}
141-
}
142-
}
143-
}
144-
145-
void dumpBuiltinTypeSection(std::ostream &OS) {
146-
for (const auto &sections : ReflectionInfos) {
147-
for (const auto &descriptor : sections.builtin) {
148-
auto typeName = Demangle::demangleTypeAsString(
149-
descriptor.getMangledTypeName());
150-
151-
OS << "\n- " << typeName << ":\n";
152-
OS << "Size: " << descriptor.Size << "\n";
153-
OS << "Alignment: " << descriptor.Alignment << "\n";
154-
OS << "Stride: " << descriptor.Stride << "\n";
155-
OS << "NumExtraInhabitants: " << descriptor.NumExtraInhabitants << "\n";
156-
}
157-
}
158-
}
159-
16060
void dumpAllSections(std::ostream &OS) {
161-
OS << "FIELDS:\n";
162-
OS << "=======\n";
163-
dumpFieldSection(OS);
164-
OS << '\n';
165-
OS << "ASSOCIATED TYPES:\n";
166-
OS << "=================\n";
167-
dumpAssociatedTypeSection(OS);
168-
OS << '\n';
169-
OS << "BUILTIN TYPES:\n";
170-
OS << "==============\n";
171-
dumpBuiltinTypeSection(OS);
172-
OS << '\n';
173-
}
174-
175-
const TypeRef *
176-
getDependentMemberTypeRef(const std::string &MangledTypeName,
177-
const DependentMemberTypeRef *DependentMember) {
178-
179-
if (auto AssocTys = lookupAssociatedTypes(MangledTypeName, DependentMember)) {
180-
for (auto &AssocTy : *AssocTys) {
181-
if (DependentMember->getMember().compare(AssocTy.getName()) != 0)
182-
continue;
183-
184-
auto SubstitutedTypeName = AssocTy.getMangledSubstitutedTypeName();
185-
auto Demangled = Demangle::demangleTypeAsNode(SubstitutedTypeName);
186-
return decodeMangledType(Demangled);
187-
}
188-
}
189-
return nullptr;
61+
getBuilder().dumpAllSections();
19062
}
19163

19264
std::vector<std::pair<std::string, const TypeRef *>>
19365
getFieldTypeRefs(const TypeRef *TR) {
194-
std::string MangledName;
195-
if (auto N = dyn_cast<NominalTypeRef>(TR))
196-
MangledName = N->getMangledName();
197-
else if (auto BG = dyn_cast<BoundGenericTypeRef>(TR))
198-
MangledName = BG->getMangledName();
199-
else
200-
return {};
201-
202-
auto Subs = TR->getSubstMap();
203-
204-
std::vector<std::pair<std::string, const TypeRef *>> Fields;
205-
for (auto Info : ReflectionInfos) {
206-
for (auto &FieldDescriptor : Info.fieldmd) {
207-
auto CandidateMangledName = FieldDescriptor.MangledTypeName.get();
208-
if (!CandidateMangledName)
209-
continue;
210-
if (MangledName.compare(CandidateMangledName) != 0)
211-
continue;
212-
for (auto &Field : FieldDescriptor) {
213-
auto FieldName = Field.getFieldName();
214-
215-
// Empty cases of enums do not have a type
216-
if (!Field.hasMangledTypeName()) {
217-
Fields.push_back({FieldName, nullptr});
218-
continue;
219-
}
220-
221-
auto Demangled
222-
= Demangle::demangleTypeAsNode(Field.getMangledTypeName());
223-
auto Unsubstituted = decodeMangledType(Demangled);
224-
if (!Unsubstituted)
225-
return {};
226-
227-
auto Substituted = Unsubstituted->subst(*this, Subs);
228-
if (FieldName.empty())
229-
FieldName = "<Redacted Field Name>";
230-
Fields.push_back({FieldName, Substituted});
231-
}
232-
}
233-
}
234-
return Fields;
66+
return getBuilder().getFieldTypeRefs(TR);
23567
}
23668

23769
std::vector<std::pair<std::string, const TypeRef *>>
@@ -241,7 +73,7 @@ class ReflectionContext
24173
}
24274

24375
void addReflectionInfo(ReflectionInfo I) {
244-
ReflectionInfos.push_back(I);
76+
getBuilder().addReflectionInfo(I);
24577
}
24678

24779
swift_typeinfo_t getInfoForTypeRef(const TypeRef *TR) {

include/swift/Reflection/TypeRef.h

Lines changed: 2 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@
2626
namespace swift {
2727
namespace reflection {
2828

29-
template <typename Allocator>
30-
class ReflectionContext;
31-
32-
struct ReflectionInfo;
33-
3429
using llvm::cast;
3530
using llvm::dyn_cast;
3631

@@ -41,6 +36,7 @@ enum class TypeRefKind {
4136
};
4237

4338
class TypeRef;
39+
class TypeRefBuilder;
4440
using DepthAndIndex = std::pair<unsigned, unsigned>;
4541
using GenericArgumentMap = llvm::DenseMap<DepthAndIndex, const TypeRef *>;
4642

@@ -59,9 +55,8 @@ class alignas(void *) TypeRef {
5955

6056
bool isConcrete() const;
6157

62-
template <typename Runtime>
6358
const TypeRef *
64-
subst(ReflectionContext<Runtime> &RC, GenericArgumentMap Subs) const;
59+
subst(TypeRefBuilder &Builder, GenericArgumentMap Subs) const;
6560

6661
GenericArgumentMap getSubstMap() const;
6762

@@ -520,139 +515,6 @@ class TypeRefVisitor {
520515
}
521516
};
522517

523-
template <typename Runtime>
524-
class TypeRefSubstitution
525-
: public TypeRefVisitor<TypeRefSubstitution<Runtime>, const TypeRef *> {
526-
using StoredPointer = typename Runtime::StoredPointer;
527-
ReflectionContext<Runtime> &RC;
528-
GenericArgumentMap Substitutions;
529-
public:
530-
using TypeRefVisitor<TypeRefSubstitution<Runtime>, const TypeRef *>::visit;
531-
TypeRefSubstitution(ReflectionContext<Runtime> &RC,
532-
GenericArgumentMap Substitutions)
533-
: RC(RC),
534-
Substitutions(Substitutions) {}
535-
536-
const TypeRef *visitBuiltinTypeRef(const BuiltinTypeRef *B) {
537-
return B;
538-
}
539-
540-
const TypeRef *visitNominalTypeRef(const NominalTypeRef *N) {
541-
return N;
542-
}
543-
544-
const TypeRef *visitBoundGenericTypeRef(const BoundGenericTypeRef *BG) {
545-
std::vector<const TypeRef *> GenericParams;
546-
for (auto Param : BG->getGenericParams())
547-
GenericParams.push_back(visit(Param));
548-
return BoundGenericTypeRef::create(RC.Builder, BG->getMangledName(),
549-
GenericParams);
550-
}
551-
552-
const TypeRef *visitTupleTypeRef(const TupleTypeRef *T) {
553-
std::vector<const TypeRef *> Elements;
554-
for (auto Element : T->getElements()) {
555-
Elements.push_back(visit(Element));
556-
}
557-
return TupleTypeRef::create(RC.Builder, Elements);
558-
}
559-
560-
const TypeRef *visitFunctionTypeRef(const FunctionTypeRef *F) {
561-
std::vector<const TypeRef *> SubstitutedArguments;
562-
for (auto Argument : F->getArguments())
563-
SubstitutedArguments.push_back(visit(Argument));
564-
565-
auto SubstitutedResult = visit(F->getResult());
566-
567-
return FunctionTypeRef::create(RC.Builder, SubstitutedArguments,
568-
SubstitutedResult);
569-
}
570-
571-
const TypeRef *visitProtocolTypeRef(const ProtocolTypeRef *P) {
572-
return P;
573-
}
574-
575-
const TypeRef *
576-
visitProtocolCompositionTypeRef(const ProtocolCompositionTypeRef *PC) {
577-
return PC;
578-
}
579-
580-
const TypeRef *visitMetatypeTypeRef(const MetatypeTypeRef *M) {
581-
return MetatypeTypeRef::create(RC.Builder, visit(M->getInstanceType()));
582-
}
583-
584-
const TypeRef *
585-
visitExistentialMetatypeTypeRef(const ExistentialMetatypeTypeRef *EM) {
586-
assert(EM->getInstanceType()->isConcrete());
587-
return EM;
588-
}
589-
590-
const TypeRef *
591-
visitGenericTypeParameterTypeRef(const GenericTypeParameterTypeRef *GTP) {
592-
auto found = Substitutions.find({GTP->getDepth(), GTP->getIndex()});
593-
assert(found != Substitutions.end());
594-
assert(found->second->isConcrete());
595-
return found->second;
596-
}
597-
598-
const TypeRef *visitDependentMemberTypeRef(const DependentMemberTypeRef *DM) {
599-
auto SubstBase = visit(DM->getBase());
600-
601-
const TypeRef *TypeWitness;
602-
603-
switch (SubstBase->getKind()) {
604-
case TypeRefKind::Nominal: {
605-
auto Nominal = cast<NominalTypeRef>(SubstBase);
606-
TypeWitness = RC.getDependentMemberTypeRef(Nominal->getMangledName(), DM);
607-
break;
608-
}
609-
case TypeRefKind::BoundGeneric: {
610-
auto BG = cast<BoundGenericTypeRef>(SubstBase);
611-
TypeWitness = RC.getDependentMemberTypeRef(BG->getMangledName(), DM);
612-
break;
613-
}
614-
default:
615-
assert(false && "Unknown base type");
616-
}
617-
618-
assert(TypeWitness);
619-
return TypeWitness->subst(RC, SubstBase->getSubstMap());
620-
}
621-
622-
const TypeRef *visitForeignClassTypeRef(const ForeignClassTypeRef *F) {
623-
return F;
624-
}
625-
626-
const TypeRef *visitObjCClassTypeRef(const ObjCClassTypeRef *OC) {
627-
return OC;
628-
}
629-
630-
const TypeRef *visitUnownedStorageTypeRef(const UnownedStorageTypeRef *US) {
631-
return UnownedStorageTypeRef::create(RC.Builder, visit(US->getType()));
632-
}
633-
634-
const TypeRef *visitWeakStorageTypeRef(const WeakStorageTypeRef *WS) {
635-
return WeakStorageTypeRef::create(RC.Builder, visit(WS->getType()));
636-
}
637-
638-
const TypeRef *
639-
visitUnmanagedStorageTypeRef(const UnmanagedStorageTypeRef *US) {
640-
return UnmanagedStorageTypeRef::create(RC.Builder, visit(US->getType()));
641-
}
642-
643-
const TypeRef *visitOpaqueTypeRef(const OpaqueTypeRef *Op) {
644-
return Op;
645-
}
646-
};
647-
648-
template <typename Runtime>
649-
const TypeRef *
650-
TypeRef::subst(ReflectionContext<Runtime> &RC, GenericArgumentMap Subs) const {
651-
const TypeRef *Result = TypeRefSubstitution<Runtime>(RC, Subs).visit(this);
652-
assert(Result->isConcrete());
653-
return Result;
654-
}
655-
656518
} // end namespace reflection
657519
} // end namespace swift
658520

0 commit comments

Comments
 (0)