Skip to content

Commit 5dcc6b1

Browse files
committed
IRGen: Count number of immediate class members in ClassMetadataLayout
1 parent 176efde commit 5dcc6b1

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

lib/IRGen/MetadataLayout.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ Address irgen::emitAddressOfFieldOffsetVector(IRGenFunction &IGF,
203203
/********************************** CLASSES ***********************************/
204204

205205
ClassMetadataLayout::ClassMetadataLayout(IRGenModule &IGM, ClassDecl *decl)
206-
: NominalMetadataLayout(Kind::Class) {
206+
: NominalMetadataLayout(Kind::Class), NumImmediateMembers(0) {
207207

208208
struct Scanner : LayoutScanner<Scanner, ClassMetadataScanner> {
209209
using super = LayoutScanner;
@@ -228,9 +228,26 @@ ClassMetadataLayout::ClassMetadataLayout(IRGenModule &IGM, ClassDecl *decl)
228228
super::noteStartOfGenericRequirements(forClass);
229229
}
230230

231+
void addGenericWitnessTable(CanType argType, ProtocolConformanceRef conf,
232+
ClassDecl *forClass) {
233+
if (forClass == Target) {
234+
Layout.NumImmediateMembers++;
235+
}
236+
super::addGenericWitnessTable(argType, conf, forClass);
237+
}
238+
239+
void addGenericArgument(CanType argType, ClassDecl *forClass) {
240+
if (forClass == Target) {
241+
Layout.NumImmediateMembers++;
242+
}
243+
super::addGenericArgument(argType, forClass);
244+
}
245+
231246
void addMethod(SILDeclRef fn) {
232-
if (fn.getDecl()->getDeclContext() == Target)
247+
if (fn.getDecl()->getDeclContext() == Target) {
248+
Layout.NumImmediateMembers++;
233249
Layout.MethodInfos.try_emplace(fn, getNextOffset());
250+
}
234251
super::addMethod(fn);
235252
}
236253

@@ -241,11 +258,21 @@ ClassMetadataLayout::ClassMetadataLayout(IRGenModule &IGM, ClassDecl *decl)
241258
}
242259

243260
void addFieldOffset(VarDecl *field) {
244-
if (field->getDeclContext() == Target)
261+
if (field->getDeclContext() == Target) {
262+
Layout.NumImmediateMembers++;
245263
Layout.FieldOffsets.try_emplace(field, getNextOffset());
264+
}
246265
super::addFieldOffset(field);
247266
}
248267

268+
void addFieldOffsetPlaceholders(MissingMemberDecl *placeholder) {
269+
if (placeholder->getDeclContext() == Target) {
270+
Layout.NumImmediateMembers +=
271+
placeholder->getNumberOfFieldOffsetVectorEntries();
272+
}
273+
super::addFieldOffsetPlaceholders(placeholder);
274+
}
275+
249276
void addVTableEntries(ClassDecl *forClass) {
250277
if (forClass == Target)
251278
Layout.VTableOffset = getNextOffset();

lib/IRGen/MetadataLayout.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ class ClassMetadataLayout : public NominalMetadataLayout {
168168
/// The start of the field-offset vector.
169169
StoredOffset FieldOffsetVector;
170170

171+
/// The number of members to add after superclass metadata.
172+
unsigned NumImmediateMembers;
173+
171174
const StoredMethodInfo &getStoredMethodInfo(SILDeclRef method) const {
172175
auto it = MethodInfos.find(method);
173176
assert(it != MethodInfos.end());
@@ -222,6 +225,13 @@ class ClassMetadataLayout : public NominalMetadataLayout {
222225

223226
Offset getFieldOffsetVectorOffset(IRGenFunction &IGF) const;
224227

228+
/// The number of members to add after superclass metadata. The size of
229+
/// this metadata is the superclass size plus the number of immediate
230+
/// members in the class itself.
231+
unsigned getNumImmediateMembers() const {
232+
return NumImmediateMembers;
233+
}
234+
225235
static bool classof(const MetadataLayout *layout) {
226236
return layout->getKind() == Kind::Class;
227237
}

0 commit comments

Comments
 (0)