summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
diff options
context:
space:
mode:
authorGabor Horvath <xazax.hun@gmail.com>2017-08-08 15:33:48 +0000
committerGabor Horvath <xazax.hun@gmail.com>2017-08-08 15:33:48 +0000
commit40b6512d9ef7c68cc0c6bb5521f29616f4f79264 (patch)
tree5d3de437ae77c131800c7fe00bfa4b4e4765e67d /clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
parent741d21f958fc76222c7cc4c6183e293ff86d1e1b (diff)
downloadbcm5719-llvm-40b6512d9ef7c68cc0c6bb5521f29616f4f79264.tar.gz
bcm5719-llvm-40b6512d9ef7c68cc0c6bb5521f29616f4f79264.zip
[clang-tidy] Add new readability non-idiomatic static access check
Patch by: Lilla Barancsuk Differential Revision: https://reviews.llvm.org/D35937 llvm-svn: 310371
Diffstat (limited to 'clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
new file mode 100644
index 00000000000..b1365772b59
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
@@ -0,0 +1,90 @@
+//===--- StaticAccessedThroughInstanceCheck.cpp - clang-tidy---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "StaticAccessedThroughInstanceCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+static unsigned getNameSpecifierNestingLevel(const QualType &QType) {
+ if (const ElaboratedType *ElType = QType->getAs<ElaboratedType>()) {
+ const NestedNameSpecifier *NestedSpecifiers = ElType->getQualifier();
+ unsigned NameSpecifierNestingLevel = 1;
+ do {
+ NameSpecifierNestingLevel++;
+ NestedSpecifiers = NestedSpecifiers->getPrefix();
+ } while (NestedSpecifiers);
+
+ return NameSpecifierNestingLevel;
+ }
+ return 0;
+}
+
+void StaticAccessedThroughInstanceCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "NameSpecifierNestingThreshold",
+ NameSpecifierNestingThreshold);
+}
+
+void StaticAccessedThroughInstanceCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(
+ memberExpr(hasDeclaration(anyOf(cxxMethodDecl(isStaticStorageClass()),
+ varDecl(hasStaticStorageDuration()))),
+ unless(isInTemplateInstantiation()))
+ .bind("memberExpression"),
+ this);
+}
+
+void StaticAccessedThroughInstanceCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ const auto *MemberExpression =
+ Result.Nodes.getNodeAs<MemberExpr>("memberExpression");
+
+ if (MemberExpression->getLocStart().isMacroID())
+ return;
+
+ const Expr *BaseExpr = MemberExpression->getBase();
+
+ // Do not warn for overlaoded -> operators.
+ if (isa<CXXOperatorCallExpr>(BaseExpr))
+ return;
+
+ QualType BaseType =
+ BaseExpr->getType()->isPointerType()
+ ? BaseExpr->getType()->getPointeeType().getUnqualifiedType()
+ : BaseExpr->getType().getUnqualifiedType();
+
+ const ASTContext *AstContext = Result.Context;
+ PrintingPolicy PrintingPolicyWithSupressedTag(AstContext->getLangOpts());
+ PrintingPolicyWithSupressedTag.SuppressTagKeyword = true;
+ std::string BaseTypeName =
+ BaseType.getAsString(PrintingPolicyWithSupressedTag);
+
+ SourceLocation MemberExprStartLoc = MemberExpression->getLocStart();
+ auto Diag =
+ diag(MemberExprStartLoc, "static member accessed through instance");
+
+ if (BaseExpr->HasSideEffects(*AstContext) ||
+ getNameSpecifierNestingLevel(BaseType) > NameSpecifierNestingThreshold)
+ return;
+
+ Diag << FixItHint::CreateReplacement(
+ CharSourceRange::getCharRange(MemberExprStartLoc,
+ MemberExpression->getMemberLoc()),
+ BaseTypeName + "::");
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
OpenPOWER on IntegriCloud