diff options
author | Alexander Kornienko <alexfh@google.com> | 2017-01-03 14:36:13 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2017-01-03 14:36:13 +0000 |
commit | 6b97b9e1162fc98a8047e0b61cc659a2286a1c47 (patch) | |
tree | 7773af8e2280ec87aee830ee75515fc430a32b48 /clang-apply-replacements | |
parent | 7ee33c19aae558d5d7b37c83a6da9f7e2a304c53 (diff) |
[clang-tidy] Add check name to YAML export (clang-tools-extra part)
Add a field indicating the associated check for every replacement to the YAML
report generated with the '-export-fixes' option. Update
clang-apply-replacements to handle the new format.
Patch by Alpha Abdoulaye!
Differential revision: https://reviews.llvm.org/D26137
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@290893 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'clang-apply-replacements')
3 files changed, 106 insertions, 12 deletions
diff --git a/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h b/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h index 22393724..5e0ff48a 100644 --- a/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h +++ b/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h @@ -16,6 +16,7 @@ #ifndef LLVM_CLANG_APPLYREPLACEMENTS_H #define LLVM_CLANG_APPLYREPLACEMENTS_H +#include "clang/Tooling/Core/Diagnostic.h" #include "clang/Tooling/Refactoring.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -43,6 +44,9 @@ typedef std::vector<clang::tooling::TranslationUnitReplacements> TUReplacements; /// \brief Collection of TranslationUnitReplacement files. typedef std::vector<std::string> TUReplacementFiles; +/// \brief Collection of TranslationUniDiagnostics. +typedef std::vector<clang::tooling::TranslationUnitDiagnostics> TUDiagnostics; + /// \brief Map mapping file name to Replacements targeting that file. typedef llvm::DenseMap<const clang::FileEntry *, std::vector<clang::tooling::Replacement>> @@ -58,8 +62,8 @@ typedef llvm::DenseMap<const clang::FileEntry *, /// \param[in] Directory Directory to begin search for serialized /// TranslationUnitReplacements. /// \param[out] TUs Collection of all found and deserialized -/// TranslationUnitReplacements. -/// \param[out] TURFiles Collection of all TranslationUnitReplacement files +/// TranslationUnitReplacements or TranslationUnitDiagnostics. +/// \param[out] TUFiles Collection of all TranslationUnitReplacement files /// found in \c Directory. /// \param[in] Diagnostics DiagnosticsEngine used for error output. /// @@ -67,7 +71,11 @@ typedef llvm::DenseMap<const clang::FileEntry *, /// directory structure. std::error_code collectReplacementsFromDirectory( const llvm::StringRef Directory, TUReplacements &TUs, - TUReplacementFiles &TURFiles, clang::DiagnosticsEngine &Diagnostics); + TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics); + +std::error_code collectReplacementsFromDirectory( + const llvm::StringRef Directory, TUDiagnostics &TUs, + TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics); /// \brief Deduplicate, check for conflicts, and apply all Replacements stored /// in \c TUs. If conflicts occur, no Replacements are applied. @@ -75,7 +83,8 @@ std::error_code collectReplacementsFromDirectory( /// \post For all (key,value) in GroupedReplacements, value[i].getOffset() <= /// value[i+1].getOffset(). /// -/// \param[in] TUs Collection of TranslationUnitReplacements to merge, +/// \param[in] TUs Collection of TranslationUnitReplacements or +/// TranslationUnitDiagnostics to merge, /// deduplicate, and test for conflicts. /// \param[out] GroupedReplacements Container grouping all Replacements by the /// file they target. @@ -88,6 +97,10 @@ bool mergeAndDeduplicate(const TUReplacements &TUs, FileToReplacementsMap &GroupedReplacements, clang::SourceManager &SM); +bool mergeAndDeduplicate(const TUDiagnostics &TUs, + FileToReplacementsMap &GroupedReplacements, + clang::SourceManager &SM); + // FIXME: Remove this function after changing clang-apply-replacements to use // Replacements class. bool applyAllReplacements(const std::vector<tooling::Replacement> &Replaces, diff --git a/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp b/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp index d2607b06..52234fed 100644 --- a/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp +++ b/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp @@ -20,6 +20,7 @@ #include "clang/Format/Format.h" #include "clang/Lex/Lexer.h" #include "clang/Rewrite/Core/Rewriter.h" +#include "clang/Tooling/DiagnosticsYaml.h" #include "clang/Tooling/ReplacementsYaml.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/FileSystem.h" @@ -37,7 +38,7 @@ namespace replace { std::error_code collectReplacementsFromDirectory( const llvm::StringRef Directory, TUReplacements &TUs, - TUReplacementFiles &TURFiles, clang::DiagnosticsEngine &Diagnostics) { + TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics) { using namespace llvm::sys::fs; using namespace llvm::sys::path; @@ -54,7 +55,7 @@ std::error_code collectReplacementsFromDirectory( if (extension(I->path()) != ".yaml") continue; - TURFiles.push_back(I->path()); + TUFiles.push_back(I->path()); ErrorOr<std::unique_ptr<MemoryBuffer>> Out = MemoryBuffer::getFile(I->path()); @@ -79,6 +80,51 @@ std::error_code collectReplacementsFromDirectory( return ErrorCode; } +std::error_code +collectReplacementsFromDirectory(const llvm::StringRef Directory, + TUDiagnostics &TUs, TUReplacementFiles &TUFiles, + clang::DiagnosticsEngine &Diagnostics) { + using namespace llvm::sys::fs; + using namespace llvm::sys::path; + + std::error_code ErrorCode; + + for (recursive_directory_iterator I(Directory, ErrorCode), E; + I != E && !ErrorCode; I.increment(ErrorCode)) { + if (filename(I->path())[0] == '.') { + // Indicate not to descend into directories beginning with '.' + I.no_push(); + continue; + } + + if (extension(I->path()) != ".yaml") + continue; + + TUFiles.push_back(I->path()); + + ErrorOr<std::unique_ptr<MemoryBuffer>> Out = + MemoryBuffer::getFile(I->path()); + if (std::error_code BufferError = Out.getError()) { + errs() << "Error reading " << I->path() << ": " << BufferError.message() + << "\n"; + continue; + } + + yaml::Input YIn(Out.get()->getBuffer(), nullptr, &eatDiagnostics); + tooling::TranslationUnitDiagnostics TU; + YIn >> TU; + if (YIn.error()) { + // File doesn't appear to be a header change description. Ignore it. + continue; + } + + // Only keep files that properly parse. + TUs.push_back(TU); + } + + return ErrorCode; +} + /// \brief Dumps information for a sequence of conflicting Replacements. /// /// \param[in] File FileEntry for the file the conflicting Replacements are @@ -256,6 +302,34 @@ bool mergeAndDeduplicate(const TUReplacements &TUs, return !deduplicateAndDetectConflicts(GroupedReplacements, SM); } +bool mergeAndDeduplicate(const TUDiagnostics &TUs, + FileToReplacementsMap &GroupedReplacements, + clang::SourceManager &SM) { + + // Group all replacements by target file. + std::set<StringRef> Warned; + for (const auto &TU : TUs) { + for (const auto &D : TU.Diagnostics) { + for (const auto &Fix : D.Fix) { + for (const tooling::Replacement &R : Fix.second) { + // Use the file manager to deduplicate paths. FileEntries are + // automatically canonicalized. + const FileEntry *Entry = SM.getFileManager().getFile(R.getFilePath()); + if (!Entry && Warned.insert(R.getFilePath()).second) { + errs() << "Described file '" << R.getFilePath() + << "' doesn't exist. Ignoring...\n"; + continue; + } + GroupedReplacements[Entry].push_back(R); + } + } + } + } + + // Ask clang to deduplicate and report conflicts. + return !deduplicateAndDetectConflicts(GroupedReplacements, SM); +} + bool applyReplacements(const FileToReplacementsMap &GroupedReplacements, clang::Rewriter &Rewrites) { diff --git a/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp b/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp index 48c6903f..0881e677 100644 --- a/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp +++ b/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp @@ -66,7 +66,7 @@ static cl::opt<std::string> cl::init("LLVM"), cl::cat(FormattingCategory)); namespace { -// Helper object to remove the TUReplacement files (triggered by +// Helper object to remove the TUReplacement and TUDiagnostic (triggered by // "remove-change-desc-files" command line option) when exiting current scope. class ScopedFileRemover { public: @@ -211,11 +211,16 @@ int main(int argc, char **argv) { if (DoFormat) FormatStyle = format::getStyle(FormatStyleOpt, FormatStyleConfig, "LLVM"); - TUReplacements TUs; - TUReplacementFiles TURFiles; + TUReplacements TURs; + TUReplacementFiles TUFiles; std::error_code ErrorCode = - collectReplacementsFromDirectory(Directory, TUs, TURFiles, Diagnostics); + collectReplacementsFromDirectory(Directory, TURs, TUFiles, Diagnostics); + + TUDiagnostics TUDs; + TUFiles.clear(); + ErrorCode = + collectReplacementsFromDirectory(Directory, TUDs, TUFiles, Diagnostics); if (ErrorCode) { errs() << "Trouble iterating over directory '" << Directory @@ -227,13 +232,15 @@ int main(int argc, char **argv) { // command line option) when exiting main(). std::unique_ptr<ScopedFileRemover> Remover; if (RemoveTUReplacementFiles) - Remover.reset(new ScopedFileRemover(TURFiles, Diagnostics)); + Remover.reset(new ScopedFileRemover(TUFiles, Diagnostics)); FileManager Files((FileSystemOptions())); SourceManager SM(Diagnostics, Files); FileToReplacementsMap GroupedReplacements; - if (!mergeAndDeduplicate(TUs, GroupedReplacements, SM)) + if (!mergeAndDeduplicate(TURs, GroupedReplacements, SM)) + return 1; + if (!mergeAndDeduplicate(TUDs, GroupedReplacements, SM)) return 1; Rewriter ReplacementsRewriter(SM, LangOptions()); |