From 94404b1050a9f1d2d27c1262a93828d1ee1ebf89 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Thu, 19 Nov 2015 00:03:54 +0000 Subject: [PATCH] [MS ABI] Let arbitrary entities participate in vftable ordering 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 --- lib/AST/VTableBuilder.cpp | 16 ++++++++++------ .../microsoft-abi-vtables-single-inheritance.cpp | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index 6829da5bb1..bae018652f 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -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 MethodGroup; SmallVector Groups; typedef llvm::DenseMap VisitedGroupIndicesTy; VisitedGroupIndicesTy VisitedGroupIndices; - for (const auto *MD : RD->methods()) { - MD = MD->getCanonicalDecl(); + for (const auto *D : RD->decls()) { + const auto *ND = dyn_cast(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(ND)) + if (MD->isVirtual()) + Groups[J->second].push_back(MD->getCanonicalDecl()); } for (const MethodGroup &Group : Groups) diff --git a/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp index baed35145f..aa39d6de61 100644 --- a/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp +++ b/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp @@ -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() {} -- 2.50.1