hokein updated this revision to Diff 48463.
hokein added a comment.

- Add lit test.
- Address review comments.


http://reviews.llvm.org/D17335

Files:
  clang-tidy/ClangTidy.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tidy/ClangTidyDiagnosticConsumer.h
  test/clang-tidy/Inputs/compilation-database/header.h
  test/clang-tidy/Inputs/compilation-database/template.json
  test/clang-tidy/clang-tidy-run-with-database.cpp

Index: test/clang-tidy/clang-tidy-run-with-database.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/clang-tidy-run-with-database.cpp
@@ -0,0 +1,5 @@
+// RUN: DATABASEDIR=$S/Inputs/compilation-database
+// RUN: sed 's|test_dir|%S|g' %S/Inputs/compilation-database/template.json > %S/Inputs/compilation-database/compile_commands.json
+// RUN: clang-tidy --checks=-*,modernize-use-nullptr -p %S/Inputs/compilation-database %s -header-filter=.*
+
+#include "./Inputs/compilation-database/header.h"
Index: test/clang-tidy/Inputs/compilation-database/template.json
===================================================================
--- /dev/null
+++ test/clang-tidy/Inputs/compilation-database/template.json
@@ -0,0 +1,7 @@
+[
+{
+  "directory": "test_dir",
+  "command": "clang++ -o test.o clang-tidy-run-with-database.cpp",
+  "file": "test_dir/clang-tidy-run-with-database.cpp"
+}
+]
Index: test/clang-tidy/Inputs/compilation-database/header.h
===================================================================
--- /dev/null
+++ test/clang-tidy/Inputs/compilation-database/header.h
@@ -0,0 +1,3 @@
+#define NULL 0
+
+int *a = NULL;
Index: clang-tidy/ClangTidyDiagnosticConsumer.h
===================================================================
--- clang-tidy/ClangTidyDiagnosticConsumer.h
+++ clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -57,8 +57,18 @@
     Error = DiagnosticsEngine::Error
   };
 
-  ClangTidyError(StringRef CheckName, Level DiagLevel, bool IsWarningAsError);
-
+  ClangTidyError(StringRef CheckName, Level DiagLevel, bool IsWarningAsError,
+                 const std::string &BuildDirectory);
+
+  // A build directory of the source file containing the error.
+  //
+  // It's an absolute path which is `directory` field of the source file in
+  // compilation database (compile_commands.json). If users don't specify
+  // compilation database directory, it is the current directory where
+  // clang-tidy runs.
+  //
+  // It can be empty in some cases, e.g. the source file is not exist.
+  std::string BuildDirectory;
   std::string CheckName;
   ClangTidyMessage Message;
   tooling::Replacements Fix;
Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp
===================================================================
--- clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -116,9 +116,10 @@
 
 ClangTidyError::ClangTidyError(StringRef CheckName,
                                ClangTidyError::Level DiagLevel,
-                               bool IsWarningAsError)
-    : CheckName(CheckName), DiagLevel(DiagLevel),
-      IsWarningAsError(IsWarningAsError) {}
+                               bool IsWarningAsError,
+                               const std::string &BuildDirectory)
+    : BuildDirectory(std::move(BuildDirectory)), CheckName(CheckName),
+      DiagLevel(DiagLevel), IsWarningAsError(IsWarningAsError) {}
 
 // Returns true if GlobList starts with the negative indicator ('-'), removes it
 // from the GlobList.
@@ -335,7 +336,17 @@
     bool IsWarningAsError =
         DiagLevel == DiagnosticsEngine::Warning &&
         Context.getWarningAsErrorFilter().contains(CheckName);
-    Errors.push_back(ClangTidyError(CheckName, Level, IsWarningAsError));
+
+    std::string BuildDirectory;
+    if (Info.hasSourceManager()) {
+      auto WorkingDir = Info.getSourceManager()
+                            .getFileManager().getVirtualFileSystem()
+                            ->getCurrentWorkingDirectory();
+      if (WorkingDir)
+        BuildDirectory = WorkingDir.get();
+    }
+    Errors.push_back(
+        ClangTidyError(CheckName, Level, IsWarningAsError, BuildDirectory));
   }
 
   // FIXME: Provide correct LangOptions for each file.
Index: clang-tidy/ClangTidy.cpp
===================================================================
--- clang-tidy/ClangTidy.cpp
+++ clang-tidy/ClangTidy.cpp
@@ -109,6 +109,14 @@
 
   void reportDiagnostic(const ClangTidyError &Error) {
     const ClangTidyMessage &Message = Error.Message;
+    // By default, the working directory of file system is the current
+    // clang-tidy running directory.
+    //
+    // Specify the build directory of the source file as current working
+    // directroy to find source file correctly.
+    if (!Error.BuildDirectory.empty())
+      Files.getVirtualFileSystem()->setCurrentWorkingDirectory(
+          Error.BuildDirectory);
     SourceLocation Loc = getLocation(Message.FilePath, Message.FileOffset);
     // Contains a pair for each attempted fix: location and whether the fix was
     // applied successfully.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to