diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index 6829da5bb142..bae018652f91 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/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/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp index baed35145f98..aa39d6de615a 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp +++ b/clang/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() {}