r201249 - libclang: report error code for bad PCH files

Daniel Jasper djasper at google.com
Thu Feb 13 06:31:22 PST 2014


On Wed, Feb 12, 2014 at 8:12 PM, Dmitri Gribenko <gribozavr at gmail.com>wrote:

> Author: gribozavr
> Date: Wed Feb 12 13:12:37 2014
> New Revision: 201249
>
> URL: http://llvm.org/viewvc/llvm-project?rev=201249&view=rev
> Log:
> 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.
>
> Added:
>     cfe/trunk/test/Index/pch-depending-on-deleted-module.c
> Modified:
>     cfe/trunk/include/clang-c/Index.h
>     cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
>     cfe/trunk/test/Modules/fatal-module-loader-error.m
>     cfe/trunk/tools/c-index-test/c-index-test.c
>     cfe/trunk/tools/libclang/CIndex.cpp
>     cfe/trunk/tools/libclang/CXTranslationUnit.h
>     cfe/trunk/tools/libclang/Indexing.cpp
>     cfe/trunk/tools/libclang/libclang.exports
>
> Modified: cfe/trunk/include/clang-c/Index.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=201249&r1=201248&r2=201249&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang-c/Index.h (original)
> +++ cfe/trunk/include/clang-c/Index.h Wed Feb 12 13:12:37 2014
> @@ -30,7 +30,7 @@
>   * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
>   */
>  #define CINDEX_VERSION_MAJOR 0
> -#define CINDEX_VERSION_MINOR 22
> +#define CINDEX_VERSION_MINOR 23
>
>  #define CINDEX_VERSION_ENCODE(major, minor) ( \
>        ((major) * 10000)                       \
> @@ -73,6 +73,43 @@ extern "C" {
>   */
>
>  /**
> + * \brief Error codes returned by libclang routines.
> + *
> + * Zero (\c CXError_Success) is the only error code indicating success.
>  Other
> + * error codes, including not yet assigned non-zero values, indicate
> errors.
> + */
> +enum CXErrorCode {
> +  /**
> +   * \brief No error.
> +   */
> +  CXError_Success = 0,
> +
> +  /**
> +   * \brief A generic error code, no further details are available.
> +   *
> +   * Errors of this kind can get their own specific error codes in future
> +   * libclang versions.
> +   */
> +  CXError_Failure = 1,
> +
> +  /**
> +   * \brief libclang crashed while performing the requested operation.
> +   */
> +  CXError_Crashed = 2,
> +
> +  /**
> +   * \brief The function detected that the arguments violate the function
> +   * contract.
> +   */
> +  CXError_InvalidArguments = 3,
> +
> +  /**
> +   * \brief An AST deserialization error has occurred.
> +   */
> +  CXError_ASTReadError = 4
> +};
> +
> +/**
>   * \brief An "index" that consists of a set of translation units that
> would
>   * typically be linked together into an executable or library.
>   */
> @@ -1076,10 +1113,27 @@ CINDEX_LINKAGE CXTranslationUnit clang_c
>                                           struct CXUnsavedFile
> *unsaved_files);
>
>  /**
> - * \brief Create a translation unit from an AST file (-emit-ast).
> + * \brief Same as \c clang_createTranslationUnit2, but returns
> + * the \c CXTranslationUnit instead of an error code.  In case of an
> error this
> + * routine returns a \c NULL \c CXTranslationUnit, without further
> detailed
> + * error codes.
> + */
> +CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(
> +    CXIndex CIdx,
> +    const char *ast_filename);
> +
> +/**
> + * \brief Create a translation unit from an AST file (\c -emit-ast).
> + *
> + * \param[out] out_TU A non-NULL pointer to store the created
> + * \c CXTranslationUnit.
> + *
> + * \returns Zero on success, otherwise returns an error code.
>   */
> -CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(CXIndex,
> -                                             const char *ast_filename);
> +CINDEX_LINKAGE enum CXErrorCode clang_createTranslationUnit2(
> +    CXIndex CIdx,
> +    const char *ast_filename,
> +    CXTranslationUnit *out_TU);
>
>  /**
>   * \brief Flags that control the creation of translation units.
> @@ -1193,7 +1247,22 @@ enum CXTranslationUnit_Flags {
>   * set of optimizations enabled may change from one version to the next.
>   */
>  CINDEX_LINKAGE unsigned clang_defaultEditingTranslationUnitOptions(void);
> -
> +
> +/**
> + * \brief Same as \c clang_parseTranslationUnit2, but returns
> + * the \c CXTranslationUnit instead of an error code.  In case of an
> error this
> + * routine returns a \c NULL \c CXTranslationUnit, without further
> detailed
> + * error codes.
> + */
> +CINDEX_LINKAGE CXTranslationUnit
> +clang_parseTranslationUnit(CXIndex CIdx,
> +                           const char *source_filename,
> +                           const char *const *command_line_args,
> +                           int num_command_line_args,
> +                           struct CXUnsavedFile *unsaved_files,
> +                           unsigned num_unsaved_files,
> +                           unsigned options);
> +
>  /**
>   * \brief Parse the given source file and the translation unit
> corresponding
>   * to that file.
> @@ -1208,7 +1277,7 @@ CINDEX_LINKAGE unsigned clang_defaultEdi
>   * associated.
>   *
>   * \param source_filename The name of the source file to load, or NULL if
> the
> - * source file is included in \p command_line_args.
> + * source file is included in \c command_line_args.
>   *
>   * \param command_line_args The command-line arguments that would be
>   * passed to the \c clang executable if it were being invoked
> out-of-process.
> @@ -1217,7 +1286,7 @@ CINDEX_LINKAGE unsigned clang_defaultEdi
>   * '-emit-ast', '-fsyntax-only' (which is the default), and '-o \<output
> file>'.
>   *
>   * \param num_command_line_args The number of command-line arguments in
> - * \p command_line_args.
> + * \c command_line_args.
>   *
>   * \param unsaved_files the files that have not yet been saved to disk
>   * but may be required for parsing, including the contents of
> @@ -1232,18 +1301,22 @@ CINDEX_LINKAGE unsigned clang_defaultEdi
>   * is managed but not its compilation. This should be a bitwise OR of the
>   * CXTranslationUnit_XXX flags.
>   *
> - * \returns A new translation unit describing the parsed code and
> containing
> - * any diagnostics produced by the compiler. If there is a failure from
> which
> - * the compiler cannot recover, returns NULL.
> - */
> -CINDEX_LINKAGE CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
> -                                                    const char
> *source_filename,
> -                                         const char * const
> *command_line_args,
> -                                                      int
> num_command_line_args,
> -                                            struct CXUnsavedFile
> *unsaved_files,
> -                                                     unsigned
> num_unsaved_files,
> -                                                            unsigned
> options);
> -
> + * \param[out] out_TU A non-NULL pointer to store the created
> + * \c CXTranslationUnit, describing the parsed code and containing any
> + * diagnostics produced by the compiler.
> + *
> + * \returns Zero on success, otherwise returns an error code.
> + */
> +CINDEX_LINKAGE enum CXErrorCode
> +clang_parseTranslationUnit2(CXIndex CIdx,
> +                            const char *source_filename,
> +                            const char *const *command_line_args,
> +                            int num_command_line_args,
> +                            struct CXUnsavedFile *unsaved_files,
> +                            unsigned num_unsaved_files,
> +                            unsigned options,
> +                            CXTranslationUnit *out_TU);
> +
>  /**
>   * \brief Flags that control how translation units are saved.
>   *
> @@ -1395,10 +1468,11 @@ CINDEX_LINKAGE unsigned clang_defaultRep
>   * The function \c clang_defaultReparseOptions() produces a default set of
>   * options recommended for most uses, based on the translation unit.
>   *
> - * \returns 0 if the sources could be reparsed. A non-zero value will be
> + * \returns 0 if the sources could be reparsed.  A non-zero error code
> will be
>   * returned if reparsing was impossible, such that the translation unit is
> - * invalid. In such cases, the only valid call for \p TU is
> - * \c clang_disposeTranslationUnit(TU).
> + * invalid. In such cases, the only valid call for \c TU is
> + * \c clang_disposeTranslationUnit(TU).  The error codes returned by this
> + * routine are described by the \c CXErrorCode enum.
>   */
>  CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU,
>                                                  unsigned
> num_unsaved_files,
> @@ -5789,11 +5863,12 @@ typedef enum {
>   * \param index_options A bitmask of options that affects how indexing is
>   * performed. This should be a bitwise OR of the CXIndexOpt_XXX flags.
>   *
> - * \param out_TU [out] pointer to store a CXTranslationUnit that can be
> reused
> - * after indexing is finished. Set to NULL if you do not require it.
> + * \param[out] out_TU pointer to store a \c CXTranslationUnit that can be
> + * reused after indexing is finished. Set to \c NULL if you do not
> require it.
>   *
> - * \returns If there is a failure from which the there is no recovery,
> returns
> - * non-zero, otherwise returns 0.
> + * \returns 0 on success or if there were errors from which the compiler
> could
> + * recover.  If there is a failure from which the there is no recovery,
> returns
> + * a non-zero \c CXErrorCode.
>   *
>   * The rest of the parameters are the same as #clang_parseTranslationUnit.
>   */
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=201249&r1=201248&r2=201249&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
> (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Wed Feb
> 12 13:12:37 2014
> @@ -8,6 +8,7 @@
>
>  //===----------------------------------------------------------------------===//
>
>  let Component = "Serialization" in {
> +let CategoryName = "AST Deserialization Issue" in {
>
>  def err_fe_unable_to_read_pch_file : Error<
>      "unable to read PCH file %0: '%1'">;
> @@ -78,4 +79,6 @@ def note_module_odr_violation_no_possibl
>  def note_module_odr_violation_possible_decl : Note<
>    "declaration of %0 does not match">;
>
> -}
> +} // let CategoryName
> +} // let Component
> +
>
> Added: cfe/trunk/test/Index/pch-depending-on-deleted-module.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/pch-depending-on-deleted-module.c?rev=201249&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/Index/pch-depending-on-deleted-module.c (added)
> +++ cfe/trunk/test/Index/pch-depending-on-deleted-module.c Wed Feb 12
> 13:12:37 2014
> @@ -0,0 +1,14 @@
> +#include "a.h"
> +
> +// RUN: rm -rf %t
> +// RUN: mkdir %t
> +
> +// RUN: %clang_cc1 -x c-header -fmodules -fdisable-module-hash
> -fmodules-cache-path=%t/modules-cache -emit-pch -I %S/Inputs/Headers -o
> %t/use_LibA.pch %s
> +// RUN: %clang_cc1 -fmodules -fdisable-module-hash
> -fmodules-cache-path=%t/modules-cache -verify-pch %t/use_LibA.pch
> +// RUN: rm -f %t/modules-cache/LibA.pcm
> +// RUN: not %clang_cc1 -fmodules -fdisable-module-hash
> -fmodules-cache-path=modules-cache -verify-pch %t/use_LibA.pch 2>&1 |
> FileCheck -check-prefix=VERIFY %s
> +// RUN: not c-index-test -test-load-source all -x c -fmodules
> -fdisable-module-hash -fmodules-cache-path=modules-cache -include-pch
> %t/use_LibA.pch %s 2>&1 | FileCheck -check-prefix=INDEX %s
> +
> +// VERIFY: fatal error: malformed or corrupted AST file: 'Unable to load
> module
> +// INDEX: {{^}}Failure: AST deserialization error occurred{{$}}
> +
>
> Modified: cfe/trunk/test/Modules/fatal-module-loader-error.m
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/fatal-module-loader-error.m?rev=201249&r1=201248&r2=201249&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/Modules/fatal-module-loader-error.m (original)
> +++ cfe/trunk/test/Modules/fatal-module-loader-error.m Wed Feb 12 13:12:37
> 2014
> @@ -23,4 +23,4 @@
>  // Also check that libclang does not create a PCH with such an error.
>  // RUN: not c-index-test -write-pch %t.pch -fmodules
> -fmodules-cache-path=%t \
>  // RUN: %s -Xclang -fdisable-module-hash -F %S/Inputs 2>&1 | FileCheck %s
> -// CHECK: Unable to write PCH file
> +// CHECK: {{^}}Failure: AST deserialization error occurred{{$}}
>
> Modified: cfe/trunk/tools/c-index-test/c-index-test.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=201249&r1=201248&r2=201249&view=diff
>
> ==============================================================================
> --- cfe/trunk/tools/c-index-test/c-index-test.c (original)
> +++ cfe/trunk/tools/c-index-test/c-index-test.c Wed Feb 12 13:12:37 2014
> @@ -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, unsig
>
>  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, c
>    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, c
>      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
>    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
>
>    /* 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
>        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, co
>    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, co
>
>    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, c
>    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, c
>    /* 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, c
>      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, c
>    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, c
>    /* 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, c
>      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 arg
>    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 arg
>    /* 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());
> +  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 (!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 arg
>      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_ar
>                                   &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, c
>    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, c
>    }
>
>    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, c
>
>    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,
>    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,
>      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;
>    }
>
> Modified: cfe/trunk/tools/libclang/CIndex.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=201249&r1=201248&r2=201249&view=diff
>
> ==============================================================================
> --- cfe/trunk/tools/libclang/CIndex.cpp (original)
> +++ cfe/trunk/tools/libclang/CIndex.cpp Wed Feb 12 13:12:37 2014
> @@ -25,6 +25,8 @@
>  #include "clang/AST/Attr.h"
>  #include "clang/AST/StmtVisitor.h"
>  #include "clang/Basic/Diagnostic.h"
> +#include "clang/Basic/DiagnosticCategories.h"
> +#include "clang/Basic/DiagnosticIDs.h"
>  #include "clang/Basic/Version.h"
>  #include "clang/Frontend/ASTUnit.h"
>  #include "clang/Frontend/CompilerInstance.h"
> @@ -34,6 +36,7 @@
>  #include "clang/Lex/Lexer.h"
>  #include "clang/Lex/PreprocessingRecord.h"
>  #include "clang/Lex/Preprocessor.h"
> +#include "clang/Serialization/SerializationDiagnostic.h"
>  #include "llvm/ADT/Optional.h"
>  #include "llvm/ADT/STLExtras.h"
>  #include "llvm/ADT/StringSwitch.h"
> @@ -62,6 +65,7 @@ using namespace clang::cxindex;
>  CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit
> *AU) {
>    if (!AU)
>      return 0;
> +  assert(CIdx);
>    CXTranslationUnit D = new CXTranslationUnitImpl();
>    D->CIdx = CIdx;
>    D->TheASTUnit = AU;
> @@ -72,6 +76,18 @@ CXTranslationUnit cxtu::MakeCXTranslatio
>    return D;
>  }
>
> +bool cxtu::isASTReadError(ASTUnit *AU) {
> +  for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
> +                                     DEnd = AU->stored_diag_end();
> +       D != DEnd; ++D) {
> +    if (D->getLevel() >= DiagnosticsEngine::Error &&
> +        DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
> +            diag::DiagCat_AST_Deserialization_Issue)
> +      return true;
> +  }
> +  return false;
> +}
> +
>  cxtu::CXTUOwner::~CXTUOwner() {
>    if (TU)
>      clang_disposeTranslationUnit(TU);
> @@ -2589,11 +2605,22 @@ void clang_toggleCrashRecovery(unsigned
>    else
>      llvm::CrashRecoveryContext::Disable();
>  }
> -
> +
>  CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
>                                                const char *ast_filename) {
> -  if (!CIdx || !ast_filename)
> -    return 0;
> +  CXTranslationUnit TU;
> +  enum CXErrorCode Result =
> +      clang_createTranslationUnit2(CIdx, ast_filename, &TU);
> +  assert((TU && Result == CXError_Success) ||
> +         (!TU && Result != CXError_Success));
>

This triggers on one of our internal tests. I have submitted r201329, which
kind of papers over the underlying cause. Can you take a look? If the fix
is not obvious, I am happy to look into this further.

Cheers,
Daniel


> +  return TU;
> +}
> +
> +enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
> +                                              const char *ast_filename,
> +                                              CXTranslationUnit *out_TU) {
> +  if (!CIdx || !ast_filename || !out_TU)
> +    return CXError_InvalidArguments;
>
>    LOG_FUNC_SECTION {
>      *Log << ast_filename;
> @@ -2603,19 +2630,20 @@ CXTranslationUnit clang_createTranslatio
>    FileSystemOptions FileSystemOpts;
>
>    IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
> -  ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags,
> FileSystemOpts,
> +  ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags,
> FileSystemOpts,
>                                           CXXIdx->getOnlyLocalDecls(),
> None,
>                                           /*CaptureDiagnostics=*/true,
>
> /*AllowPCHWithCompilerErrors=*/true,
>                                           /*UserFilesAreVolatile=*/true);
> -  return MakeCXTranslationUnit(CXXIdx, TU);
> +  *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
> +  return *out_TU ? CXError_Success : CXError_Failure;
>  }
>
>  unsigned clang_defaultEditingTranslationUnitOptions() {
>    return CXTranslationUnit_PrecompiledPreamble |
>           CXTranslationUnit_CacheCompletionResults;
>  }
> -
> +
>  CXTranslationUnit
>  clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
>                                            const char *source_filename,
> @@ -2638,7 +2666,8 @@ struct ParseTranslationUnitInfo {
>    struct CXUnsavedFile *unsaved_files;
>    unsigned num_unsaved_files;
>    unsigned options;
> -  CXTranslationUnit result;
> +  CXTranslationUnit *out_TU;
> +  CXErrorCode result;
>  };
>  static void clang_parseTranslationUnit_Impl(void *UserData) {
>    ParseTranslationUnitInfo *PTUI =
> @@ -2650,10 +2679,18 @@ static void clang_parseTranslationUnit_I
>    struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
>    unsigned num_unsaved_files = PTUI->num_unsaved_files;
>    unsigned options = PTUI->options;
> -  PTUI->result = 0;
> +  CXTranslationUnit *out_TU = PTUI->out_TU;
>
> -  if (!CIdx)
> +  // Check arguments.
> +  if (!CIdx || !out_TU ||
> +      (unsaved_files == NULL && num_unsaved_files != 0)) {
> +    PTUI->result = CXError_InvalidArguments;
>      return;
> +  }
> +
> +  // Set up the initial return values.
> +  *out_TU = NULL;
> +  PTUI->result = CXError_Failure;
>
>    CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
>
> @@ -2763,15 +2800,40 @@ static void clang_parseTranslationUnit_I
>        printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
>    }
>
> -  PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
> +  if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
> +    PTUI->result = CXError_ASTReadError;
> +  } else {
> +    *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.take());
> +    PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
> +  }
>  }
> -CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
> -                                             const char *source_filename,
> -                                         const char * const
> *command_line_args,
> -                                             int num_command_line_args,
> -                                            struct CXUnsavedFile
> *unsaved_files,
> -                                             unsigned num_unsaved_files,
> -                                             unsigned options) {
> +
> +CXTranslationUnit
> +clang_parseTranslationUnit(CXIndex CIdx,
> +                           const char *source_filename,
> +                           const char *const *command_line_args,
> +                           int num_command_line_args,
> +                           struct CXUnsavedFile *unsaved_files,
> +                           unsigned num_unsaved_files,
> +                           unsigned options) {
> +  CXTranslationUnit TU;
> +  enum CXErrorCode Result = clang_parseTranslationUnit2(
> +      CIdx, source_filename, command_line_args, num_command_line_args,
> +      unsaved_files, num_unsaved_files, options, &TU);
> +  assert((TU && Result == CXError_Success) ||
> +         (!TU && Result != CXError_Success));
> +  return TU;
> +}
> +
> +enum CXErrorCode clang_parseTranslationUnit2(
> +    CXIndex CIdx,
> +    const char *source_filename,
> +    const char *const *command_line_args,
> +    int num_command_line_args,
> +    struct CXUnsavedFile *unsaved_files,
> +    unsigned num_unsaved_files,
> +    unsigned options,
> +    CXTranslationUnit *out_TU) {
>    LOG_FUNC_SECTION {
>      *Log << source_filename << ": ";
>      for (int i = 0; i != num_command_line_args; ++i)
> @@ -2780,7 +2842,8 @@ CXTranslationUnit clang_parseTranslation
>
>    ParseTranslationUnitInfo PTUI = { CIdx, source_filename,
> command_line_args,
>                                      num_command_line_args, unsaved_files,
> -                                    num_unsaved_files, options, 0 };
> +                                    num_unsaved_files, options, out_TU,
> +                                    CXError_Failure };
>    llvm::CrashRecoveryContext CRC;
>
>    if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
> @@ -2803,10 +2866,11 @@ CXTranslationUnit clang_parseTranslation
>      fprintf(stderr, "],\n");
>      fprintf(stderr, "  'options' : %d,\n", options);
>      fprintf(stderr, "}\n");
> -
> -    return 0;
> +
> +    return CXError_Crashed;
>    } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
> -    PrintLibclangResourceUsage(PTUI.result);
> +    if (CXTranslationUnit *TU = PTUI.out_TU)
> +      PrintLibclangResourceUsage(*TU);
>    }
>
>    return PTUI.result;
> @@ -2891,7 +2955,8 @@ void clang_disposeTranslationUnit(CXTran
>    if (CTUnit) {
>      // If the translation unit has been marked as unsafe to free, just
> discard
>      // it.
> -    if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
> +    ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
> +    if (Unit && Unit->isUnsafeToFree())
>        return;
>
>      delete cxtu::getASTUnit(CTUnit);
> @@ -2918,11 +2983,22 @@ struct ReparseTranslationUnitInfo {
>  static void clang_reparseTranslationUnit_Impl(void *UserData) {
>    ReparseTranslationUnitInfo *RTUI =
>      static_cast<ReparseTranslationUnitInfo*>(UserData);
> -  RTUI->result = 1; // Error.
> +  RTUI->result = CXError_Failure;
>
>    CXTranslationUnit TU = RTUI->TU;
> +  unsigned num_unsaved_files = RTUI->num_unsaved_files;
> +  struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
> +  unsigned options = RTUI->options;
> +  (void) options;
> +
> +  // Check arguments.
>    if (isNotUsableTU(TU)) {
>      LOG_BAD_TU(TU);
> +    RTUI->result = CXError_InvalidArguments;
> +    return;
> +  }
> +  if (unsaved_files == NULL && num_unsaved_files != 0) {
> +    RTUI->result = CXError_InvalidArguments;
>      return;
>    }
>
> @@ -2930,11 +3006,6 @@ static void clang_reparseTranslationUnit
>    delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
>    TU->Diagnostics = 0;
>
> -  unsigned num_unsaved_files = RTUI->num_unsaved_files;
> -  struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
> -  unsigned options = RTUI->options;
> -  (void) options;
> -
>    CIndexer *CXXIdx = TU->CIdx;
>    if
> (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
>      setThreadBackgroundPriority();
> @@ -2956,9 +3027,11 @@ static void clang_reparseTranslationUnit
>      RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
>                                              Buffer));
>    }
> -
> +
>    if (!CXXUnit->Reparse(*RemappedFiles.get()))
> -    RTUI->result = 0;
> +    RTUI->result = CXError_Success;
> +  else if (isASTReadError(CXXUnit))
> +    RTUI->result = CXError_ASTReadError;
>  }
>
>  int clang_reparseTranslationUnit(CXTranslationUnit TU,
> @@ -2970,7 +3043,7 @@ int clang_reparseTranslationUnit(CXTrans
>    }
>
>    ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files,
> unsaved_files,
> -                                      options, 0 };
> +                                      options, CXError_Failure };
>
>    if (getenv("LIBCLANG_NOTHREADS")) {
>      clang_reparseTranslationUnit_Impl(&RTUI);
> @@ -2982,7 +3055,7 @@ int clang_reparseTranslationUnit(CXTrans
>    if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
>      fprintf(stderr, "libclang: crash detected during reparsing\n");
>      cxtu::getASTUnit(TU)->setUnsafeToFree(true);
> -    return 1;
> +    return CXError_Crashed;
>    } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
>      PrintLibclangResourceUsage(TU);
>
> @@ -6747,9 +6820,9 @@ Logger &cxindex::Logger::operator<<(CXTr
>          LogOS << " (" << Unit->getASTFileName() << ')';
>        return *this;
>      }
> +  } else {
> +    LogOS << "<NULL TU>";
>    }
> -
> -  LogOS << "<NULL TU>";
>    return *this;
>  }
>
>
> Modified: cfe/trunk/tools/libclang/CXTranslationUnit.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXTranslationUnit.h?rev=201249&r1=201248&r2=201249&view=diff
>
> ==============================================================================
> --- cfe/trunk/tools/libclang/CXTranslationUnit.h (original)
> +++ cfe/trunk/tools/libclang/CXTranslationUnit.h Wed Feb 12 13:12:37 2014
> @@ -46,6 +46,10 @@ static inline ASTUnit *getASTUnit(CXTran
>    return TU->TheASTUnit;
>  }
>
> +/// \returns true if the ASTUnit has a diagnostic about the AST file being
> +/// corrupted.
> +bool isASTReadError(ASTUnit *AU);
> +
>  static inline bool isNotUsableTU(CXTranslationUnit TU) {
>    return !TU;
>  }
>
> Modified: cfe/trunk/tools/libclang/Indexing.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Indexing.cpp?rev=201249&r1=201248&r2=201249&view=diff
>
> ==============================================================================
> --- cfe/trunk/tools/libclang/Indexing.cpp (original)
> +++ cfe/trunk/tools/libclang/Indexing.cpp Wed Feb 12 13:12:37 2014
> @@ -514,16 +514,22 @@ static void clang_indexSourceFile_Impl(v
>    unsigned num_unsaved_files = ITUI->num_unsaved_files;
>    CXTranslationUnit *out_TU  = ITUI->out_TU;
>    unsigned TU_options = ITUI->TU_options;
> -  ITUI->result = 1; // init as error.
> -
> +
> +  // Set up the initial return value.
> +  ITUI->result = CXError_Failure;
> +
>    if (out_TU)
>      *out_TU = 0;
> -  bool requestedToGetTU = (out_TU != 0);
> +  bool requestedToGetTU = (out_TU != 0);
>
> -  if (!cxIdxAction)
> +  if (!cxIdxAction) {
> +    ITUI->result = CXError_InvalidArguments;
>      return;
> -  if (!client_index_callbacks || index_callbacks_size == 0)
> +  }
> +  if (!client_index_callbacks || index_callbacks_size == 0) {
> +    ITUI->result = CXError_InvalidArguments;
>      return;
> +  }
>
>    IndexerCallbacks CB;
>    memset(&CB, 0, sizeof(CB));
> @@ -671,13 +677,18 @@ static void clang_indexSourceFile_Impl(v
>    if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())
>      printDiagsToStderr(Unit);
>
> +  if (isASTReadError(Unit)) {
> +    ITUI->result = CXError_ASTReadError;
> +    return;
> +  }
> +
>    if (!Success)
>      return;
>
>    if (out_TU)
>      *out_TU = CXTU->takeTU();
>
> -  ITUI->result = 0; // success.
> +  ITUI->result = CXError_Success;
>  }
>
>
>  //===----------------------------------------------------------------------===//
> @@ -754,14 +765,20 @@ static void clang_indexTranslationUnit_I
>    IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
>    unsigned index_callbacks_size = ITUI->index_callbacks_size;
>    unsigned index_options = ITUI->index_options;
> -  ITUI->result = 1; // init as error.
>
> +  // Set up the initial return value.
> +  ITUI->result = CXError_Failure;
> +
> +  // Check arguments.
>    if (isNotUsableTU(TU)) {
>      LOG_BAD_TU(TU);
> +    ITUI->result = CXError_InvalidArguments;
>      return;
>    }
> -  if (!client_index_callbacks || index_callbacks_size == 0)
> +  if (!client_index_callbacks || index_callbacks_size == 0) {
> +    ITUI->result = CXError_InvalidArguments;
>      return;
> +  }
>
>    CIndexer *CXXIdx = TU->CIdx;
>    if
> (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
> @@ -809,7 +826,7 @@ static void clang_indexTranslationUnit_I
>    indexTranslationUnit(*Unit, *IndexCtx);
>    indexDiagnostics(TU, *IndexCtx);
>
> -  ITUI->result = 0;
> +  ITUI->result = CXError_Success;
>  }
>
>
>  //===----------------------------------------------------------------------===//
> @@ -981,7 +998,8 @@ int clang_indexSourceFile(CXIndexAction
>                                 index_callbacks_size, index_options,
>                                 source_filename, command_line_args,
>                                 num_command_line_args, unsaved_files,
> -                               num_unsaved_files, out_TU, TU_options, 0 };
> +                               num_unsaved_files, out_TU, TU_options,
> +                               CXError_Failure };
>
>    if (getenv("LIBCLANG_NOTHREADS")) {
>      clang_indexSourceFile_Impl(&ITUI);
>
> Modified: cfe/trunk/tools/libclang/libclang.exports
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=201249&r1=201248&r2=201249&view=diff
>
> ==============================================================================
> --- cfe/trunk/tools/libclang/libclang.exports (original)
> +++ cfe/trunk/tools/libclang/libclang.exports Wed Feb 12 13:12:37 2014
> @@ -87,6 +87,7 @@ clang_constructUSR_ObjCProtocol
>  clang_createCXCursorSet
>  clang_createIndex
>  clang_createTranslationUnit
> +clang_createTranslationUnit2
>  clang_createTranslationUnitFromSourceFile
>  clang_defaultCodeCompleteOptions
>  clang_defaultDiagnosticDisplayOptions
> @@ -262,6 +263,7 @@ clang_loadDiagnostics
>  clang_Location_isInSystemHeader
>  clang_Location_isFromMainFile
>  clang_parseTranslationUnit
> +clang_parseTranslationUnit2
>  clang_remap_dispose
>  clang_remap_getFilenames
>  clang_remap_getNumFiles
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140213/16b05458/attachment.html>


More information about the cfe-commits mailing list