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

llvm-svn: 228875
diff --git a/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp b/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp
index 2e74dea..0b19af2 100644
--- a/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp
+++ b/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp
@@ -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 @@
           "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