24 const CXXRecordDecl &ThisClass) {
25 if (Parent.getCanonicalDecl() == ThisClass.getCanonicalDecl())
27 const CXXRecordDecl *ParentCanonicalDecl = Parent.getCanonicalDecl();
28 return llvm::any_of(ThisClass.bases(), [=](
const CXXBaseSpecifier &Base) {
29 auto *BaseDecl = Base.getType()->getAsCXXRecordDecl();
31 return ParentCanonicalDecl == BaseDecl->getCanonicalDecl();
36 const CXXRecordDecl &ThisClass,
37 const CXXMethodDecl &MemberDecl) {
39 for (
const auto &Base : ThisClass.bases()) {
40 const auto *BaseDecl = Base.getType()->getAsCXXRecordDecl();
41 const CXXMethodDecl *ActualMemberDecl =
42 MemberDecl.getCorrespondingMethodInClass(BaseDecl);
43 if (!ActualMemberDecl)
48 const Type *TypePtr = ActualMemberDecl->getThisType().getTypePtr();
49 const CXXRecordDecl *RecordDeclType = TypePtr->getPointeeCXXRecordDecl();
50 assert(RecordDeclType &&
"TypePtr is not a pointer to CXXRecordDecl!");
51 if (RecordDeclType->getCanonicalDecl()->isDerivedFrom(&GrandParent))
52 Result.emplace_back(RecordDeclType);
94 const auto *Member = Result.Nodes.getNodeAs<MemberExpr>(
"member");
97 if (!Member->getQualifier())
100 const auto *MemberDecl = cast<CXXMethodDecl>(Member->getMemberDecl());
102 const auto *ThisTypePtr = Result.Nodes.getNodeAs<PointerType>(
"thisType");
105 const auto *ThisType = ThisTypePtr->getPointeeCXXRecordDecl();
108 const auto *CastToTypePtr = Result.Nodes.getNodeAs<Type>(
"castToType");
109 assert(CastToTypePtr);
111 const auto *CastToType = CastToTypePtr->getAsCXXRecordDecl();
123 std::string ParentsStr;
124 ParentsStr.reserve(30 * Parents.size());
125 for (
const CXXRecordDecl *Parent : Parents) {
126 if (!ParentsStr.empty())
127 ParentsStr.append(
" or ");
131 assert(Member->getQualifierLoc().getSourceRange().getBegin().isValid());
132 auto Diag = diag(Member->getQualifierLoc().getSourceRange().getBegin(),
133 "qualified name '%0' refers to a member overridden "
134 "in %plural{1:subclass|:subclasses}1; did you mean %2?")
136 <<
static_cast<unsigned>(Parents.size()) << ParentsStr;
139 if (Parents.size() == 1 &&
141 !isa<ClassTemplateSpecializationDecl>(Parents.front()))
142 Diag << FixItHint::CreateReplacement(
143 Member->getQualifierLoc().getSourceRange(),