Export virtual functions when exporting a class definition (#7210)

This allows Clang to correctly generate the vtable for the exported
class.

There's still something wrong with new virtual functions in the Carbon
type (left a TODO) - I thought it might be related to not flagging
the CXXMethodDecl as virtual, but my initial experiments don't seem to
back that up, so I'll look into it further separately.

There's also a test regression due to an virtual (well, abstract
specifically, but I think it'd happen with a virtual one too) function
in an abstract class taking `self` by value being rejected since
the abstract class can't be instantiated. Not sure if this is a correct
change - the test's behavior could be preserved by using `ref self`
instnead of `self` in this function. Is that reasonable/expected? Should
we not require a type to be complete when passing by value if we can
compute the value representation without such completeness?

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
David Blaikie
2026-05-15 23:53:12 +00:00
committed by GitHub
co-authored by Richard Smith
parent 6d5a883d6d
commit 843323b864
4 changed files with 226 additions and 174 deletions
@@ -133,6 +133,16 @@ import Cpp;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
abstract class Abstract {
// CHECK:STDERR: fail_todo_abstract_nonvirtual_dtor_but_virtual_fns.carbon:[[@LINE+10]]:3: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
// CHECK:STDERR: abstract fn F[self: Self]();
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_todo_abstract_nonvirtual_dtor_but_virtual_fns.carbon:[[@LINE-4]]:1: note: class was declared abstract here [ClassAbstractHere]
// CHECK:STDERR: abstract class Abstract {
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_todo_abstract_nonvirtual_dtor_but_virtual_fns.carbon:[[@LINE+4]]:17: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: abstract fn F[self: Self]();
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
abstract fn F[self: Self]();
}