21 unsigned NameSpecifierNestingLevel = 1;
22 for (NestedNameSpecifier Qualifier = QType->getPrefix(); ;
23 ++NameSpecifierNestingLevel) {
24 switch (Qualifier.getKind()) {
25 case NestedNameSpecifier::Kind::Null:
26 return NameSpecifierNestingLevel;
27 case NestedNameSpecifier::Kind::Global:
28 case NestedNameSpecifier::Kind::MicrosoftSuper:
29 return NameSpecifierNestingLevel + 1;
30 case NestedNameSpecifier::Kind::Namespace:
31 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix;
33 case NestedNameSpecifier::Kind::Type:
34 Qualifier = Qualifier.getAsType()->getPrefix();
37 llvm_unreachable(
"unhandled nested name specifier kind");
57 const MatchFinder::MatchResult &Result) {
58 const auto *MemberExpression =
59 Result.Nodes.getNodeAs<MemberExpr>(
"memberExpression");
61 if (MemberExpression->getBeginLoc().isMacroID())
64 const Expr *BaseExpr = MemberExpression->getBase();
66 const QualType BaseType =
67 BaseExpr->getType()->isPointerType()
68 ? BaseExpr->getType()->getPointeeType().getUnqualifiedType()
69 : BaseExpr->getType().getUnqualifiedType();
71 const ASTContext *AstContext = Result.Context;
72 PrintingPolicy PrintingPolicyWithSuppressedTag(AstContext->getLangOpts());
73 PrintingPolicyWithSuppressedTag.SuppressTagKeyword =
true;
74 PrintingPolicyWithSuppressedTag.SuppressUnwrittenScope =
true;
76 PrintingPolicyWithSuppressedTag.PrintAsCanonical =
77 !BaseExpr->getType()->isTypedefNameType();
79 std::string BaseTypeName =
80 BaseType.getAsString(PrintingPolicyWithSuppressedTag);
83 const RecordDecl *RecDecl = BaseType->getAsCXXRecordDecl();
84 if (!RecDecl || RecDecl->getIdentifier() ==
nullptr)
88 if (StringRef(BaseTypeName).starts_with(
"__cuda_builtin_"))
91 SourceLocation MemberExprStartLoc = MemberExpression->getBeginLoc();
92 const auto CreateFix = [&] {
93 return FixItHint::CreateReplacement(
94 CharSourceRange::getCharRange(MemberExprStartLoc,
95 MemberExpression->getMemberLoc()),
101 diag(MemberExprStartLoc,
"static member accessed through instance");
106 if (!BaseExpr->HasSideEffects(*AstContext,
113 diag(MemberExprStartLoc,
"member base expression may carry some side effects",
114 DiagnosticIDs::Level::Note)
115 << BaseExpr->getSourceRange() << CreateFix();