diff options
author | Dmitri Gribenko <gribozavr@gmail.com> | 2014-02-12 19:12:37 +0000 |
---|---|---|
committer | Dmitri Gribenko <gribozavr@gmail.com> | 2014-02-12 19:12:37 +0000 |
commit | ea4d1c32fb9681b093461e03fc098f8f29f71b5b (patch) | |
tree | ffc026456ec5ef9cd5fd464247a7528d967074f6 /clang/tools/c-index-test | |
parent | 2039d446034b332c2ce9238924f74a1c2304014f (diff) | |
download | bcm5719-llvm-ea4d1c32fb9681b093461e03fc098f8f29f71b5b.tar.gz bcm5719-llvm-ea4d1c32fb9681b093461e03fc098f8f29f71b5b.zip |
libclang: report error code for bad PCH files
This commit improves libclang to report the error condition when
CXTranslationUnit can not be created because of a stale PCH file. This allows
the caller, for example, to rebuild the PCH file and retry the request.
There two are APIs in libclang that return a CXTranslationUnit and don't
support reporting detailed errors (the only error condition is a NULL result).
For these APIs, a second, superior, version is introduced --
clang_createTranslationUnit2 and clang_parseTranslationUnit2. These functions
return a CXTranslationUnit indirectly and also return an error code. Old
functions are still supported and are nothing more than convenience wrappers
that ignore extended error codes.
As a cleanup, this commit also categorizes some libclang errors in the
functions I had to modify anyway.
llvm-svn: 201249
Diffstat (limited to 'clang/tools/c-index-test')
-rw-r--r-- | clang/tools/c-index-test/c-index-test.c | 236 |
1 files changed, 150 insertions, 86 deletions
diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index 7f5bf4c2edf..8895371d55b 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -79,8 +79,33 @@ static unsigned getDefaultParsingOptions() { return options; } +/// \brief Returns 0 in case of success, non-zero in case of a failure. static int checkForErrors(CXTranslationUnit TU); +static void describeLibclangFailure(enum CXErrorCode Err) { + switch (Err) { + case CXError_Success: + fprintf(stderr, "Success\n"); + return; + + case CXError_Failure: + fprintf(stderr, "Failure (no details available)\n"); + return; + + case CXError_Crashed: + fprintf(stderr, "Failure: libclang crashed\n"); + return; + + case CXError_InvalidArguments: + fprintf(stderr, "Failure: invalid arguments passed to a libclang routine\n"); + return; + + case CXError_ASTReadError: + fprintf(stderr, "Failure: AST deserialization error occurred\n"); + return; + } +} + static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column, unsigned end_line, unsigned end_column) { fprintf(out, "[%d:%d - %d:%d]", begin_line, begin_column, @@ -89,10 +114,11 @@ static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column, static unsigned CreateTranslationUnit(CXIndex Idx, const char *file, CXTranslationUnit *TU) { - - *TU = clang_createTranslationUnit(Idx, file); - if (!*TU) { + enum CXErrorCode Err = clang_createTranslationUnit2(Idx, file, TU); + if (Err != CXError_Success) { fprintf(stderr, "Unable to load translation unit from '%s'!\n", file); + describeLibclangFailure(Err); + *TU = 0; return 0; } return 1; @@ -1420,8 +1446,9 @@ int perform_test_load_source(int argc, const char **argv, const char *CommentSchemaFile; struct CXUnsavedFile *unsaved_files = 0; int num_unsaved_files = 0; + enum CXErrorCode Err; int result; - + Idx = clang_createIndex(/* excludeDeclsFromPCH */ (!strcmp(filter, "local") || !strcmp(filter, "local-display"))? 1 : 0, @@ -1437,13 +1464,14 @@ int perform_test_load_source(int argc, const char **argv, return -1; } - TU = clang_parseTranslationUnit(Idx, 0, - argv + num_unsaved_files, - argc - num_unsaved_files, - unsaved_files, num_unsaved_files, - getDefaultParsingOptions()); - if (!TU) { + Err = clang_parseTranslationUnit2(Idx, 0, + argv + num_unsaved_files, + argc - num_unsaved_files, + unsaved_files, num_unsaved_files, + getDefaultParsingOptions(), &TU); + if (Err != CXError_Success) { fprintf(stderr, "Unable to load translation unit!\n"); + describeLibclangFailure(Err); free_remapped_files(unsaved_files, num_unsaved_files); clang_disposeIndex(Idx); return 1; @@ -1464,6 +1492,7 @@ int perform_test_reparse_source(int argc, const char **argv, int trials, struct CXUnsavedFile *unsaved_files = 0; int num_unsaved_files = 0; int compiler_arg_idx = 0; + enum CXErrorCode Err; int result, i; int trial; int remap_after_trial = 0; @@ -1489,12 +1518,13 @@ int perform_test_reparse_source(int argc, const char **argv, int trials, /* Load the initial translation unit -- we do this without honoring remapped * files, so that we have a way to test results after changing the source. */ - TU = clang_parseTranslationUnit(Idx, 0, - argv + compiler_arg_idx, - argc - compiler_arg_idx, - 0, 0, getDefaultParsingOptions()); - if (!TU) { + Err = clang_parseTranslationUnit2(Idx, 0, + argv + compiler_arg_idx, + argc - compiler_arg_idx, + 0, 0, getDefaultParsingOptions(), &TU); + if (Err != CXError_Success) { fprintf(stderr, "Unable to load translation unit!\n"); + describeLibclangFailure(Err); free_remapped_files(unsaved_files, num_unsaved_files); clang_disposeIndex(Idx); return 1; @@ -1517,11 +1547,14 @@ int perform_test_reparse_source(int argc, const char **argv, int trials, return -1; } - if (clang_reparseTranslationUnit(TU, - trial >= remap_after_trial ? num_unsaved_files : 0, - trial >= remap_after_trial ? unsaved_files : 0, - clang_defaultReparseOptions(TU))) { + Err = clang_reparseTranslationUnit( + TU, + trial >= remap_after_trial ? num_unsaved_files : 0, + trial >= remap_after_trial ? unsaved_files : 0, + clang_defaultReparseOptions(TU)); + if (Err != CXError_Success) { fprintf(stderr, "Unable to reparse translation unit!\n"); + describeLibclangFailure(Err); clang_disposeTranslationUnit(TU); free_remapped_files(unsaved_files, num_unsaved_files); clang_disposeIndex(Idx); @@ -1943,7 +1976,8 @@ int perform_code_completion(int argc, const char **argv, int timing_only) { struct CXUnsavedFile *unsaved_files = 0; int num_unsaved_files = 0; CXCodeCompleteResults *results = 0; - CXTranslationUnit TU = 0; + enum CXErrorCode Err; + CXTranslationUnit TU; unsigned I, Repeats = 1; unsigned completionOptions = clang_defaultCodeCompleteOptions(); @@ -1968,21 +2002,27 @@ int perform_code_completion(int argc, const char **argv, int timing_only) { if (getenv("CINDEXTEST_EDITING")) Repeats = 5; - - TU = clang_parseTranslationUnit(CIdx, 0, - argv + num_unsaved_files + 2, - argc - num_unsaved_files - 2, - 0, 0, getDefaultParsingOptions()); - if (!TU) { + + Err = clang_parseTranslationUnit2(CIdx, 0, + argv + num_unsaved_files + 2, + argc - num_unsaved_files - 2, + 0, 0, getDefaultParsingOptions(), &TU); + if (Err != CXError_Success) { fprintf(stderr, "Unable to load translation unit!\n"); + describeLibclangFailure(Err); return 1; } - if (clang_reparseTranslationUnit(TU, 0, 0, clang_defaultReparseOptions(TU))) { + Err = clang_reparseTranslationUnit(TU, 0, 0, + clang_defaultReparseOptions(TU)); + + if (Err != CXError_Success) { fprintf(stderr, "Unable to reparse translation init!\n"); + describeLibclangFailure(Err); + clang_disposeTranslationUnit(TU); return 1; } - + for (I = 0; I != Repeats; ++I) { results = clang_codeCompleteAt(TU, filename, line, column, unsaved_files, num_unsaved_files, @@ -2069,6 +2109,7 @@ static int inspect_cursor_at(int argc, const char **argv) { int errorCode; struct CXUnsavedFile *unsaved_files = 0; int num_unsaved_files = 0; + enum CXErrorCode Err; CXTranslationUnit TU; CXCursor Cursor; CursorSourceLocation *Locations = 0; @@ -2102,15 +2143,15 @@ static int inspect_cursor_at(int argc, const char **argv) { /* Parse the translation unit. When we're testing clang_getCursor() after reparsing, don't remap unsaved files until the second parse. */ CIdx = clang_createIndex(1, 1); - TU = clang_parseTranslationUnit(CIdx, argv[argc - 1], - argv + num_unsaved_files + 1 + NumLocations, - argc - num_unsaved_files - 2 - NumLocations, - unsaved_files, - Repeats > 1? 0 : num_unsaved_files, - getDefaultParsingOptions()); - - if (!TU) { + Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1], + argv + num_unsaved_files + 1 + NumLocations, + argc - num_unsaved_files - 2 - NumLocations, + unsaved_files, + Repeats > 1? 0 : num_unsaved_files, + getDefaultParsingOptions(), &TU); + if (Err != CXError_Success) { fprintf(stderr, "unable to parse input\n"); + describeLibclangFailure(Err); return -1; } @@ -2118,11 +2159,14 @@ static int inspect_cursor_at(int argc, const char **argv) { return -1; for (I = 0; I != Repeats; ++I) { - if (Repeats > 1 && - clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, - clang_defaultReparseOptions(TU))) { - clang_disposeTranslationUnit(TU); - return 1; + if (Repeats > 1) { + Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, + clang_defaultReparseOptions(TU)); + if (Err != CXError_Success) { + describeLibclangFailure(Err); + clang_disposeTranslationUnit(TU); + return 1; + } } if (checkForErrors(TU) != 0) @@ -2235,6 +2279,7 @@ static int find_file_refs_at(int argc, const char **argv) { int errorCode; struct CXUnsavedFile *unsaved_files = 0; int num_unsaved_files = 0; + enum CXErrorCode Err; CXTranslationUnit TU; CXCursor Cursor; CursorSourceLocation *Locations = 0; @@ -2268,15 +2313,16 @@ static int find_file_refs_at(int argc, const char **argv) { /* Parse the translation unit. When we're testing clang_getCursor() after reparsing, don't remap unsaved files until the second parse. */ CIdx = clang_createIndex(1, 1); - TU = clang_parseTranslationUnit(CIdx, argv[argc - 1], - argv + num_unsaved_files + 1 + NumLocations, - argc - num_unsaved_files - 2 - NumLocations, - unsaved_files, - Repeats > 1? 0 : num_unsaved_files, - getDefaultParsingOptions()); - - if (!TU) { + Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1], + argv + num_unsaved_files + 1 + NumLocations, + argc - num_unsaved_files - 2 - NumLocations, + unsaved_files, + Repeats > 1? 0 : num_unsaved_files, + getDefaultParsingOptions(), &TU); + if (Err != CXError_Success) { fprintf(stderr, "unable to parse input\n"); + describeLibclangFailure(Err); + clang_disposeTranslationUnit(TU); return -1; } @@ -2284,11 +2330,14 @@ static int find_file_refs_at(int argc, const char **argv) { return -1; for (I = 0; I != Repeats; ++I) { - if (Repeats > 1 && - clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, - clang_defaultReparseOptions(TU))) { - clang_disposeTranslationUnit(TU); - return 1; + if (Repeats > 1) { + Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, + clang_defaultReparseOptions(TU)); + if (Err != CXError_Success) { + describeLibclangFailure(Err); + clang_disposeTranslationUnit(TU); + return 1; + } } if (checkForErrors(TU) != 0) @@ -2339,6 +2388,7 @@ static int find_file_includes_in(int argc, const char **argv) { CXIndex CIdx; struct CXUnsavedFile *unsaved_files = 0; int num_unsaved_files = 0; + enum CXErrorCode Err; CXTranslationUnit TU; const char **Filenames = 0; unsigned NumFilenames = 0; @@ -2368,15 +2418,17 @@ static int find_file_includes_in(int argc, const char **argv) { /* Parse the translation unit. When we're testing clang_getCursor() after reparsing, don't remap unsaved files until the second parse. */ CIdx = clang_createIndex(1, 1); - TU = clang_parseTranslationUnit(CIdx, argv[argc - 1], - argv + num_unsaved_files + 1 + NumFilenames, - argc - num_unsaved_files - 2 - NumFilenames, - unsaved_files, - Repeats > 1? 0 : num_unsaved_files, - getDefaultParsingOptions()); - - if (!TU) { + Err = clang_parseTranslationUnit2( + CIdx, argv[argc - 1], + argv + num_unsaved_files + 1 + NumFilenames, + argc - num_unsaved_files - 2 - NumFilenames, + unsaved_files, + Repeats > 1 ? 0 : num_unsaved_files, getDefaultParsingOptions(), &TU); + + if (Err != CXError_Success) { fprintf(stderr, "unable to parse input\n"); + describeLibclangFailure(Err); + clang_disposeTranslationUnit(TU); return -1; } @@ -2384,11 +2436,14 @@ static int find_file_includes_in(int argc, const char **argv) { return -1; for (I = 0; I != Repeats; ++I) { - if (Repeats > 1 && - clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, - clang_defaultReparseOptions(TU))) { - clang_disposeTranslationUnit(TU); - return 1; + if (Repeats > 1) { + Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, + clang_defaultReparseOptions(TU)); + if (Err != CXError_Success) { + describeLibclangFailure(Err); + clang_disposeTranslationUnit(TU); + return 1; + } } if (checkForErrors(TU) != 0) @@ -2933,6 +2988,9 @@ static int index_compile_args(int num_args, const char **args, &IndexCB,sizeof(IndexCB), index_opts, 0, args, num_args, 0, 0, 0, getDefaultParsingOptions()); + if (result != CXError_Success) + describeLibclangFailure(result); + if (index_data.fail_for_error) result = -1; @@ -3185,6 +3243,7 @@ int perform_token_annotation(int argc, const char **argv) { CXFile file = 0; CXCursor *cursors = 0; CXSourceRangeList *skipped_ranges = 0; + enum CXErrorCode Err; unsigned i; input += strlen("-test-annotate-tokens="); @@ -3198,14 +3257,15 @@ int perform_token_annotation(int argc, const char **argv) { } CIdx = clang_createIndex(0, 1); - TU = clang_parseTranslationUnit(CIdx, argv[argc - 1], - argv + num_unsaved_files + 2, - argc - num_unsaved_files - 3, - unsaved_files, - num_unsaved_files, - getDefaultParsingOptions()); - if (!TU) { + Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1], + argv + num_unsaved_files + 2, + argc - num_unsaved_files - 3, + unsaved_files, + num_unsaved_files, + getDefaultParsingOptions(), &TU); + if (Err != CXError_Success) { fprintf(stderr, "unable to parse input\n"); + describeLibclangFailure(Err); clang_disposeIndex(CIdx); free(filename); free_remapped_files(unsaved_files, num_unsaved_files); @@ -3220,9 +3280,11 @@ int perform_token_annotation(int argc, const char **argv) { if (getenv("CINDEXTEST_EDITING")) { for (i = 0; i < 5; ++i) { - if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, - clang_defaultReparseOptions(TU))) { + Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, + clang_defaultReparseOptions(TU)); + if (Err != CXError_Success) { fprintf(stderr, "Unable to reparse translation unit!\n"); + describeLibclangFailure(Err); errorCode = -1; goto teardown; } @@ -3586,6 +3648,7 @@ int write_pch_file(const char *filename, int argc, const char *argv[]) { CXTranslationUnit TU; struct CXUnsavedFile *unsaved_files = 0; int num_unsaved_files = 0; + enum CXErrorCode Err; int result = 0; Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnostics=*/1); @@ -3594,18 +3657,19 @@ int write_pch_file(const char *filename, int argc, const char *argv[]) { clang_disposeIndex(Idx); return -1; } - - TU = clang_parseTranslationUnit(Idx, 0, - argv + num_unsaved_files, - argc - num_unsaved_files, - unsaved_files, - num_unsaved_files, - CXTranslationUnit_Incomplete | - CXTranslationUnit_DetailedPreprocessingRecord| - CXTranslationUnit_ForSerialization); - if (!TU) { + + Err = clang_parseTranslationUnit2( + Idx, 0, argv + num_unsaved_files, argc - num_unsaved_files, + unsaved_files, num_unsaved_files, + CXTranslationUnit_Incomplete | + CXTranslationUnit_DetailedPreprocessingRecord | + CXTranslationUnit_ForSerialization, + &TU); + if (Err != CXError_Success) { fprintf(stderr, "Unable to load translation unit!\n"); + describeLibclangFailure(Err); free_remapped_files(unsaved_files, num_unsaved_files); + clang_disposeTranslationUnit(TU); clang_disposeIndex(Idx); return 1; } |