diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-01-28 00:27:43 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-01-28 00:27:43 +0000 |
commit | 5352ac06d8f6194825bb2a99ffa009b61bafb503 (patch) | |
tree | e50e65bcdcd96fb196e24794c7086caa9b489bfd /tools/c-index-test/c-index-test.c | |
parent | f291976ecf537dc4f2d5537b1664d47ff4b94865 (diff) |
Implement a diagnostics callback for the C interface to Clang, so that
clients can format diagnostics as they wish rather than having to
parse standard error. All of the important parts of the front end's
diagnostics are exposed: text, severity, location, source ranges, and
fix-its. The diagnostics callback is now available with
clang_createTranslationUnitFromSource() and
clang_createTranslationUnit().
As part of this change, CXSourceLocation and CXSourceRange got one
pointer larger, since we need to hold on to the SourceManager and
LangOptions structures in the source location. This is the minimum
amount of information needed for the functions that operate on source
locations and ranges (as implemented now). Previously we held on to
the ASTContext, but the diagnostics callback can end up with source
locations when there is no ASTContext (or preprocessor).
Still to do:
- Code completion needs to support the diagnostics callback, once we
have the ability to (de-)serialize diagnostics.
- Eliminate the "displayDiagnostics" argument to createIndex; we'll
always pass diagnostics to the callback and let it deal with display.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94709 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/c-index-test/c-index-test.c')
-rw-r--r-- | tools/c-index-test/c-index-test.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 2ad9da12bb..39c3446f04 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -28,10 +28,13 @@ char *basename(const char* path) extern char *basename(const char *); #endif +static void PrintDiagnosticCallback(CXDiagnostic Diagnostic, + CXClientData ClientData); + static unsigned CreateTranslationUnit(CXIndex Idx, const char *file, CXTranslationUnit *TU) { - *TU = clang_createTranslationUnit(Idx, file); + *TU = clang_createTranslationUnit(Idx, file, PrintDiagnosticCallback, 0); if (!TU) { fprintf(stderr, "Unable to load translation unit from '%s'!\n", file); return 0; @@ -177,6 +180,41 @@ static const char* GetCursorSource(CXCursor Cursor) { typedef void (*PostVisitTU)(CXTranslationUnit); +static void PrintDiagnosticCallback(CXDiagnostic Diagnostic, + CXClientData ClientData) { + FILE *out = (FILE *)ClientData; + CXFile file; + unsigned line, column; + CXString text; + enum CXDiagnosticSeverity severity = clang_getDiagnosticSeverity(Diagnostic); + + /* Ignore diagnostics that should be ignored. */ + if (severity == CXDiagnostic_Ignored) + return; + + /* Print file:line:column. */ + clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic), + &file, &line, &column, 0); + if (file) + fprintf(out, "%s:%d:%d: ", clang_getFileName(file), line, column); + + /* Print warning/error/etc. */ + switch (severity) { + case CXDiagnostic_Ignored: assert(0 && "impossible"); break; + case CXDiagnostic_Note: fprintf(out, "note: "); break; + case CXDiagnostic_Warning: fprintf(out, "warning: "); break; + case CXDiagnostic_Error: fprintf(out, "error: "); break; + case CXDiagnostic_Fatal: fprintf(out, "fatal error: "); break; + } + + text = clang_getDiagnosticSpelling(Diagnostic); + if (clang_getCString(text)) + fprintf(out, "%s\n", clang_getCString(text)); + else + fprintf(out, "<no diagnostic text>\n"); + clang_disposeString(text); +} + /******************************************************************************/ /* Logic for testing traversal. */ /******************************************************************************/ @@ -407,7 +445,9 @@ int perform_test_load_source(int argc, const char **argv, argc - num_unsaved_files, argv + num_unsaved_files, num_unsaved_files, - unsaved_files); + unsaved_files, + PrintDiagnosticCallback, + stderr); if (!TU) { fprintf(stderr, "Unable to load translation unit!\n"); return 1; @@ -722,7 +762,9 @@ int inspect_cursor_at(int argc, const char **argv) { argc - num_unsaved_files - 2 - NumLocations, argv + num_unsaved_files + 1 + NumLocations, num_unsaved_files, - unsaved_files); + unsaved_files, + PrintDiagnosticCallback, + stderr); if (!TU) { fprintf(stderr, "unable to parse input\n"); return -1; @@ -779,7 +821,9 @@ int perform_token_annotation(int argc, const char **argv) { argc - num_unsaved_files - 3, argv + num_unsaved_files + 2, num_unsaved_files, - unsaved_files); + unsaved_files, + PrintDiagnosticCallback, + stderr); if (!TU) { fprintf(stderr, "unable to parse input\n"); clang_disposeIndex(CIdx); |