@@ -252,7 +252,10 @@ bool SILGenModule::requiresObjCMethodEntryPoint(ConstructorDecl *constructor) {
252
252
namespace {
253
253
254
254
// / An ASTVisitor for populating SILVTable entries from ClassDecl members.
255
- class SILGenVTable : public SILVTableVisitor <SILGenVTable> {
255
+ template <typename T>
256
+ class SILGenVTableBase : public SILVTableVisitor <T> {
257
+ T &asDerived () { return *static_cast <T *>(this ); }
258
+
256
259
public:
257
260
SILGenModule &SGM;
258
261
ClassDecl *theClass;
@@ -267,14 +270,61 @@ class SILGenVTable : public SILVTableVisitor<SILGenVTable> {
267
270
// For each base method, store the corresponding override.
268
271
SmallVector<VTableMethod, 8 > vtableMethods;
269
272
270
- SILGenVTable (SILGenModule &SGM, ClassDecl *theClass)
271
- : SGM(SGM), theClass(theClass) {
273
+ SILGenVTableBase (SILGenModule &SGM, ClassDecl *theClass)
274
+ : SGM(SGM), theClass(theClass) {
272
275
isResilient = theClass->isResilient ();
273
276
}
274
277
275
278
// / Populate our list of base methods and overrides.
276
279
void collectMethods () { visitAncestor (theClass); }
277
280
281
+ void visitAncestor (ClassDecl *ancestor) {
282
+ // Imported types don't have vtables right now.
283
+ if (ancestor->hasClangNode ())
284
+ return ;
285
+
286
+ auto *superDecl = ancestor->getSuperclassDecl ();
287
+ if (superDecl)
288
+ visitAncestor (superDecl);
289
+
290
+ asDerived ().addVTableEntries (ancestor);
291
+ }
292
+
293
+ // Try to find an overridden entry.
294
+ void addMethodOverride (SILDeclRef baseRef, SILDeclRef declRef) {
295
+ auto found = baseToIndexMap.find (baseRef);
296
+ assert (found != baseToIndexMap.end ());
297
+ auto &method = vtableMethods[found->second ];
298
+ assert (method.first == baseRef);
299
+ method.second = declRef;
300
+ }
301
+
302
+ // Add an entry to the vtable.
303
+ void addMethod (SILDeclRef member) {
304
+ unsigned index = vtableMethods.size ();
305
+ vtableMethods.push_back (std::make_pair (member, member));
306
+ auto result = baseToIndexMap.insert (std::make_pair (member, index));
307
+ assert (result.second );
308
+ (void )result;
309
+ }
310
+
311
+ void addPlaceholder (MissingMemberDecl *m) {
312
+ #ifndef NDEBUG
313
+ auto *classDecl = cast<ClassDecl>(m->getDeclContext ());
314
+ bool isResilient = classDecl->isResilient (SGM.M .getSwiftModule (),
315
+ ResilienceExpansion::Maximal);
316
+ assert (isResilient ||
317
+ m->getNumberOfVTableEntries () == 0 &&
318
+ " Should not be emitting fragile class with missing members" );
319
+ #endif
320
+ }
321
+ };
322
+
323
+ class SILGenVTable : public SILGenVTableBase <SILGenVTable> {
324
+ public:
325
+ SILGenVTable (SILGenModule &SGM, ClassDecl *theClass)
326
+ : SILGenVTableBase(SGM, theClass) {}
327
+
278
328
void emitVTable () {
279
329
PrettyStackTraceDecl (" silgen emitVTable" , theClass);
280
330
@@ -326,49 +376,7 @@ class SILGenVTable : public SILVTableVisitor<SILGenVTable> {
326
376
// Finally, create the vtable.
327
377
SILVTable::create (SGM.M , theClass, serialized, vtableEntries);
328
378
}
329
-
330
- void visitAncestor (ClassDecl *ancestor) {
331
- // Imported types don't have vtables right now.
332
- if (ancestor->hasClangNode ())
333
- return ;
334
-
335
- auto *superDecl = ancestor->getSuperclassDecl ();
336
- if (superDecl)
337
- visitAncestor (superDecl);
338
-
339
- addVTableEntries (ancestor);
340
- }
341
-
342
- // Try to find an overridden entry.
343
- void addMethodOverride (SILDeclRef baseRef, SILDeclRef declRef) {
344
- auto found = baseToIndexMap.find (baseRef);
345
- assert (found != baseToIndexMap.end ());
346
- auto &method = vtableMethods[found->second ];
347
- assert (method.first == baseRef);
348
- method.second = declRef;
349
- }
350
-
351
- // Add an entry to the vtable.
352
- void addMethod (SILDeclRef member) {
353
- unsigned index = vtableMethods.size ();
354
- vtableMethods.push_back (std::make_pair (member, member));
355
- auto result = baseToIndexMap.insert (std::make_pair (member, index));
356
- assert (result.second );
357
- (void ) result;
358
- }
359
-
360
- void addPlaceholder (MissingMemberDecl *m) {
361
- #ifndef NDEBUG
362
- auto *classDecl = cast<ClassDecl>(m->getDeclContext ());
363
- bool isResilient =
364
- classDecl->isResilient (SGM.M .getSwiftModule (),
365
- ResilienceExpansion::Maximal);
366
- assert (isResilient || m->getNumberOfVTableEntries () == 0 &&
367
- " Should not be emitting fragile class with missing members" );
368
- #endif
369
- }
370
379
};
371
-
372
380
} // end anonymous namespace
373
381
374
382
static void emitTypeMemberGlobalVariable (SILGenModule &SGM,
0 commit comments