================
@@ -19109,7 +19119,17 @@ bool Sema::DefineUsedVTables() {
         }
       }
 
-      if (IsExplicitInstantiationDeclaration)
+      if (IsExplicitInstantiationDeclaration &&
+          llvm::none_of(Class->decls(), [](Decl *decl) {
+            // If the class has a virtual member function declared with
+            // `__attribute__((exclude_from_explicit_instantiation))`, the
+            // explicit instantiation declaration shouldn't suppress emitting
+            // the vtable to ensure that the excluded member function is
+            // accessible through the vtable.
+            auto *Method = dyn_cast<CXXMethodDecl>(decl);
+            return Method && Method->isVirtual() &&
+                   Method->hasAttr<ExcludeFromExplicitInstantiationAttr>();
+          }))
----------------
kikairoya wrote:

> "vtable will live with the explicit instantiation" doesn't necessarily hold 
> if some methods are excluded from explicit instantiation.

I'm sorry, but I still don't understand. Why are non-virtual functions allowed 
to affect vtables? Is it just an optimization?

In the testcase, the implicitly instantiation of the excluded constructor 
triggers emitting the vtable. If there is no other way to run this block, the 
whole `if (!KeyFunc)` block could be omitted. Otherwise, that means this block 
may run even if no constructors are excluded, so I think that any non-virtual 
members that are not instantiated shouldn't affect code generation.

https://github.com/llvm/llvm-project/pull/168171
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to