60 const auto &D = *Result.Nodes.getNodeAs<CXXRecordDecl>(
"decl");
63 for (
const CXXBaseSpecifier &Base : D.bases())
64 if (!Base.isVirtual() && !isInterface(Base))
65 DirectConcreteBases.push_back(Base.getType()->getAsCXXRecordDecl());
68 for (
const CXXBaseSpecifier &VBase : D.vbases())
69 if (!isInterface(VBase))
70 VirtualConcreteBases.push_back(VBase.getType()->getAsCXXRecordDecl());
72 unsigned NumConcrete = DirectConcreteBases.size();
77 NumConcrete += llvm::count_if(
78 VirtualConcreteBases, [&](
const CXXRecordDecl *VirtualBase) {
79 const bool HiddenByMoreDerivedVirtualBase = llvm::any_of(
80 VirtualConcreteBases, [&](
const CXXRecordDecl *OtherVirtualBase) {
81 return VirtualBase != OtherVirtualBase &&
82 OtherVirtualBase->isVirtuallyDerivedFrom(VirtualBase);
84 const bool HiddenByDirectConcreteBase = llvm::any_of(
85 DirectConcreteBases, [&](
const CXXRecordDecl *DirectBase) {
86 return DirectBase->isVirtuallyDerivedFrom(VirtualBase);
88 return !HiddenByMoreDerivedVirtualBase && !HiddenByDirectConcreteBase;
92 diag(D.getBeginLoc(),
"inheriting multiple classes that aren't "
93 "pure virtual is discouraged");