summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/Driver/clang.cpp11
-rw-r--r--clang/include/clang/Frontend/TextDiagnosticPrinter.h7
-rw-r--r--clang/lib/Frontend/TextDiagnosticPrinter.cpp32
3 files changed, 45 insertions, 5 deletions
diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp
index a0195c629a7..171e4ecb311 100644
--- a/clang/Driver/clang.cpp
+++ b/clang/Driver/clang.cpp
@@ -202,6 +202,10 @@ NoCaretDiagnostics("fno-caret-diagnostics",
llvm::cl::desc("Do not include source line and caret with"
" diagnostics"));
+static llvm::cl::opt<bool>
+PrintSourceRangeInfo("fprint-source-range-info",
+ llvm::cl::desc("Print source range spans in numeric form"));
+
//===----------------------------------------------------------------------===//
// C++ Visualization.
@@ -799,6 +803,8 @@ static std::string CreateTargetTriple() {
// -A... - Play with #assertions
// -undef - Undefine all predefined macros
+// FIXME: -imacros
+
static llvm::cl::list<std::string>
D_macros("D", llvm::cl::value_desc("macro"), llvm::cl::Prefix,
llvm::cl::desc("Predefine the specified macro"));
@@ -810,7 +816,6 @@ static llvm::cl::list<std::string>
ImplicitIncludes("include", llvm::cl::value_desc("file"),
llvm::cl::desc("Include file before parsing"));
-
// Append a #define line to Buf for Macro. Macro should be of the form XXX,
// in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
// "#define XXX Y z W". To get a #define with no value, use "XXX=".
@@ -910,7 +915,6 @@ static bool InitializePreprocessor(Preprocessor &PP,
// FIXME: -nostdinc,-nostdinc++
// FIXME: -imultilib
//
-// FIXME: -imacros
static llvm::cl::opt<bool>
nostdinc("nostdinc", llvm::cl::desc("Disable standard #include directories"));
@@ -1496,7 +1500,8 @@ int main(int argc, char **argv) {
TextDiagClient = new TextDiagnosticPrinter(llvm::errs(),
!NoShowColumn,
!NoCaretDiagnostics,
- !NoShowLocation);
+ !NoShowLocation,
+ PrintSourceRangeInfo);
} else {
// When checking diagnostics, just buffer them up.
TextDiagClient = new TextDiagnosticBuffer();
diff --git a/clang/include/clang/Frontend/TextDiagnosticPrinter.h b/clang/include/clang/Frontend/TextDiagnosticPrinter.h
index eeff2795131..0f08a952839 100644
--- a/clang/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/clang/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -33,11 +33,14 @@ class TextDiagnosticPrinter : public DiagnosticClient {
bool ShowColumn;
bool CaretDiagnostics;
bool ShowLocation;
+ bool PrintRangeInfo;
public:
TextDiagnosticPrinter(llvm::raw_ostream &os, bool showColumn = true,
- bool caretDiagnistics = true, bool showLocation = true)
+ bool caretDiagnistics = true, bool showLocation = true,
+ bool printRangeInfo = true)
: LastCaretDiagnosticWasNote(false), OS(os), ShowColumn(showColumn),
- CaretDiagnostics(caretDiagnistics), ShowLocation(showLocation) {}
+ CaretDiagnostics(caretDiagnistics), ShowLocation(showLocation),
+ PrintRangeInfo(printRangeInfo) {}
void PrintIncludeStack(SourceLocation Loc, const SourceManager &SM);
diff --git a/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/clang/lib/Frontend/TextDiagnosticPrinter.cpp
index 160b5cfae11..f1555dbff31 100644
--- a/clang/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/clang/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -261,6 +261,38 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
if (ShowColumn)
if (unsigned ColNo = PLoc.getColumn())
OS << ColNo << ':';
+
+ if (PrintRangeInfo && Info.getNumRanges()) {
+ FileID CaretFileID =
+ SM.getFileID(SM.getInstantiationLoc(Info.getLocation()));
+ bool PrintedRange = false;
+
+ for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) {
+ SourceLocation B = Info.getRange(i).getBegin();
+ SourceLocation E = Info.getRange(i).getEnd();
+ std::pair<FileID, unsigned> BInfo=SM.getDecomposedInstantiationLoc(B);
+
+ E = SM.getInstantiationLoc(E);
+ std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
+
+ // If the start or end of the range is in another file, just discard
+ // it.
+ if (BInfo.first != CaretFileID || EInfo.first != CaretFileID)
+ continue;
+
+ // Add in the length of the token, so that we cover multi-char tokens.
+ unsigned TokSize = Lexer::MeasureTokenLength(E, SM);
+
+ OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
+ << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
+ << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
+ << (SM.getColumnNumber(EInfo.first, EInfo.second)+TokSize) << '}';
+ PrintedRange = true;
+ }
+
+ if (PrintedRange)
+ OS << ':';
+ }
OS << ' ';
}
}
OpenPOWER on IntegriCloud