summaryrefslogtreecommitdiff
path: root/lib/Frontend/TextDiagnosticPrinter.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-09-26 11:25:30 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-09-26 11:25:30 +0000
commit0ef898865aaec8c99addee23d01e03c7abdbd2b3 (patch)
tree3dde95709428ffbb6c08aaaff80fa0d1b3c6d49e /lib/Frontend/TextDiagnosticPrinter.cpp
parent75c1befb4592387ef1bec3bff5f0f5c0c931ea84 (diff)
downloadclang-0ef898865aaec8c99addee23d01e03c7abdbd2b3.tar.gz
Switch the emission of diagnostics without a source location to
a dedicated path. The logic for such diagnostics is much simpler than for others. This begins to make an important separation in this routine. We expect most (and most interesting) textual diagnostics to be made in the presence of at least *some* source locations and a source manager. However the DiagnosticConsumer must be prepared to diagnose errors even when the source manager doesn't (yet) exist or when there is no location information at all. In order to sink more and more logic into the TextDiagnostic class while minimizing its complexity, my plan is to force the DiagnosticConsumer to special case diagnosing any locationless messages and then hand the rest to the TextDiagnostic class. I'd appreciate any comments on this design. It requires a bit of code duplication in order to keep interfaces simple. Alternatively, if we really need TextDiagnostic to be capable of handling diagnostics even in the absence of a viable SourceManager, then this split isn't necessary. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140525 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/TextDiagnosticPrinter.cpp')
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp54
1 files changed, 32 insertions, 22 deletions
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index ef28bcd061..062419d11e 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -1168,6 +1168,17 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
// Default implementation (Warnings/errors count).
DiagnosticConsumer::HandleDiagnostic(Level, Info);
+ // Render the diagnostic message into a temporary buffer eagerly. We'll use
+ // this later as we print out the diagnostic to the terminal.
+ llvm::SmallString<100> OutStr;
+ Info.FormatDiagnostic(OutStr);
+
+ llvm::raw_svector_ostream DiagMessageStream(OutStr);
+ if (DiagOpts->ShowNames)
+ printDiagnosticName(DiagMessageStream, Info);
+ printDiagnosticOptions(DiagMessageStream, Level, Info, *DiagOpts);
+
+
// Keeps track of the the starting position of the location
// information (e.g., "foo.c:10:4:") that precedes the error
// message. We use this information to determine how long the
@@ -1177,32 +1188,31 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
if (!Prefix.empty())
OS << Prefix << ": ";
- if (Info.getLocation().isValid()) {
- const SourceManager &SM = Info.getSourceManager();
- PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Info.getLocation());
-
- // First, if this diagnostic is not in the main file, print out the
- // "included from" lines.
- PrintIncludeStack(Level, PLoc.getIncludeLoc(), SM);
- StartOfLocationInfo = OS.tell();
-
- // Next emit the location of this particular diagnostic.
- EmitDiagnosticLoc(Level, Info, SM, PLoc);
-
- if (DiagOpts->ShowColors)
- OS.resetColor();
+ // Use a dedicated, simpler path for diagnostics without a valid location.
+ if (!Info.getLocation().isValid()) {
+ printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
+ printDiagnosticMessage(OS, Level, DiagMessageStream.str(),
+ OS.tell() - StartOfLocationInfo,
+ DiagOpts->MessageLength, DiagOpts->ShowColors);
+ OS.flush();
+ return;
}
- printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
+ const SourceManager &SM = Info.getSourceManager();
+ PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Info.getLocation());
- llvm::SmallString<100> OutStr;
- Info.FormatDiagnostic(OutStr);
+ // First, if this diagnostic is not in the main file, print out the
+ // "included from" lines.
+ PrintIncludeStack(Level, PLoc.getIncludeLoc(), SM);
+ StartOfLocationInfo = OS.tell();
- llvm::raw_svector_ostream DiagMessageStream(OutStr);
- if (DiagOpts->ShowNames)
- printDiagnosticName(DiagMessageStream, Info);
- printDiagnosticOptions(DiagMessageStream, Level, Info, *DiagOpts);
+ // Next emit the location of this particular diagnostic.
+ EmitDiagnosticLoc(Level, Info, SM, PLoc);
+
+ if (DiagOpts->ShowColors)
+ OS.resetColor();
+ printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
printDiagnosticMessage(OS, Level, DiagMessageStream.str(),
OS.tell() - StartOfLocationInfo,
DiagOpts->MessageLength, DiagOpts->ShowColors);
@@ -1213,7 +1223,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
// was part of a different warning or error diagnostic, or if the
// diagnostic has ranges. We don't want to emit the same caret
// multiple times if one loc has multiple diagnostics.
- if (DiagOpts->ShowCarets && Info.getLocation().isValid() &&
+ if (DiagOpts->ShowCarets &&
((LastLoc != Info.getLocation()) || Info.getNumRanges() ||
(LastCaretDiagnosticWasNote && Level != DiagnosticsEngine::Note) ||
Info.getNumFixItHints())) {