TheAhmad created this revision.
TheAhmad added a reviewer: alexfh.
TheAhmad added a project: clang-tools-extra.

Hi.
Clang tidy has problem with compile command databases that do not use 
necassarily absolute file paths. This is common in many projects that use 
makefiles as the build system, whose databases are usually generated using 
Bear. Therefore, I reused some of the code of the in-place fix and revised it 
to generate a YAML export file. The diff is OK, except that the merge conflicts 
are not added, right now.
Thanks!


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D49890

Files:
  ClangTidy.cpp


Index: ClangTidy.cpp
===================================================================
--- ClangTidy.cpp
+++ ClangTidy.cpp
@@ -608,8 +608,58 @@
                         raw_ostream &OS) {
   TranslationUnitDiagnostics TUD;
   TUD.MainSourceFile = MainFilePath;
-  for (const auto &Error : Errors) {
-    tooling::Diagnostic Diag = Error;
+
+  FileManager *Files = new FileManager(FileSystemOptions());
+  vfs::FileSystem &FileSystem = *Files->getVirtualFileSystem();
+  auto InitialWorkingDir = FileSystem.getCurrentWorkingDirectory();
+  if (!InitialWorkingDir)
+    llvm::report_fatal_error("Cannot get current working path.");
+
+  llvm::StringMap<Replacements> FileReplacements;
+  llvm::StringMap<ClangTidyError> SingleErrors;
+  for (const ClangTidyError &Error : Errors) {
+    if (!Error.BuildDirectory.empty()) {
+      FileSystem.setCurrentWorkingDirectory(Error.BuildDirectory);
+    }
+
+    SmallString<128> ErrorAbsoluteFilePath = (StringRef)Error.Message.FilePath;
+    Files->makeAbsolutePath(ErrorAbsoluteFilePath);
+    if (SingleErrors.find(ErrorAbsoluteFilePath) == SingleErrors.end())
+    {
+      ClangTidyError AbsoluteError = Error;
+      AbsoluteError.Message.FilePath = ErrorAbsoluteFilePath.str();
+      AbsoluteError.Fix.clear();
+      
SingleErrors.insert(std::pair<StringRef,ClangTidyError>(ErrorAbsoluteFilePath, 
AbsoluteError));
+    }
+       
+    for (const auto &FileAndReplacements : Error.Fix) {
+      for (const auto &Repl : FileAndReplacements.second) {
+        SmallString<128> FixAbsoluteFilePath = Repl.getFilePath();
+        Files->makeAbsolutePath(FixAbsoluteFilePath);
+
+        tooling::Replacement R(FixAbsoluteFilePath, Repl.getOffset(),
+                                                 Repl.getLength(),
+                                                 Repl.getReplacementText());
+
+        FileReplacements[R.getFilePath()].add(R);
+      }
+    }
+
+    FileSystem.setCurrentWorkingDirectory(InitialWorkingDir.get());
+  }
+
+  for (const auto &FileAndReplacements : FileReplacements) {
+    StringRef File = FileAndReplacements.first();
+    Replacements Repls = FileAndReplacements.second;
+
+    ClangTidyError  AbsoluteError = SingleErrors.find(File)->second;   
+    if (SingleErrors.find(File) == SingleErrors.end())
+    {
+      llvm::report_fatal_error("Cannot find the containing ClangTidyError.");
+    }
+    AbsoluteError.Fix.insert(std::pair<StringRef,Replacements>(File,Repls));
+
+    tooling::Diagnostic Diag = AbsoluteError;
     TUD.Diagnostics.insert(TUD.Diagnostics.end(), Diag);
   }
 


Index: ClangTidy.cpp
===================================================================
--- ClangTidy.cpp
+++ ClangTidy.cpp
@@ -608,8 +608,58 @@
                         raw_ostream &OS) {
   TranslationUnitDiagnostics TUD;
   TUD.MainSourceFile = MainFilePath;
-  for (const auto &Error : Errors) {
-    tooling::Diagnostic Diag = Error;
+
+  FileManager *Files = new FileManager(FileSystemOptions());
+  vfs::FileSystem &FileSystem = *Files->getVirtualFileSystem();
+  auto InitialWorkingDir = FileSystem.getCurrentWorkingDirectory();
+  if (!InitialWorkingDir)
+    llvm::report_fatal_error("Cannot get current working path.");
+
+  llvm::StringMap<Replacements> FileReplacements;
+  llvm::StringMap<ClangTidyError> SingleErrors;
+  for (const ClangTidyError &Error : Errors) {
+    if (!Error.BuildDirectory.empty()) {
+      FileSystem.setCurrentWorkingDirectory(Error.BuildDirectory);
+    }
+
+    SmallString<128> ErrorAbsoluteFilePath = (StringRef)Error.Message.FilePath;
+    Files->makeAbsolutePath(ErrorAbsoluteFilePath);
+    if (SingleErrors.find(ErrorAbsoluteFilePath) == SingleErrors.end())
+    {
+      ClangTidyError AbsoluteError = Error;
+      AbsoluteError.Message.FilePath = ErrorAbsoluteFilePath.str();
+      AbsoluteError.Fix.clear();
+      SingleErrors.insert(std::pair<StringRef,ClangTidyError>(ErrorAbsoluteFilePath, AbsoluteError));
+    }
+	
+    for (const auto &FileAndReplacements : Error.Fix) {
+      for (const auto &Repl : FileAndReplacements.second) {
+        SmallString<128> FixAbsoluteFilePath = Repl.getFilePath();
+        Files->makeAbsolutePath(FixAbsoluteFilePath);
+
+        tooling::Replacement R(FixAbsoluteFilePath, Repl.getOffset(),
+		                                  Repl.getLength(),
+		                                  Repl.getReplacementText());
+
+        FileReplacements[R.getFilePath()].add(R);
+      }
+    }
+
+    FileSystem.setCurrentWorkingDirectory(InitialWorkingDir.get());
+  }
+
+  for (const auto &FileAndReplacements : FileReplacements) {
+    StringRef File = FileAndReplacements.first();
+    Replacements Repls = FileAndReplacements.second;
+
+    ClangTidyError  AbsoluteError = SingleErrors.find(File)->second;   
+    if (SingleErrors.find(File) == SingleErrors.end())
+    {
+      llvm::report_fatal_error("Cannot find the containing ClangTidyError.");
+    }
+    AbsoluteError.Fix.insert(std::pair<StringRef,Replacements>(File,Repls));
+
+    tooling::Diagnostic Diag = AbsoluteError;
     TUD.Diagnostics.insert(TUD.Diagnostics.end(), Diag);
   }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to