diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy')
4 files changed, 139 insertions, 6 deletions
diff --git a/clang-tools-extra/clang-tidy/google/CMakeLists.txt b/clang-tools-extra/clang-tidy/google/CMakeLists.txt index ff48b63d03d..9a919154246 100644 --- a/clang-tools-extra/clang-tidy/google/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/google/CMakeLists.txt @@ -6,6 +6,7 @@ add_clang_library(clangTidyGoogleModule ExplicitConstructorCheck.cpp ExplicitMakePairCheck.cpp GlobalNamesInHeadersCheck.cpp + GlobalVariableDeclarationCheck.cpp GoogleTidyModule.cpp IntegerTypesCheck.cpp NonConstReferences.cpp diff --git a/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.cpp new file mode 100644 index 00000000000..a278be14958 --- /dev/null +++ b/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.cpp @@ -0,0 +1,90 @@ +//===--- GlobalVariableDeclarationCheck.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 "GlobalVariableDeclarationCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" + +#include <string> + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace google { +namespace objc { + +namespace { + +FixItHint generateFixItHint(const VarDecl *Decl, bool IsConst) { + char FC = Decl->getName()[0]; + if (!llvm::isAlpha(FC) || Decl->getName().size() == 1) { + // No fix available if first character is not alphabetical character, or it + // is a single-character variable, since it is difficult to determine the + // proper fix in this case. Users should create a proper variable name by + // their own. + return FixItHint(); + } + char SC = Decl->getName()[1]; + if ((FC == 'k' || FC == 'g') && !llvm::isAlpha(SC)) { + // No fix available if the prefix is correct but the second character is not + // alphabetical, since it is difficult to determine the proper fix in this + // case. + return FixItHint(); + } + auto NewName = (IsConst ? "k" : "g") + + llvm::StringRef(std::string(1, FC)).upper() + + Decl->getName().substr(1).str(); + return FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(SourceRange(Decl->getLocation())), + llvm::StringRef(NewName)); +} +} // namespace + +void GlobalVariableDeclarationCheck::registerMatchers(MatchFinder *Finder) { + // The relevant Style Guide rule only applies to Objective-C. + if (!getLangOpts().ObjC1 && !getLangOpts().ObjC2) { + return; + } + // need to add two matchers since we need to bind different ids to distinguish + // constants and variables. Since bind() can only be called on node matchers, + // we cannot make it in one matcher. + Finder->addMatcher( + varDecl(hasGlobalStorage(), unless(hasType(isConstQualified())), + unless(matchesName("::g[A-Z]"))) + .bind("global_var"), + this); + Finder->addMatcher(varDecl(hasGlobalStorage(), hasType(isConstQualified()), + unless(matchesName("::k[A-Z]"))) + .bind("global_const"), + this); +} + +void GlobalVariableDeclarationCheck::check( + const MatchFinder::MatchResult &Result) { + if (const auto *Decl = Result.Nodes.getNodeAs<VarDecl>("global_var")) { + diag(Decl->getLocation(), + "non-const global variable '%0' must have a name which starts with " + "'g[A-Z]'") + << Decl->getName() << generateFixItHint(Decl, false); + } + if (const auto *Decl = Result.Nodes.getNodeAs<VarDecl>("global_const")) { + diag(Decl->getLocation(), + "const global variable '%0' must have a name which starts with " + "'k[A-Z]'") + << Decl->getName() << generateFixItHint(Decl, true); + } +} + +} // namespace objc +} // namespace google +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.h b/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.h new file mode 100644 index 00000000000..ed0352bb871 --- /dev/null +++ b/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.h @@ -0,0 +1,39 @@ +//===--- GlobalVariableDeclarationCheck.h - clang-tidy-----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_GLOBAL_VARIABLE_DECLARATION_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_GLOBAL_VARIABLE_DECLARATION_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace google { +namespace objc { + +/// The check for Objective-C global variables and constants naming convention. +/// The declaration should follow the patterns of 'k[A-Z].*' (constants) or +/// 'g[A-Z].*' (variables). +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/google-objc-global-variable-declaration.html +class GlobalVariableDeclarationCheck : public ClangTidyCheck { + public: + GlobalVariableDeclarationCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace objc +} // namespace google +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_GLOBAL_VARIABLE_DECLARATION_H diff --git a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp b/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp index 1328463e356..45d7de58435 100644 --- a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp @@ -19,6 +19,7 @@ #include "ExplicitConstructorCheck.h" #include "ExplicitMakePairCheck.h" #include "GlobalNamesInHeadersCheck.h" +#include "GlobalVariableDeclarationCheck.h" #include "IntegerTypesCheck.h" #include "NonConstReferences.h" #include "OverloadedUnaryAndCheck.h" @@ -34,7 +35,7 @@ namespace tidy { namespace google { class GoogleModule : public ClangTidyModule { -public: + public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck<build::ExplicitMakePairCheck>( "google-build-explicit-make-pair"); @@ -46,6 +47,10 @@ public: "google-default-arguments"); CheckFactories.registerCheck<ExplicitConstructorCheck>( "google-explicit-constructor"); + CheckFactories.registerCheck<readability::GlobalNamesInHeadersCheck>( + "google-global-names-in-headers"); + CheckFactories.registerCheck<objc::GlobalVariableDeclarationCheck>( + "google-objc-global-variable-declaration"); CheckFactories.registerCheck<runtime::IntegerTypesCheck>( "google-runtime-int"); CheckFactories.registerCheck<runtime::OverloadedUnaryAndCheck>( @@ -61,8 +66,6 @@ public: CheckFactories .registerCheck<clang::tidy::readability::BracesAroundStatementsCheck>( "google-readability-braces-around-statements"); - CheckFactories.registerCheck<readability::GlobalNamesInHeadersCheck>( - "google-global-names-in-headers"); CheckFactories.registerCheck<clang::tidy::readability::FunctionSizeCheck>( "google-readability-function-size"); CheckFactories @@ -89,11 +92,11 @@ public: static ClangTidyModuleRegistry::Add<GoogleModule> X("google-module", "Adds Google lint checks."); -} // namespace google +} // namespace google // This anchor is used to force the linker to link in the generated object file // and thus register the GoogleModule. volatile int GoogleModuleAnchorSource = 0; -} // namespace tidy -} // namespace clang +} // namespace tidy +} // namespace clang |

