Skip to content

Commit 6a51ae8

Browse files
committed
Add Self- and SelfWitnessTable metadata sources to capture descriptors
These can show up in partial applications of functions with the witness_method calling convention.
1 parent 09d0cfe commit 6a51ae8

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed

include/swift/Reflection/MetadataSource.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ class MetadataSource {
182182
return decodeGenericArgument(A, it, end);
183183
case 'P':
184184
return decodeParent(A, it, end);
185+
case 'S':
186+
++it;
187+
return A.template createSelf();
185188
default:
186189
return nullptr;
187190
}
@@ -315,6 +318,7 @@ class GenericArgumentMetadataSource final : public MetadataSource {
315318
}
316319
};
317320

321+
/// Metadata gotten through the parent of a nominal type's metadata.
318322
class ParentMetadataSource final : public MetadataSource {
319323
const MetadataSource *Child;
320324
public:
@@ -337,6 +341,41 @@ class ParentMetadataSource final : public MetadataSource {
337341
}
338342
};
339343

344+
/// A source of metadata from the Self metadata parameter passed via
345+
/// a witness_method convention function.
346+
class SelfMetadataSource final : public MetadataSource {
347+
public:
348+
SelfMetadataSource() : MetadataSource(MetadataSourceKind::Self) {}
349+
350+
template <typename Allocator>
351+
static const SelfMetadataSource*
352+
create(Allocator &A) {
353+
return A.template make_source<SelfMetadataSource>();
354+
}
355+
356+
static bool classof(const MetadataSource *MS) {
357+
return MS->getKind() == MetadataSourceKind::Self;
358+
}
359+
};
360+
361+
/// A source of metadata from the Self witness table parameter passed via
362+
/// a witness_method convention function.
363+
class SelfWitnessTableMetadataSource final : public MetadataSource {
364+
public:
365+
SelfWitnessTableMetadataSource()
366+
: MetadataSource(MetadataSourceKind::SelfWitnessTable) {}
367+
368+
template <typename Allocator>
369+
static const SelfWitnessTableMetadataSource*
370+
create(Allocator &A) {
371+
return A.template make_source<SelfWitnessTableMetadataSource>();
372+
}
373+
374+
static bool classof(const MetadataSource *MS) {
375+
return MS->getKind() == MetadataSourceKind::SelfWitnessTable;
376+
}
377+
};
378+
340379
template <typename ImplClass, typename RetTy = void, typename... Args>
341380
class MetadataSourceVisitor {
342381
public:

include/swift/Reflection/MetadataSourceBuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ class MetadataSourceBuilder {
6262
createParent(const MetadataSource *Child) {
6363
return ParentMetadataSource::create(*this, Child);
6464
}
65+
66+
const SelfMetadataSource *
67+
createSelf() {
68+
return SelfMetadataSource::create(*this);
69+
}
70+
71+
const SelfWitnessTableMetadataSource *
72+
createSelfWitnessTable() {
73+
return SelfWitnessTableMetadataSource::create(*this);
74+
}
6575
};
6676

6777
} // end namespace reflection

include/swift/Reflection/MetadataSources.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ METADATA_SOURCE(ReferenceCapture, MetadataSource)
2121
METADATA_SOURCE(MetadataCapture, MetadataSource)
2222
METADATA_SOURCE(GenericArgument, MetadataSource)
2323
METADATA_SOURCE(Parent, MetadataSource)
24+
METADATA_SOURCE(Self, MetadataSource)
25+
METADATA_SOURCE(SelfWitnessTable, MetadataSource)

lib/IRGen/GenReflection.cpp

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ class MetadataSourceEncoder
7070
visit(P->getChild());
7171
OS << '_';
7272
}
73+
74+
void visitSelfMetadataSource(const SelfMetadataSource *S) {
75+
OS << 'S';
76+
}
77+
78+
void
79+
visitSelfWitnessTableMetadataSource(const SelfWitnessTableMetadataSource *S) {
80+
OS << 'W';
81+
}
7382
};
7483

7584
class PrintMetadataSource
@@ -148,6 +157,18 @@ class PrintMetadataSource
148157
printRec(P->getChild());
149158
closeForm();
150159
}
160+
161+
void
162+
visitSelfMetadataSource(const SelfMetadataSource *S) {
163+
printHeader("self");
164+
closeForm();
165+
}
166+
167+
void
168+
visitSelfWitnessTableMetadataSource(const SelfWitnessTableMetadataSource *S) {
169+
printHeader("self-witness-table");
170+
closeForm();
171+
}
151172
};
152173

153174
class ReflectionMetadataBuilder : public ConstantBuilder<> {
@@ -511,6 +532,8 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
511532

512533
PolymorphicConvention Convention(IGM, CalleeType);
513534

535+
using SourceKind = PolymorphicConvention::SourceKind;
536+
514537
auto Generics = Callee.getContextGenericParams()->getNestedGenericParams();
515538
for (auto GenericParam : Generics) {
516539
// The generic type parameter (depth, index) serves as the key to the
@@ -527,11 +550,22 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
527550
// The convention fulfills the requirement, so record how to get
528551
// to the metadata.
529552

553+
auto ConventionSource = Convention.getSource(Fulfillment->SourceIndex);
554+
if (ConventionSource.getKind() == SourceKind::SelfMetadata) {
555+
SourceMap.insert({GenericParamType, SourceBuilder.createSelf()});
556+
continue;
557+
} else if (ConventionSource.getKind() == SourceKind::SelfWitnessTable) {
558+
SourceMap.insert({
559+
GenericParamType,
560+
SourceBuilder.createSelfWitnessTable()
561+
});
562+
continue;
563+
}
564+
530565
// Since captures are created via partial_apply instructions, we need
531566
// to see which function parameter fulfilled this metadata need and
532567
// grab its type.
533-
auto FnParameterIndex
534-
= Convention.getSource(Fulfillment->SourceIndex).getParamIndex();
568+
auto FnParameterIndex = ConventionSource.getParamIndex();
535569
auto FnParameter = CalleeType->getParameters()[FnParameterIndex];
536570
auto ParameterType = FnParameter.getType()->getCanonicalType();
537571

stdlib/public/Reflection/MetadataSource.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ class PrintMetadataSource
9393
printRec(P->getChild());
9494
closeForm();
9595
}
96+
97+
void visitSelfMetadataSource(const SelfMetadataSource *S) {
98+
printHeader("self");
99+
closeForm();
100+
}
101+
102+
void
103+
visitSelfWitnessTableMetadataSource(const SelfWitnessTableMetadataSource *W) {
104+
printHeader("self-witness-table");
105+
closeForm();
106+
}
96107
};
97108

98109
void MetadataSource::dump() const {

0 commit comments

Comments
 (0)