@@ -252,7 +252,10 @@ bool SILGenModule::requiresObjCMethodEntryPoint(ConstructorDecl *constructor) {
252252namespace {
253253
254254// / 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+
256259public:
257260 SILGenModule &SGM;
258261 ClassDecl *theClass;
@@ -267,14 +270,61 @@ class SILGenVTable : public SILVTableVisitor<SILGenVTable> {
267270 // For each base method, store the corresponding override.
268271 SmallVector<VTableMethod, 8 > vtableMethods;
269272
270- SILGenVTable (SILGenModule &SGM, ClassDecl *theClass)
271- : SGM(SGM), theClass(theClass) {
273+ SILGenVTableBase (SILGenModule &SGM, ClassDecl *theClass)
274+ : SGM(SGM), theClass(theClass) {
272275 isResilient = theClass->isResilient ();
273276 }
274277
275278 // / Populate our list of base methods and overrides.
276279 void collectMethods () { visitAncestor (theClass); }
277280
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+
278328 void emitVTable () {
279329 PrettyStackTraceDecl (" silgen emitVTable" , theClass);
280330
@@ -326,49 +376,7 @@ class SILGenVTable : public SILVTableVisitor<SILGenVTable> {
326376 // Finally, create the vtable.
327377 SILVTable::create (SGM.M , theClass, serialized, vtableEntries);
328378 }
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- }
370379};
371-
372380} // end anonymous namespace
373381
374382static void emitTypeMemberGlobalVariable (SILGenModule &SGM,
0 commit comments