diff options
author | Chris Lattner <sabre@nondot.org> | 2010-06-18 22:45:06 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-06-18 22:45:06 +0000 |
commit | 0a76aae8c03cb7dd7bdbe683485560afaf695959 (patch) | |
tree | be02325d4dbabf2f026a3297efe51a3e3511fa05 /lib | |
parent | 96fb42ea29253cf2b34848dfdb3e40ef14ca8ebc (diff) |
introduce a new CharSourceRange class, and enhance the diagnostics routines
to use them instead of SourceRange. CharSourceRange is just a SourceRange
plus a bool that indicates whether the range has the end character resolved
or whether the end location is the start of the end token. While most of
the compiler wants to think of ranges that have ends that are the start of
the end token, the printf diagnostic stuff wants to highlight ranges within
tokens.
This is transparent to the diagnostic stuff. To start taking advantage of
the new capabilities, you can do something like this:
Diag(..) << CharSourceRange::getCharRange(Begin,End)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106338 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Basic/Diagnostic.cpp | 18 | ||||
-rw-r--r-- | lib/Checker/PathDiagnostic.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/TextDiagnosticPrinter.cpp | 30 | ||||
-rw-r--r-- | lib/Rewrite/Rewriter.cpp | 12 |
4 files changed, 40 insertions, 22 deletions
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index a2480b1684..641d87bb9a 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -1043,8 +1043,7 @@ StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info) - : Level(Level), Loc(Info.getLocation()) -{ + : Level(Level), Loc(Info.getLocation()) { llvm::SmallString<64> Message; Info.FormatDiagnostic(Message); this->Message.assign(Message.begin(), Message.end()); @@ -1131,6 +1130,7 @@ void StoredDiagnostic::Serialize(llvm::raw_ostream &OS) const { WriteSourceLocation(OS, SM, R->getBegin()); WriteSourceLocation(OS, SM, R->getEnd()); + WriteUnsigned(OS, R->isTokenRange()); } } @@ -1159,6 +1159,7 @@ void StoredDiagnostic::Serialize(llvm::raw_ostream &OS) const { for (fixit_iterator F = fixit_begin(), FEnd = fixit_end(); F != FEnd; ++F) { WriteSourceLocation(OS, SM, F->RemoveRange.getBegin()); WriteSourceLocation(OS, SM, F->RemoveRange.getEnd()); + WriteUnsigned(OS, F->RemoveRange.isTokenRange()); WriteSourceLocation(OS, SM, F->InsertionLoc); WriteString(OS, F->CodeToInsert); } @@ -1272,11 +1273,14 @@ StoredDiagnostic::Deserialize(FileManager &FM, SourceManager &SM, return Diag; for (unsigned I = 0; I != NumSourceRanges; ++I) { SourceLocation Begin, End; + unsigned IsTokenRange; if (ReadSourceLocation(FM, SM, Memory, MemoryEnd, Begin) || - ReadSourceLocation(FM, SM, Memory, MemoryEnd, End)) + ReadSourceLocation(FM, SM, Memory, MemoryEnd, End) || + ReadUnsigned(Memory, MemoryEnd, IsTokenRange)) return Diag; - Diag.Ranges.push_back(SourceRange(Begin, End)); + Diag.Ranges.push_back(CharSourceRange(SourceRange(Begin, End), + IsTokenRange)); } // Read the fix-it hints. @@ -1285,9 +1289,10 @@ StoredDiagnostic::Deserialize(FileManager &FM, SourceManager &SM, return Diag; for (unsigned I = 0; I != NumFixIts; ++I) { SourceLocation RemoveBegin, RemoveEnd, InsertionLoc; - unsigned InsertLen = 0; + unsigned InsertLen = 0, RemoveIsTokenRange; if (ReadSourceLocation(FM, SM, Memory, MemoryEnd, RemoveBegin) || ReadSourceLocation(FM, SM, Memory, MemoryEnd, RemoveEnd) || + ReadUnsigned(Memory, MemoryEnd, RemoveIsTokenRange) || ReadSourceLocation(FM, SM, Memory, MemoryEnd, InsertionLoc) || ReadUnsigned(Memory, MemoryEnd, InsertLen) || Memory + InsertLen > MemoryEnd) { @@ -1296,7 +1301,8 @@ StoredDiagnostic::Deserialize(FileManager &FM, SourceManager &SM, } FixItHint Hint; - Hint.RemoveRange = SourceRange(RemoveBegin, RemoveEnd); + Hint.RemoveRange = CharSourceRange(SourceRange(RemoveBegin, RemoveEnd), + RemoveIsTokenRange); Hint.InsertionLoc = InsertionLoc; Hint.CodeToInsert.assign(Memory, Memory + InsertLen); Memory += InsertLen; diff --git a/lib/Checker/PathDiagnostic.cpp b/lib/Checker/PathDiagnostic.cpp index 963923c9ad..6e6c7496f1 100644 --- a/lib/Checker/PathDiagnostic.cpp +++ b/lib/Checker/PathDiagnostic.cpp @@ -107,7 +107,7 @@ void PathDiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel, new PathDiagnosticEventPiece(Info.getLocation(), StrC.str()); for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) - P->addRange(Info.getRange(i)); + P->addRange(Info.getRange(i).getAsRange()); for (unsigned i = 0, e = Info.getNumFixItHints(); i != e; ++i) P->addFixItHint(Info.getFixItHint(i)); D->push_front(P); diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp index 6ccf4f1ad0..3f1eb82f7e 100644 --- a/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/lib/Frontend/TextDiagnosticPrinter.cpp @@ -70,7 +70,7 @@ PrintIncludeStack(SourceLocation Loc, const SourceManager &SM) { /// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s) /// any characters in LineNo that intersect the SourceRange. -void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, +void TextDiagnosticPrinter::HighlightRange(const CharSourceRange &R, const SourceManager &SM, unsigned LineNo, FileID FID, std::string &CaretLine, @@ -112,8 +112,10 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, if (EndColNo) { --EndColNo; // Zero base the col #. - // Add in the length of the token, so that we cover multi-char tokens. - EndColNo += Lexer::MeasureTokenLength(End, SM, *LangOpts); + // Add in the length of the token, so that we cover multi-char tokens if + // this is a token range. + if (R.isTokenRange()) + EndColNo += Lexer::MeasureTokenLength(End, SM, *LangOpts); } else { EndColNo = CaretLine.size(); } @@ -281,7 +283,7 @@ static void SelectInterestingSourceRegion(std::string &SourceLine, } void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, - SourceRange *Ranges, + CharSourceRange *Ranges, unsigned NumRanges, const SourceManager &SM, const FixItHint *Hints, @@ -312,10 +314,12 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, // Map the ranges. for (unsigned i = 0; i != NumRanges; ++i) { - SourceLocation S = Ranges[i].getBegin(), E = Ranges[i].getEnd(); - if (S.isMacroID()) S = SM.getImmediateSpellingLoc(S); - if (E.isMacroID()) E = SM.getImmediateSpellingLoc(E); - Ranges[i] = SourceRange(S, E); + CharSourceRange &R = Ranges[i]; + SourceLocation S = R.getBegin(), E = R.getEnd(); + if (S.isMacroID()) + R.setBegin(SM.getImmediateSpellingLoc(S)); + if (E.isMacroID()) + R.setEnd(SM.getImmediateSpellingLoc(E)); } if (!Suppressed) { @@ -777,7 +781,9 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, continue; // Add in the length of the token, so that we cover multi-char tokens. - unsigned TokSize = Lexer::MeasureTokenLength(E, SM, *LangOpts); + unsigned TokSize = 0; + if (Info.getRange(i).isTokenRange()) + TokSize = Lexer::MeasureTokenLength(E, SM, *LangOpts); OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':' << SM.getColumnNumber(BInfo.first, BInfo.second) << '-' @@ -904,15 +910,15 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, LastCaretDiagnosticWasNote = (Level == Diagnostic::Note); // Get the ranges into a local array we can hack on. - SourceRange Ranges[20]; + CharSourceRange Ranges[20]; unsigned NumRanges = Info.getNumRanges(); assert(NumRanges < 20 && "Out of space"); for (unsigned i = 0; i != NumRanges; ++i) Ranges[i] = Info.getRange(i); unsigned NumHints = Info.getNumFixItHints(); - for (unsigned idx = 0; idx < NumHints; ++idx) { - const FixItHint &Hint = Info.getFixItHint(idx); + for (unsigned i = 0; i != NumHints; ++i) { + const FixItHint &Hint = Info.getFixItHint(i); if (Hint.RemoveRange.isValid()) { assert(NumRanges < 20 && "Out of space"); Ranges[NumRanges++] = Hint.RemoveRange; diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp index 376678a5d7..8b0bf91a95 100644 --- a/lib/Rewrite/Rewriter.cpp +++ b/lib/Rewrite/Rewriter.cpp @@ -72,7 +72,7 @@ void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength, /// getRangeSize - Return the size in bytes of the specified range if they /// are in the same file. If not, this returns -1. -int Rewriter::getRangeSize(SourceRange Range) const { +int Rewriter::getRangeSize(const CharSourceRange &Range) const { if (!isRewritable(Range.getBegin()) || !isRewritable(Range.getEnd())) return -1; @@ -97,12 +97,18 @@ int Rewriter::getRangeSize(SourceRange Range) const { // Adjust the end offset to the end of the last token, instead of being the - // start of the last token. - EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts); + // start of the last token if this is a token range. + if (Range.isTokenRange()) + EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts); return EndOff-StartOff; } +int Rewriter::getRangeSize(SourceRange Range) const { + return getRangeSize(CharSourceRange::getTokenRange(Range)); +} + + /// getRewrittenText - Return the rewritten form of the text in the specified /// range. If the start or end of the range was unrewritable or if they are /// in different buffers, this returns an empty string. |