I tried using CXXRecordDecl, to print the virtual functions, but they are in declaration order, which may not be the order actually in the vtable.
sample code
namespace test
{
class Foo {
public:
virtual void v_func() {}
virtual void v_func2() {}
virtual ~Foo() = default;
};
class Bar : public Foo {
public:
virtual void v_func2() {}
virtual void v_func() {}
virtual ~Bar() = default;
};
} // namespace test
int main() {
test::Foo *foo = new test::Bar();
test::Bar *bar = new test::Bar();
delete foo;
delete bar;
return 0;
}
The virtual function table printed by gdb is as follows:
(gdb) info vtbl foo
vtable for 'test::Foo' @ 0x65a450 (subobject @ 0x101a008):
[0]: 0x404402 <test::Bar::v_func()>
[1]: 0x4043f4 <test::Bar::v_func2(int, test::tmp)>
(gdb) info vtbl bar
vtable for 'test::Bar' @ 0x65a450 (subobject @ 0x101a010):
[0]: 0x404402 <test::Bar::v_func()>
[1]: 0x4043f4 <test::Bar::v_func2(int, test::tmp)>
By traversing the method of CXXRecordDecl, it can only print in the order of function declaration.
// CXXRecordDecl *cxx_record
// Dump out all the virtual methods
for (CXXRecordDecl::method_iterator first = cxx_record->method_begin();
first != cxx_record->method_end(); ++first) {
if (!first->isVirtual()) {
continue;
}
llvm::outs() << first->getQualifiedNameAsString() << " " << first->getType().getAsString() << "\n";
}
out:
v_func void (void)
v_func2 void (int, class test::tmp)
~Foo void (void) noexcept
v_func2 void (int, class test::tmp)
v_func void (void)
~Bar void (void) noexcept
I checked the documentation for CXXRecordDecl and found nothing related to vtables