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