[clang-tools-extra] r228875 - Add clang-tidy check google-global-names-in-headers.
Samuel Benzaquen
sbenza at google.com
Wed Feb 11 13:21:06 PST 2015
Author: sbenza
Date: Wed Feb 11 15:21:05 2015
New Revision: 228875
URL: http://llvm.org/viewvc/llvm-project?rev=228875&view=rev
Log:
Add clang-tidy check google-global-names-in-headers.
Summary:
google-global-names-in-headers flags global namespace pollution in header files.
Right now it only triggers on using declarations and directives.
Reviewers: alexfh
Subscribers: curdeius
Differential Revision: http://reviews.llvm.org/D7563
Added:
clang-tools-extra/trunk/clang-tidy/google/GlobalNamesInHeadersCheck.cpp
clang-tools-extra/trunk/clang-tidy/google/GlobalNamesInHeadersCheck.h
Modified:
clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt
clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp
clang-tools-extra/trunk/unittests/clang-tidy/GoogleModuleTest.cpp
Modified: clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt?rev=228875&r1=228874&r2=228875&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/google/CMakeLists.txt Wed Feb 11 15:21:05 2015
@@ -4,6 +4,7 @@ add_clang_library(clangTidyGoogleModule
AvoidCStyleCastsCheck.cpp
ExplicitConstructorCheck.cpp
ExplicitMakePairCheck.cpp
+ GlobalNamesInHeadersCheck.cpp
GoogleTidyModule.cpp
IntegerTypesCheck.cpp
MemsetZeroLengthCheck.cpp
Added: clang-tools-extra/trunk/clang-tidy/google/GlobalNamesInHeadersCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/GlobalNamesInHeadersCheck.cpp?rev=228875&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/google/GlobalNamesInHeadersCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/google/GlobalNamesInHeadersCheck.cpp Wed Feb 11 15:21:05 2015
@@ -0,0 +1,53 @@
+//===--- GlobalNamesInHeadersCheck.cpp - clang-tidy -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GlobalNamesInHeadersCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+void
+GlobalNamesInHeadersCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
+ Finder->addMatcher(
+ decl(anyOf(usingDecl(), usingDirectiveDecl()),
+ hasDeclContext(translationUnitDecl())).bind("using_decl"),
+ this);
+}
+
+void GlobalNamesInHeadersCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *D = Result.Nodes.getNodeAs<Decl>("using_decl");
+ // If it comes from a macro, we'll assume it is fine.
+ if (D->getLocStart().isMacroID())
+ return;
+
+ // Ignore if it comes from the "main" file ...
+ if (Result.SourceManager->isInMainFile(
+ Result.SourceManager->getExpansionLoc(D->getLocStart()))) {
+ // unless that file is a header.
+ StringRef Filename = Result.SourceManager->getFilename(
+ Result.SourceManager->getSpellingLoc(D->getLocStart()));
+
+ if (!Filename.endswith(".h"))
+ return;
+ }
+
+ diag(D->getLocStart(),
+ "using declarations in the global namespace in headers are prohibited");
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
Added: clang-tools-extra/trunk/clang-tidy/google/GlobalNamesInHeadersCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/GlobalNamesInHeadersCheck.h?rev=228875&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/google/GlobalNamesInHeadersCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/google/GlobalNamesInHeadersCheck.h Wed Feb 11 15:21:05 2015
@@ -0,0 +1,34 @@
+//===--- GlobalNamesInHeadersCheck.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_GLOBAL_NAMES_IN_HEADERS_CHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GLOBAL_NAMES_IN_HEADERS_CHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+// Flag global namespace pollution in header files.
+// Right now it only triggers on using declarations and directives.
+class GlobalNamesInHeadersCheck : public ClangTidyCheck {
+public:
+ GlobalNamesInHeadersCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GLOBAL_NAMES_IN_HEADERS_CHECK_H
+
Modified: clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp?rev=228875&r1=228874&r2=228875&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp Wed Feb 11 15:21:05 2015
@@ -17,6 +17,7 @@
#include "AvoidCStyleCastsCheck.h"
#include "ExplicitConstructorCheck.h"
#include "ExplicitMakePairCheck.h"
+#include "GlobalNamesInHeadersCheck.h"
#include "IntegerTypesCheck.h"
#include "MemsetZeroLengthCheck.h"
#include "NamedParameterCheck.h"
@@ -58,6 +59,8 @@ public:
"google-readability-todo");
CheckFactories.registerCheck<readability::BracesAroundStatementsCheck>(
"google-readability-braces-around-statements");
+ CheckFactories.registerCheck<readability::GlobalNamesInHeadersCheck>(
+ "google-global-names-in-headers");
CheckFactories.registerCheck<readability::FunctionSizeCheck>(
"google-readability-function-size");
CheckFactories.registerCheck<readability::NamespaceCommentCheck>(
Modified: clang-tools-extra/trunk/unittests/clang-tidy/GoogleModuleTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/GoogleModuleTest.cpp?rev=228875&r1=228874&r2=228875&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-tidy/GoogleModuleTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/GoogleModuleTest.cpp Wed Feb 11 15:21:05 2015
@@ -1,5 +1,6 @@
#include "ClangTidyTest.h"
#include "google/ExplicitConstructorCheck.h"
+#include "google/GlobalNamesInHeadersCheck.h"
#include "gtest/gtest.h"
namespace clang {
@@ -56,6 +57,51 @@ TEST(ExplicitConstructorCheckTest, Remov
"A(Foo);"));
}
+class GlobalNamesInHeadersCheckTest : public ::testing::Test {
+protected:
+ bool runCheckOnCode(const std::string &Code, const std::string &Filename) {
+ static const char *const Header = "namespace std {\n"
+ "class string {};\n"
+ "} // namespace std\n"
+ "\n"
+ "#define SOME_MACRO(x) using x\n";
+ std::vector<ClangTidyError> Errors;
+ std::vector<std::string> Args;
+ if (!StringRef(Filename).endswith(".cpp")) {
+ Args.emplace_back("-xc++-header");
+ }
+ test::runCheckOnCode<readability::GlobalNamesInHeadersCheck>(
+ Header + Code, &Errors, Filename, Args);
+ if (Errors.empty())
+ return false;
+ assert(Errors.size() == 1);
+ assert(
+ Errors[0].Message.Message ==
+ "using declarations in the global namespace in headers are prohibited");
+ return true;
+ }
+};
+
+TEST_F(GlobalNamesInHeadersCheckTest, UsingDeclarations) {
+ EXPECT_TRUE(runCheckOnCode("using std::string;", "foo.h"));
+ EXPECT_FALSE(runCheckOnCode("using std::string;", "foo.cpp"));
+ EXPECT_FALSE(runCheckOnCode("namespace my_namespace {\n"
+ "using std::string;\n"
+ "} // my_namespace\n",
+ "foo.h"));
+ EXPECT_FALSE(runCheckOnCode("SOME_MACRO(std::string);", "foo.h"));
+}
+
+TEST_F(GlobalNamesInHeadersCheckTest, UsingDirectives) {
+ EXPECT_TRUE(runCheckOnCode("using namespace std;", "foo.h"));
+ EXPECT_FALSE(runCheckOnCode("using namespace std;", "foo.cpp"));
+ EXPECT_FALSE(runCheckOnCode("namespace my_namespace {\n"
+ "using namespace std;\n"
+ "} // my_namespace\n",
+ "foo.h"));
+ EXPECT_FALSE(runCheckOnCode("SOME_MACRO(namespace std);", "foo.h"));
+}
+
} // namespace test
} // namespace tidy
} // namespace clang
More information about the cfe-commits
mailing list