23 const CXXRecordDecl &ThisClass) {
24 if (Parent.getCanonicalDecl() == ThisClass.getCanonicalDecl())
26 const CXXRecordDecl *ParentCanonicalDecl = Parent.getCanonicalDecl();
27 return llvm::any_of(ThisClass.bases(), [=](
const CXXBaseSpecifier &Base) {
28 auto *BaseDecl = Base.getType()->getAsCXXRecordDecl();
30 return ParentCanonicalDecl == BaseDecl->getCanonicalDecl();
35 const CXXRecordDecl &ThisClass,
36 const CXXMethodDecl &MemberDecl) {
38 for (
const auto &Base : ThisClass.bases()) {
39 const auto *BaseDecl = Base.getType()->getAsCXXRecordDecl();
40 const CXXMethodDecl *ActualMemberDecl =
41 MemberDecl.getCorrespondingMethodInClass(BaseDecl);
42 if (!ActualMemberDecl)
47 const Type *TypePtr = ActualMemberDecl->getThisType().getTypePtr();
48 const CXXRecordDecl *RecordDeclType = TypePtr->getPointeeCXXRecordDecl();
49 assert(RecordDeclType &&
"TypePtr is not a pointer to CXXRecordDecl!");
50 if (RecordDeclType->getCanonicalDecl()->isDerivedFrom(&GrandParent))
51 Result.emplace_back(RecordDeclType);
92 const auto *Member = Result.Nodes.getNodeAs<MemberExpr>(
"member");
95 if (!Member->getQualifier())
98 const auto *MemberDecl = cast<CXXMethodDecl>(Member->getMemberDecl());
100 const auto *ThisTypePtr = Result.Nodes.getNodeAs<PointerType>(
"thisType");
103 const auto *ThisType = ThisTypePtr->getPointeeCXXRecordDecl();
106 const auto *CastToTypePtr = Result.Nodes.getNodeAs<Type>(
"castToType");
107 assert(CastToTypePtr);
109 const auto *CastToType = CastToTypePtr->getAsCXXRecordDecl();
121 std::string ParentsStr;
122 ParentsStr.reserve(30 * Parents.size());
123 for (
const CXXRecordDecl *Parent : Parents) {
124 if (!ParentsStr.empty())
125 ParentsStr.append(
" or ");
129 assert(Member->getQualifierLoc().getSourceRange().getBegin().isValid());
130 auto Diag = diag(Member->getQualifierLoc().getSourceRange().getBegin(),
131 "qualified name '%0' refers to a member overridden "
132 "in %plural{1:subclass|:subclasses}1; did you mean %2?")
134 <<
static_cast<unsigned>(Parents.size()) << ParentsStr;
137 if (Parents.size() == 1 &&
139 !isa<ClassTemplateSpecializationDecl>(Parents.front()))
140 Diag << FixItHint::CreateReplacement(
141 Member->getQualifierLoc().getSourceRange(),