diff options
| author | Chris Lattner <sabre@nondot.org> | 2009-02-17 08:44:50 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2009-02-17 08:44:50 +0000 |
| commit | 7b60a164b19662061bc7125f46ae7c516fd09b52 (patch) | |
| tree | d9baebd57b21db276528c83285555747c906624f | |
| parent | a6f037cee1a80d7616f83f7ce0e629eeed19d357 (diff) | |
| download | bcm5719-llvm-7b60a164b19662061bc7125f46ae7c516fd09b52.tar.gz bcm5719-llvm-7b60a164b19662061bc7125f46ae7c516fd09b52.zip | |
As an experimental hack, emit "instantiated from" information in
diagnostics. I'm not sure I want to keep this, but hey, it's easy
and could be useful or something, even if guarded by a
-fshow-me-tons-of-details option. A silly example is:
#define A B
#define C A
#define D C
int y = D;
We now emit:
t.c:11:9: error: use of undeclared identifier 'B'
int y = D;
^
t.c:9:11: note: instantiated from:
#define D C
^
t.c:8:11: note: instantiated from:
#define C A
^
t.c:7:11: note: instantiated from:
#define A B
^
A more useful example is from tgmath:
t.c:4:9: error: no matching function for call to '__tg_acos'
return acos(x);
^~~~~~~
/Users/sabre/llvm/Debug/Headers/tgmath-sofar.h:51:17: note: instantiated from:
#define acos(x) __tg_acos(x)
^
... candidate set follows ...
This does not yet print ranges in instantiation info, (e.g. highlighting the
range "__tg_acos(x)" in the last example), but that could be added if we
decide this is a good idea :).
Thoughts and bug reports welcome!
llvm-svn: 64761
| -rw-r--r-- | clang/lib/Driver/TextDiagnosticPrinter.cpp | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/clang/lib/Driver/TextDiagnosticPrinter.cpp b/clang/lib/Driver/TextDiagnosticPrinter.cpp index c6a8a23facc..a9d011a6cb7 100644 --- a/clang/lib/Driver/TextDiagnosticPrinter.cpp +++ b/clang/lib/Driver/TextDiagnosticPrinter.cpp @@ -104,9 +104,25 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, void TextDiagnosticPrinter::EmitCaretDiagnostic(const DiagnosticInfo &Info, SourceLocation Loc, SourceManager &SM) { + assert(!Loc.isInvalid() && "must have a valid source location here"); + // We always emit diagnostics about the instantiation points, not the spelling // points. This more closely correlates to what the user writes. - Loc = SM.getInstantiationLoc(Loc); + if (!Loc.isFileID()) { + SourceLocation OneLevelUp; + OneLevelUp = SM.getImmediateInstantiationRange(Loc).first; + + EmitCaretDiagnostic(Info, OneLevelUp, SM); + + Loc = SM.getInstantiationLoc(SM.getImmediateSpellingLoc(Loc)); + + // Emit the file/line/column that this expansion came from. + OS << SM.getBufferName(Loc) << ':' << SM.getInstantiationLineNumber(Loc) + << ':'; + if (ShowColumn) + OS << SM.getInstantiationColumnNumber(Loc) << ':'; + OS << " note: instantiated from:\n"; + } // Decompose the location into a FID/Offset pair. std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); |

