Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[MS ABI] Let arbitrary entities participate in vftable ordering
Browse files Browse the repository at this point in the history
In the Microsoft ABI, the vftable is laid out in the order in the
declaration order of the entities defined within it.

Obviously, only virtual methods end up in the vftable but they will be
placed into the table at the same position as the first entity with the
same name.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@253523 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
majnemer committed Nov 19, 2015
1 parent f88e4c3 commit 94404b1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
16 changes: 10 additions & 6 deletions lib/AST/VTableBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2882,22 +2882,26 @@ static void GroupNewVirtualOverloads(
// Put the virtual methods into VirtualMethods in the proper order:
// 1) Group overloads by declaration name. New groups are added to the
// vftable in the order of their first declarations in this class
// (including overrides and non-virtual methods).
// (including overrides, non-virtual methods and any other named decl that
// might be nested within the class).
// 2) In each group, new overloads appear in the reverse order of declaration.
typedef SmallVector<const CXXMethodDecl *, 1> MethodGroup;
SmallVector<MethodGroup, 10> Groups;
typedef llvm::DenseMap<DeclarationName, unsigned> VisitedGroupIndicesTy;
VisitedGroupIndicesTy VisitedGroupIndices;
for (const auto *MD : RD->methods()) {
MD = MD->getCanonicalDecl();
for (const auto *D : RD->decls()) {
const auto *ND = dyn_cast<NamedDecl>(D);
if (!ND)
continue;
VisitedGroupIndicesTy::iterator J;
bool Inserted;
std::tie(J, Inserted) = VisitedGroupIndices.insert(
std::make_pair(MD->getDeclName(), Groups.size()));
std::make_pair(ND->getDeclName(), Groups.size()));
if (Inserted)
Groups.push_back(MethodGroup());
if (MD->isVirtual())
Groups[J->second].push_back(MD);
if (const auto *MD = dyn_cast<CXXMethodDecl>(ND))
if (MD->isVirtual())
Groups[J->second].push_back(MD->getCanonicalDecl());
}

for (const MethodGroup &Group : Groups)
Expand Down
15 changes: 15 additions & 0 deletions test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,18 @@ struct S {
};

S::S() {}

struct T {
struct U {};
};
struct V : T {
// CHECK-LABEL: VFTable for 'V' (2 entries).
// CHECK-NEXT: 0 | void V::U()
// CHECK-NEXT: 1 | void V::f()
using T::U;
virtual void f();
virtual void U();
V();
};

V::V() {}

0 comments on commit 94404b1

Please sign in to comment.