diff options
Diffstat (limited to 'lib/Frontend/DiagnosticRenderer.cpp')
| -rw-r--r-- | lib/Frontend/DiagnosticRenderer.cpp | 168 |
1 files changed, 97 insertions, 71 deletions
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp index e3263843e29b..fb0a92d1f8c6 100644 --- a/lib/Frontend/DiagnosticRenderer.cpp +++ b/lib/Frontend/DiagnosticRenderer.cpp @@ -1,4 +1,4 @@ -//===--- DiagnosticRenderer.cpp - Diagnostic Pretty-Printing --------------===// +//===- DiagnosticRenderer.cpp - Diagnostic Pretty-Printing ----------------===// // // The LLVM Compiler Infrastructure // @@ -8,24 +8,34 @@ //===----------------------------------------------------------------------===// #include "clang/Frontend/DiagnosticRenderer.h" +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Edit/Commit.h" #include "clang/Edit/EditedSource.h" #include "clang/Edit/EditsReceiver.h" #include "clang/Lex/Lexer.h" -#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/None.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Support/ErrorHandling.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> +#include <cassert> +#include <iterator> +#include <utility> + using namespace clang; DiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts, DiagnosticOptions *DiagOpts) - : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {} + : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {} -DiagnosticRenderer::~DiagnosticRenderer() {} +DiagnosticRenderer::~DiagnosticRenderer() = default; namespace { @@ -34,24 +44,24 @@ class FixitReceiver : public edit::EditsReceiver { public: FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits) - : MergedFixits(MergedFixits) { } + : MergedFixits(MergedFixits) {} + void insert(SourceLocation loc, StringRef text) override { MergedFixits.push_back(FixItHint::CreateInsertion(loc, text)); } + void replace(CharSourceRange range, StringRef text) override { MergedFixits.push_back(FixItHint::CreateReplacement(range, text)); } }; -} +} // namespace static void mergeFixits(ArrayRef<FixItHint> FixItHints, const SourceManager &SM, const LangOptions &LangOpts, SmallVectorImpl<FixItHint> &MergedFixits) { edit::Commit commit(SM, LangOpts); - for (ArrayRef<FixItHint>::const_iterator - I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) { - const FixItHint &Hint = *I; + for (const auto &Hint : FixItHints) if (Hint.CodeToInsert.empty()) { if (Hint.InsertFromRange.isValid()) commit.insertFromRange(Hint.RemoveRange.getBegin(), @@ -67,7 +77,6 @@ static void mergeFixits(ArrayRef<FixItHint> FixItHints, commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert, /*afterToken=*/false, Hint.BeforePreviousInsertions); } - } edit::EditedSource Editor(SM, LangOpts); if (Editor.commit(commit)) { @@ -100,11 +109,9 @@ void DiagnosticRenderer::emitDiagnostic(FullSourceLoc Loc, FixItHints = MergedFixits; } - for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(), - E = FixItHints.end(); - I != E; ++I) - if (I->RemoveRange.isValid()) - MutableRanges.push_back(I->RemoveRange); + for (const auto &Hint : FixItHints) + if (Hint.RemoveRange.isValid()) + MutableRanges.push_back(Hint.RemoveRange); FullSourceLoc UnexpandedLoc = Loc; @@ -134,7 +141,6 @@ void DiagnosticRenderer::emitDiagnostic(FullSourceLoc Loc, endDiagnostic(D, Level); } - void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) { emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(), Diag.getRanges(), Diag.getFixIts(), @@ -146,7 +152,7 @@ void DiagnosticRenderer::emitBasicNote(StringRef Message) { Message, None, DiagOrStoredDiag()); } -/// \brief Prints an include stack when appropriate for a particular +/// Prints an include stack when appropriate for a particular /// diagnostic level and location. /// /// This routine handles all the logic of suppressing particular include @@ -180,7 +186,7 @@ void DiagnosticRenderer::emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc, } } -/// \brief Helper to recursivly walk up the include stack and print each layer +/// Helper to recursively walk up the include stack and print each layer /// on the way back down. void DiagnosticRenderer::emitIncludeStackRecursively(FullSourceLoc Loc) { if (Loc.isInvalid()) { @@ -210,7 +216,7 @@ void DiagnosticRenderer::emitIncludeStackRecursively(FullSourceLoc Loc) { emitIncludeLocation(Loc, PLoc); } -/// \brief Emit the module import stack associated with the current location. +/// Emit the module import stack associated with the current location. void DiagnosticRenderer::emitImportStack(FullSourceLoc Loc) { if (Loc.isInvalid()) { emitModuleBuildStack(Loc.getManager()); @@ -221,7 +227,7 @@ void DiagnosticRenderer::emitImportStack(FullSourceLoc Loc) { emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second); } -/// \brief Helper to recursivly walk up the import stack and print each layer +/// Helper to recursively walk up the import stack and print each layer /// on the way back down. void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc, StringRef ModuleName) { @@ -239,14 +245,14 @@ void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc, emitImportLocation(Loc, PLoc, ModuleName); } -/// \brief Emit the module build stack, for cases where a module is (re-)built +/// Emit the module build stack, for cases where a module is (re-)built /// on demand. void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) { ModuleBuildStack Stack = SM.getModuleBuildStack(); - for (unsigned I = 0, N = Stack.size(); I != N; ++I) { - emitBuildingModuleLocation(Stack[I].second, Stack[I].second.getPresumedLoc( - DiagOpts->ShowPresumedLoc), - Stack[I].first); + for (const auto &I : Stack) { + emitBuildingModuleLocation(I.second, I.second.getPresumedLoc( + DiagOpts->ShowPresumedLoc), + I.first); } } @@ -256,41 +262,54 @@ static SourceLocation retrieveMacroLocation(SourceLocation Loc, FileID MacroFileID, FileID CaretFileID, const SmallVectorImpl<FileID> &CommonArgExpansions, - bool IsBegin, const SourceManager *SM) { + bool IsBegin, const SourceManager *SM, + bool &IsTokenRange) { assert(SM->getFileID(Loc) == MacroFileID); if (MacroFileID == CaretFileID) return Loc; if (!Loc.isMacroID()) - return SourceLocation(); + return {}; - SourceLocation MacroLocation, MacroArgLocation; + CharSourceRange MacroRange, MacroArgRange; if (SM->isMacroArgExpansion(Loc)) { // Only look at the immediate spelling location of this macro argument if // the other location in the source range is also present in that expansion. if (std::binary_search(CommonArgExpansions.begin(), CommonArgExpansions.end(), MacroFileID)) - MacroLocation = SM->getImmediateSpellingLoc(Loc); - MacroArgLocation = IsBegin ? SM->getImmediateExpansionRange(Loc).first - : SM->getImmediateExpansionRange(Loc).second; + MacroRange = + CharSourceRange(SM->getImmediateSpellingLoc(Loc), IsTokenRange); + MacroArgRange = SM->getImmediateExpansionRange(Loc); } else { - MacroLocation = IsBegin ? SM->getImmediateExpansionRange(Loc).first - : SM->getImmediateExpansionRange(Loc).second; - MacroArgLocation = SM->getImmediateSpellingLoc(Loc); + MacroRange = SM->getImmediateExpansionRange(Loc); + MacroArgRange = + CharSourceRange(SM->getImmediateSpellingLoc(Loc), IsTokenRange); } + SourceLocation MacroLocation = + IsBegin ? MacroRange.getBegin() : MacroRange.getEnd(); if (MacroLocation.isValid()) { MacroFileID = SM->getFileID(MacroLocation); + bool TokenRange = IsBegin ? IsTokenRange : MacroRange.isTokenRange(); MacroLocation = retrieveMacroLocation(MacroLocation, MacroFileID, CaretFileID, - CommonArgExpansions, IsBegin, SM); - if (MacroLocation.isValid()) + CommonArgExpansions, IsBegin, SM, TokenRange); + if (MacroLocation.isValid()) { + IsTokenRange = TokenRange; return MacroLocation; + } } + // If we moved the end of the range to an expansion location, we now have + // a range of the same kind as the expansion range. + if (!IsBegin) + IsTokenRange = MacroArgRange.isTokenRange(); + + SourceLocation MacroArgLocation = + IsBegin ? MacroArgRange.getBegin() : MacroArgRange.getEnd(); MacroFileID = SM->getFileID(MacroArgLocation); return retrieveMacroLocation(MacroArgLocation, MacroFileID, CaretFileID, - CommonArgExpansions, IsBegin, SM); + CommonArgExpansions, IsBegin, SM, IsTokenRange); } /// Walk up the chain of macro expansions and collect the FileIDs identifying the @@ -304,7 +323,7 @@ static void getMacroArgExpansionFileIDs(SourceLocation Loc, Loc = SM->getImmediateSpellingLoc(Loc); } else { auto ExpRange = SM->getImmediateExpansionRange(Loc); - Loc = IsBegin ? ExpRange.first : ExpRange.second; + Loc = IsBegin ? ExpRange.getBegin() : ExpRange.getEnd(); } } } @@ -318,8 +337,8 @@ static void computeCommonMacroArgExpansionFileIDs( SmallVector<FileID, 4> EndArgExpansions; getMacroArgExpansionFileIDs(Begin, BeginArgExpansions, /*IsBegin=*/true, SM); getMacroArgExpansionFileIDs(End, EndArgExpansions, /*IsBegin=*/false, SM); - std::sort(BeginArgExpansions.begin(), BeginArgExpansions.end()); - std::sort(EndArgExpansions.begin(), EndArgExpansions.end()); + llvm::sort(BeginArgExpansions.begin(), BeginArgExpansions.end()); + llvm::sort(EndArgExpansions.begin(), EndArgExpansions.end()); std::set_intersection(BeginArgExpansions.begin(), BeginArgExpansions.end(), EndArgExpansions.begin(), EndArgExpansions.end(), std::back_inserter(CommonArgExpansions)); @@ -342,11 +361,12 @@ mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges, const SourceManager *SM = &CaretLoc.getManager(); - for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { - if (I->isInvalid()) continue; + for (const auto &Range : Ranges) { + if (Range.isInvalid()) + continue; - SourceLocation Begin = I->getBegin(), End = I->getEnd(); - bool IsTokenRange = I->isTokenRange(); + SourceLocation Begin = Range.getBegin(), End = Range.getEnd(); + bool IsTokenRange = Range.isTokenRange(); FileID BeginFileID = SM->getFileID(Begin); FileID EndFileID = SM->getFileID(End); @@ -357,14 +377,16 @@ mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges, llvm::SmallDenseMap<FileID, SourceLocation> BeginLocsMap; while (Begin.isMacroID() && BeginFileID != EndFileID) { BeginLocsMap[BeginFileID] = Begin; - Begin = SM->getImmediateExpansionRange(Begin).first; + Begin = SM->getImmediateExpansionRange(Begin).getBegin(); BeginFileID = SM->getFileID(Begin); } // Then, crawl the expansion chain for the end of the range. if (BeginFileID != EndFileID) { while (End.isMacroID() && !BeginLocsMap.count(EndFileID)) { - End = SM->getImmediateExpansionRange(End).second; + auto Exp = SM->getImmediateExpansionRange(End); + IsTokenRange = Exp.isTokenRange(); + End = Exp.getEnd(); EndFileID = SM->getFileID(End); } if (End.isMacroID()) { @@ -377,9 +399,11 @@ mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges, SmallVector<FileID, 4> CommonArgExpansions; computeCommonMacroArgExpansionFileIDs(Begin, End, SM, CommonArgExpansions); Begin = retrieveMacroLocation(Begin, BeginFileID, CaretLocFileID, - CommonArgExpansions, /*IsBegin=*/true, SM); + CommonArgExpansions, /*IsBegin=*/true, SM, + IsTokenRange); End = retrieveMacroLocation(End, BeginFileID, CaretLocFileID, - CommonArgExpansions, /*IsBegin=*/false, SM); + CommonArgExpansions, /*IsBegin=*/false, SM, + IsTokenRange); if (Begin.isInvalid() || End.isInvalid()) continue; // Return the spelling location of the beginning and end of the range. @@ -400,7 +424,7 @@ void DiagnosticRenderer::emitCaret(FullSourceLoc Loc, emitCodeContext(Loc, Level, SpellingRanges, Hints); } -/// \brief A helper function for emitMacroExpansion to print the +/// A helper function for emitMacroExpansion to print the /// macro expansion message void DiagnosticRenderer::emitSingleMacroExpansion( FullSourceLoc Loc, DiagnosticsEngine::Level Level, @@ -441,7 +465,7 @@ static bool checkLocForMacroArgExpansion(SourceLocation Loc, } /// Check if all the locations in the range have the same macro argument -/// expansion, and that that expansion starts with ArgumentLoc. +/// expansion, and that the expansion starts with ArgumentLoc. static bool checkRangeForMacroArgExpansion(CharSourceRange Range, const SourceManager &SM, SourceLocation ArgumentLoc) { @@ -466,8 +490,9 @@ static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc, /// Count all valid ranges. unsigned ValidCount = 0; - for (auto I : Ranges) - if (I.isValid()) ValidCount++; + for (const auto &Range : Ranges) + if (Range.isValid()) + ValidCount++; if (ValidCount > SpellingRanges.size()) return false; @@ -480,15 +505,14 @@ static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc, if (!Loc.isMacroArgExpansion(&ArgumentLoc)) return false; - for (auto I = SpellingRanges.begin(), E = SpellingRanges.end(); I != E; ++I) { - if (!checkRangeForMacroArgExpansion(*I, Loc.getManager(), ArgumentLoc)) + for (const auto &Range : SpellingRanges) + if (!checkRangeForMacroArgExpansion(Range, Loc.getManager(), ArgumentLoc)) return false; - } return true; } -/// \brief Recursively emit notes for each macro expansion and caret +/// Recursively emit notes for each macro expansion and caret /// diagnostics where appropriate. /// /// Walks up the macro expansion stack printing expansion notes, the code @@ -504,29 +528,31 @@ void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc, ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints) { assert(Loc.isValid() && "must have a valid source location here"); + const SourceManager &SM = Loc.getManager(); + SourceLocation L = Loc; // Produce a stack of macro backtraces. - SmallVector<FullSourceLoc, 8> LocationStack; + SmallVector<SourceLocation, 8> LocationStack; unsigned IgnoredEnd = 0; - while (Loc.isMacroID()) { + while (L.isMacroID()) { // If this is the expansion of a macro argument, point the caret at the // use of the argument in the definition of the macro, not the expansion. - if (Loc.isMacroArgExpansion()) - LocationStack.push_back(Loc.getImmediateExpansionRange().first); + if (SM.isMacroArgExpansion(L)) + LocationStack.push_back(SM.getImmediateExpansionRange(L).getBegin()); else - LocationStack.push_back(Loc); + LocationStack.push_back(L); - if (checkRangesForMacroArgExpansion(Loc, Ranges)) + if (checkRangesForMacroArgExpansion(FullSourceLoc(L, SM), Ranges)) IgnoredEnd = LocationStack.size(); - Loc = Loc.getImmediateMacroCallerLoc(); + L = SM.getImmediateMacroCallerLoc(L); // Once the location no longer points into a macro, try stepping through // the last found location. This sometimes produces additional useful // backtraces. - if (Loc.isFileID()) - Loc = LocationStack.back().getImmediateMacroCallerLoc(); - assert(Loc.isValid() && "must have a valid source location here"); + if (L.isFileID()) + L = SM.getImmediateMacroCallerLoc(LocationStack.back()); + assert(L.isValid() && "must have a valid source location here"); } LocationStack.erase(LocationStack.begin(), @@ -537,7 +563,7 @@ void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc, if (MacroDepth <= MacroLimit || MacroLimit == 0) { for (auto I = LocationStack.rbegin(), E = LocationStack.rend(); I != E; ++I) - emitSingleMacroExpansion(*I, Level, Ranges); + emitSingleMacroExpansion(FullSourceLoc(*I, SM), Level, Ranges); return; } @@ -547,7 +573,7 @@ void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc, for (auto I = LocationStack.rbegin(), E = LocationStack.rbegin() + MacroStartMessages; I != E; ++I) - emitSingleMacroExpansion(*I, Level, Ranges); + emitSingleMacroExpansion(FullSourceLoc(*I, SM), Level, Ranges); SmallString<200> MessageStorage; llvm::raw_svector_ostream Message(MessageStorage); @@ -559,10 +585,10 @@ void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc, for (auto I = LocationStack.rend() - MacroEndMessages, E = LocationStack.rend(); I != E; ++I) - emitSingleMacroExpansion(*I, Level, Ranges); + emitSingleMacroExpansion(FullSourceLoc(*I, SM), Level, Ranges); } -DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {} +DiagnosticNoteRenderer::~DiagnosticNoteRenderer() = default; void DiagnosticNoteRenderer::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) { |
