diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp')
-rw-r--r-- | clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp index 0d6c0a94d45..0abd63ee56b 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -18,8 +18,10 @@ #include "ClangTidyDiagnosticConsumer.h" #include "ClangTidyOptions.h" #include "clang/AST/ASTDiagnostic.h" +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Frontend/DiagnosticRenderer.h" +#include "clang/Tooling/Core/Diagnostic.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include <tuple> @@ -68,6 +70,9 @@ protected: SmallVectorImpl<CharSourceRange> &Ranges, ArrayRef<FixItHint> Hints) override { assert(Loc.isValid()); + tooling::DiagnosticMessage *DiagWithFix = + Level == DiagnosticsEngine::Note ? &Error.Notes.back() : &Error.Message; + for (const auto &FixIt : Hints) { CharSourceRange Range = FixIt.RemoveRange; assert(Range.getBegin().isValid() && Range.getEnd().isValid() && @@ -77,7 +82,8 @@ protected: tooling::Replacement Replacement(Loc.getManager(), Range, FixIt.CodeToInsert); - llvm::Error Err = Error.Fix[Replacement.getFilePath()].add(Replacement); + llvm::Error Err = + DiagWithFix->Fix[Replacement.getFilePath()].add(Replacement); // FIXME: better error handling (at least, don't let other replacements be // applied). if (Err) { @@ -581,9 +587,17 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() { // Compute error sizes. std::vector<int> Sizes; - for (const auto &Error : Errors) { + std::vector< + std::pair<ClangTidyError *, llvm::StringMap<tooling::Replacements> *>> + ErrorFixes; + for (auto &Error : Errors) { + if (const auto *Fix = tooling::selectFirstFix(Error)) + ErrorFixes.emplace_back( + &Error, const_cast<llvm::StringMap<tooling::Replacements> *>(Fix)); + } + for (const auto &ErrorAndFix : ErrorFixes) { int Size = 0; - for (const auto &FileAndReplaces : Error.Fix) { + for (const auto &FileAndReplaces : *ErrorAndFix.second) { for (const auto &Replace : FileAndReplaces.second) Size += Replace.getLength(); } @@ -592,8 +606,8 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() { // Build events from error intervals. std::map<std::string, std::vector<Event>> FileEvents; - for (unsigned I = 0; I < Errors.size(); ++I) { - for (const auto &FileAndReplace : Errors[I].Fix) { + for (unsigned I = 0; I < ErrorFixes.size(); ++I) { + for (const auto &FileAndReplace : *ErrorFixes[I].second) { for (const auto &Replace : FileAndReplace.second) { unsigned Begin = Replace.getOffset(); unsigned End = Begin + Replace.getLength(); @@ -608,7 +622,7 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() { } } - std::vector<bool> Apply(Errors.size(), true); + std::vector<bool> Apply(ErrorFixes.size(), true); for (auto &FileAndEvents : FileEvents) { std::vector<Event> &Events = FileAndEvents.second; // Sweep. @@ -627,10 +641,10 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() { assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match"); } - for (unsigned I = 0; I < Errors.size(); ++I) { + for (unsigned I = 0; I < ErrorFixes.size(); ++I) { if (!Apply[I]) { - Errors[I].Fix.clear(); - Errors[I].Notes.emplace_back( + ErrorFixes[I].second->clear(); + ErrorFixes[I].first->Notes.emplace_back( "this fix will not be applied because it overlaps with another fix"); } } |