sbenza created this revision.
sbenza added a reviewer: alexfh.
sbenza added a subscriber: cfe-commits.

Add 'included from' details to warning message to 
google-global-names-in-headers.
It should make it clearer on those cases where a non-header is being mistakenly 
#included.

http://reviews.llvm.org/D21815

Files:
  clang-tidy/google/GlobalNamesInHeadersCheck.cpp
  unittests/clang-tidy/GoogleModuleTest.cpp

Index: unittests/clang-tidy/GoogleModuleTest.cpp
===================================================================
--- unittests/clang-tidy/GoogleModuleTest.cpp
+++ unittests/clang-tidy/GoogleModuleTest.cpp
@@ -58,25 +58,34 @@
 
 class GlobalNamesInHeadersCheckTest : public ::testing::Test {
 protected:
-  bool runCheckOnCode(const std::string &Code, const std::string &Filename) {
+  bool runCheckOnCode(const std::string &Code, const std::string &Filename,
+                      bool IsIncluded = false) {
     static const char *const Header = "namespace std {\n"
                                       "class string {};\n"
                                       "}  // namespace std\n"
+                                      "#include \"header.h\"\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");
     }
+    std::map<StringRef, StringRef> Paths;
+    Paths["header.h"] = IsIncluded ? StringRef(Code) : StringRef("\n");
+    ClangTidyOptions Options;
+    Options.HeaderFilterRegex = ".*";
     test::runCheckOnCode<readability::GlobalNamesInHeadersCheck>(
-        Header + Code, &Errors, Filename, Args);
+        Header + (IsIncluded ? "" : Code), &Errors,
+        IsIncluded ? "main.cpp" : Filename, Args, Options, Paths);
     if (Errors.empty())
       return false;
     assert(Errors.size() == 1);
-    assert(
-        Errors[0].Message.Message ==
-        "using declarations in the global namespace in headers are prohibited");
+    std::string Expected =
+        "using declarations in the global namespace in headers are prohibited";
+    if (IsIncluded)
+      Expected += "; in file included from 'main.cpp'";
+    assert(Errors[0].Message.Message == Expected);
     return true;
   }
 };
@@ -89,6 +98,7 @@
                               "}  // my_namespace\n",
                               "foo.h"));
   EXPECT_FALSE(runCheckOnCode("SOME_MACRO(std::string);", "foo.h"));
+  EXPECT_TRUE(runCheckOnCode("using std::string;", "foo.h", true));
 }
 
 TEST_F(GlobalNamesInHeadersCheckTest, UsingDirectives) {
@@ -99,6 +109,7 @@
                               "}  // my_namespace\n",
                               "foo.h"));
   EXPECT_FALSE(runCheckOnCode("SOME_MACRO(namespace std);", "foo.h"));
+  EXPECT_TRUE(runCheckOnCode("using namespace std;", "foo.h", true));
 }
 
 TEST_F(GlobalNamesInHeadersCheckTest, RegressionAnonymousNamespace) {
Index: clang-tidy/google/GlobalNamesInHeadersCheck.cpp
===================================================================
--- clang-tidy/google/GlobalNamesInHeadersCheck.cpp
+++ clang-tidy/google/GlobalNamesInHeadersCheck.cpp
@@ -46,6 +46,24 @@
       this);
 }
 
+namespace {
+std::string getIncludeFromMessage(SourceLocation DeclLoc,
+                                  const SourceManager &SM) {
+  FileID FID = SM.getFileID(DeclLoc);
+  bool Invalid;
+  const auto &Entry = SM.getSLocEntry(FID, &Invalid);
+  if (Invalid)
+    return "";
+  SourceLocation IncludeLoc = Entry.getFile().getIncludeLoc();
+  if (!IncludeLoc.isValid())
+    return "";
+  StringRef Filename = SM.getFilename(IncludeLoc);
+  if (Filename.empty())
+    return "";
+  return (Twine("; in file included from '") + Filename + "'").str();
+}
+}  // namespace
+
 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.
@@ -71,8 +89,12 @@
     }
   }
 
+  std::string IncludeMessage =
+      getIncludeFromMessage(D->getLocStart(), *Result.SourceManager);
+
   diag(D->getLocStart(),
-       "using declarations in the global namespace in headers are prohibited");
+       "using declarations in the global namespace in headers are prohibited%0")
+      << IncludeMessage;
 }
 
 } // namespace readability
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to