<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Feb 12, 2014 at 8:12 PM, Dmitri Gribenko <span dir="ltr"><<a href="mailto:gribozavr@gmail.com" target="_blank" class="cremed">gribozavr@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: gribozavr<br>
Date: Wed Feb 12 13:12:37 2014<br>
New Revision: 201249<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=201249&view=rev" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project?rev=201249&view=rev</a><br>
Log:<br>
libclang: report error code for bad PCH files<br>
<br>
This commit improves libclang to report the error condition when<br>
CXTranslationUnit can not be created because of a stale PCH file. This allows<br>
the caller, for example, to rebuild the PCH file and retry the request.<br>
<br>
There two are APIs in libclang that return a CXTranslationUnit and don't<br>
support reporting detailed errors (the only error condition is a NULL result).<br>
For these APIs, a second, superior, version is introduced --<br>
clang_createTranslationUnit2 and clang_parseTranslationUnit2. These functions<br>
return a CXTranslationUnit indirectly and also return an error code. Old<br>
functions are still supported and are nothing more than convenience wrappers<br>
that ignore extended error codes.<br>
<br>
As a cleanup, this commit also categorizes some libclang errors in the<br>
functions I had to modify anyway.<br>
<br>
Added:<br>
cfe/trunk/test/Index/pch-depending-on-deleted-module.c<br>
Modified:<br>
cfe/trunk/include/clang-c/Index.h<br>
cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td<br>
cfe/trunk/test/Modules/fatal-module-loader-error.m<br>
cfe/trunk/tools/c-index-test/c-index-test.c<br>
cfe/trunk/tools/libclang/CIndex.cpp<br>
cfe/trunk/tools/libclang/CXTranslationUnit.h<br>
cfe/trunk/tools/libclang/Indexing.cpp<br>
cfe/trunk/tools/libclang/libclang.exports<br>
<br>
Modified: cfe/trunk/include/clang-c/Index.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=201249&r1=201248&r2=201249&view=diff" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=201249&r1=201248&r2=201249&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang-c/Index.h (original)<br>
+++ cfe/trunk/include/clang-c/Index.h Wed Feb 12 13:12:37 2014<br>
@@ -30,7 +30,7 @@<br>
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.<br>
*/<br>
#define CINDEX_VERSION_MAJOR 0<br>
-#define CINDEX_VERSION_MINOR 22<br>
+#define CINDEX_VERSION_MINOR 23<br>
<br>
#define CINDEX_VERSION_ENCODE(major, minor) ( \<br>
((major) * 10000) \<br>
@@ -73,6 +73,43 @@ extern "C" {<br>
*/<br>
<br>
/**<br>
+ * \brief Error codes returned by libclang routines.<br>
+ *<br>
+ * Zero (\c CXError_Success) is the only error code indicating success. Other<br>
+ * error codes, including not yet assigned non-zero values, indicate errors.<br>
+ */<br>
+enum CXErrorCode {<br>
+ /**<br>
+ * \brief No error.<br>
+ */<br>
+ CXError_Success = 0,<br>
+<br>
+ /**<br>
+ * \brief A generic error code, no further details are available.<br>
+ *<br>
+ * Errors of this kind can get their own specific error codes in future<br>
+ * libclang versions.<br>
+ */<br>
+ CXError_Failure = 1,<br>
+<br>
+ /**<br>
+ * \brief libclang crashed while performing the requested operation.<br>
+ */<br>
+ CXError_Crashed = 2,<br>
+<br>
+ /**<br>
+ * \brief The function detected that the arguments violate the function<br>
+ * contract.<br>
+ */<br>
+ CXError_InvalidArguments = 3,<br>
+<br>
+ /**<br>
+ * \brief An AST deserialization error has occurred.<br>
+ */<br>
+ CXError_ASTReadError = 4<br>
+};<br>
+<br>
+/**<br>
* \brief An "index" that consists of a set of translation units that would<br>
* typically be linked together into an executable or library.<br>
*/<br>
@@ -1076,10 +1113,27 @@ CINDEX_LINKAGE CXTranslationUnit clang_c<br>
struct CXUnsavedFile *unsaved_files);<br>
<br>
/**<br>
- * \brief Create a translation unit from an AST file (-emit-ast).<br>
+ * \brief Same as \c clang_createTranslationUnit2, but returns<br>
+ * the \c CXTranslationUnit instead of an error code. In case of an error this<br>
+ * routine returns a \c NULL \c CXTranslationUnit, without further detailed<br>
+ * error codes.<br>
+ */<br>
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(<br>
+ CXIndex CIdx,<br>
+ const char *ast_filename);<br>
+<br>
+/**<br>
+ * \brief Create a translation unit from an AST file (\c -emit-ast).<br>
+ *<br>
+ * \param[out] out_TU A non-NULL pointer to store the created<br>
+ * \c CXTranslationUnit.<br>
+ *<br>
+ * \returns Zero on success, otherwise returns an error code.<br>
*/<br>
-CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(CXIndex,<br>
- const char *ast_filename);<br>
+CINDEX_LINKAGE enum CXErrorCode clang_createTranslationUnit2(<br>
+ CXIndex CIdx,<br>
+ const char *ast_filename,<br>
+ CXTranslationUnit *out_TU);<br>
<br>
/**<br>
* \brief Flags that control the creation of translation units.<br>
@@ -1193,7 +1247,22 @@ enum CXTranslationUnit_Flags {<br>
* set of optimizations enabled may change from one version to the next.<br>
*/<br>
CINDEX_LINKAGE unsigned clang_defaultEditingTranslationUnitOptions(void);<br>
-<br>
+<br>
+/**<br>
+ * \brief Same as \c clang_parseTranslationUnit2, but returns<br>
+ * the \c CXTranslationUnit instead of an error code. In case of an error this<br>
+ * routine returns a \c NULL \c CXTranslationUnit, without further detailed<br>
+ * error codes.<br>
+ */<br>
+CINDEX_LINKAGE CXTranslationUnit<br>
+clang_parseTranslationUnit(CXIndex CIdx,<br>
+ const char *source_filename,<br>
+ const char *const *command_line_args,<br>
+ int num_command_line_args,<br>
+ struct CXUnsavedFile *unsaved_files,<br>
+ unsigned num_unsaved_files,<br>
+ unsigned options);<br>
+<br>
/**<br>
* \brief Parse the given source file and the translation unit corresponding<br>
* to that file.<br>
@@ -1208,7 +1277,7 @@ CINDEX_LINKAGE unsigned clang_defaultEdi<br>
* associated.<br>
*<br>
* \param source_filename The name of the source file to load, or NULL if the<br>
- * source file is included in \p command_line_args.<br>
+ * source file is included in \c command_line_args.<br>
*<br>
* \param command_line_args The command-line arguments that would be<br>
* passed to the \c clang executable if it were being invoked out-of-process.<br>
@@ -1217,7 +1286,7 @@ CINDEX_LINKAGE unsigned clang_defaultEdi<br>
* '-emit-ast', '-fsyntax-only' (which is the default), and '-o \<output file>'.<br>
*<br>
* \param num_command_line_args The number of command-line arguments in<br>
- * \p command_line_args.<br>
+ * \c command_line_args.<br>
*<br>
* \param unsaved_files the files that have not yet been saved to disk<br>
* but may be required for parsing, including the contents of<br>
@@ -1232,18 +1301,22 @@ CINDEX_LINKAGE unsigned clang_defaultEdi<br>
* is managed but not its compilation. This should be a bitwise OR of the<br>
* CXTranslationUnit_XXX flags.<br>
*<br>
- * \returns A new translation unit describing the parsed code and containing<br>
- * any diagnostics produced by the compiler. If there is a failure from which<br>
- * the compiler cannot recover, returns NULL.<br>
- */<br>
-CINDEX_LINKAGE CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,<br>
- const char *source_filename,<br>
- const char * const *command_line_args,<br>
- int num_command_line_args,<br>
- struct CXUnsavedFile *unsaved_files,<br>
- unsigned num_unsaved_files,<br>
- unsigned options);<br>
-<br>
+ * \param[out] out_TU A non-NULL pointer to store the created<br>
+ * \c CXTranslationUnit, describing the parsed code and containing any<br>
+ * diagnostics produced by the compiler.<br>
+ *<br>
+ * \returns Zero on success, otherwise returns an error code.<br>
+ */<br>
+CINDEX_LINKAGE enum CXErrorCode<br>
+clang_parseTranslationUnit2(CXIndex CIdx,<br>
+ const char *source_filename,<br>
+ const char *const *command_line_args,<br>
+ int num_command_line_args,<br>
+ struct CXUnsavedFile *unsaved_files,<br>
+ unsigned num_unsaved_files,<br>
+ unsigned options,<br>
+ CXTranslationUnit *out_TU);<br>
+<br>
/**<br>
* \brief Flags that control how translation units are saved.<br>
*<br>
@@ -1395,10 +1468,11 @@ CINDEX_LINKAGE unsigned clang_defaultRep<br>
* The function \c clang_defaultReparseOptions() produces a default set of<br>
* options recommended for most uses, based on the translation unit.<br>
*<br>
- * \returns 0 if the sources could be reparsed. A non-zero value will be<br>
+ * \returns 0 if the sources could be reparsed. A non-zero error code will be<br>
* returned if reparsing was impossible, such that the translation unit is<br>
- * invalid. In such cases, the only valid call for \p TU is<br>
- * \c clang_disposeTranslationUnit(TU).<br>
+ * invalid. In such cases, the only valid call for \c TU is<br>
+ * \c clang_disposeTranslationUnit(TU). The error codes returned by this<br>
+ * routine are described by the \c CXErrorCode enum.<br>
*/<br>
CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU,<br>
unsigned num_unsaved_files,<br>
@@ -5789,11 +5863,12 @@ typedef enum {<br>
* \param index_options A bitmask of options that affects how indexing is<br>
* performed. This should be a bitwise OR of the CXIndexOpt_XXX flags.<br>
*<br>
- * \param out_TU [out] pointer to store a CXTranslationUnit that can be reused<br>
- * after indexing is finished. Set to NULL if you do not require it.<br>
+ * \param[out] out_TU pointer to store a \c CXTranslationUnit that can be<br>
+ * reused after indexing is finished. Set to \c NULL if you do not require it.<br>
*<br>
- * \returns If there is a failure from which the there is no recovery, returns<br>
- * non-zero, otherwise returns 0.<br>
+ * \returns 0 on success or if there were errors from which the compiler could<br>
+ * recover. If there is a failure from which the there is no recovery, returns<br>
+ * a non-zero \c CXErrorCode.<br>
*<br>
* The rest of the parameters are the same as #clang_parseTranslationUnit.<br>
*/<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=201249&r1=201248&r2=201249&view=diff" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=201249&r1=201248&r2=201249&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Wed Feb 12 13:12:37 2014<br>
@@ -8,6 +8,7 @@<br>
//===----------------------------------------------------------------------===//<br>
<br>
let Component = "Serialization" in {<br>
+let CategoryName = "AST Deserialization Issue" in {<br>
<br>
def err_fe_unable_to_read_pch_file : Error<<br>
"unable to read PCH file %0: '%1'">;<br>
@@ -78,4 +79,6 @@ def note_module_odr_violation_no_possibl<br>
def note_module_odr_violation_possible_decl : Note<<br>
"declaration of %0 does not match">;<br>
<br>
-}<br>
+} // let CategoryName<br>
+} // let Component<br>
+<br>
<br>
Added: cfe/trunk/test/Index/pch-depending-on-deleted-module.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/pch-depending-on-deleted-module.c?rev=201249&view=auto" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/pch-depending-on-deleted-module.c?rev=201249&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Index/pch-depending-on-deleted-module.c (added)<br>
+++ cfe/trunk/test/Index/pch-depending-on-deleted-module.c Wed Feb 12 13:12:37 2014<br>
@@ -0,0 +1,14 @@<br>
+#include "a.h"<br>
+<br>
+// RUN: rm -rf %t<br>
+// RUN: mkdir %t<br>
+<br>
+// 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<br>
+// RUN: %clang_cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -verify-pch %t/use_LibA.pch<br>
+// RUN: rm -f %t/modules-cache/LibA.pcm<br>
+// 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<br>
+// 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<br>
+<br>
+// VERIFY: fatal error: malformed or corrupted AST file: 'Unable to load module<br>
+// INDEX: {{^}}Failure: AST deserialization error occurred{{$}}<br>
+<br>
<br>
Modified: cfe/trunk/test/Modules/fatal-module-loader-error.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/fatal-module-loader-error.m?rev=201249&r1=201248&r2=201249&view=diff" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/fatal-module-loader-error.m?rev=201249&r1=201248&r2=201249&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/fatal-module-loader-error.m (original)<br>
+++ cfe/trunk/test/Modules/fatal-module-loader-error.m Wed Feb 12 13:12:37 2014<br>
@@ -23,4 +23,4 @@<br>
// Also check that libclang does not create a PCH with such an error.<br>
// RUN: not c-index-test -write-pch %t.pch -fmodules -fmodules-cache-path=%t \<br>
// RUN: %s -Xclang -fdisable-module-hash -F %S/Inputs 2>&1 | FileCheck %s<br>
-// CHECK: Unable to write PCH file<br>
+// CHECK: {{^}}Failure: AST deserialization error occurred{{$}}<br>
<br>
Modified: cfe/trunk/tools/c-index-test/c-index-test.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=201249&r1=201248&r2=201249&view=diff" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=201249&r1=201248&r2=201249&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)<br>
+++ cfe/trunk/tools/c-index-test/c-index-test.c Wed Feb 12 13:12:37 2014<br>
@@ -79,8 +79,33 @@ static unsigned getDefaultParsingOptions<br>
return options;<br>
}<br>
<br>
+/// \brief Returns 0 in case of success, non-zero in case of a failure.<br>
static int checkForErrors(CXTranslationUnit TU);<br>
<br>
+static void describeLibclangFailure(enum CXErrorCode Err) {<br>
+ switch (Err) {<br>
+ case CXError_Success:<br>
+ fprintf(stderr, "Success\n");<br>
+ return;<br>
+<br>
+ case CXError_Failure:<br>
+ fprintf(stderr, "Failure (no details available)\n");<br>
+ return;<br>
+<br>
+ case CXError_Crashed:<br>
+ fprintf(stderr, "Failure: libclang crashed\n");<br>
+ return;<br>
+<br>
+ case CXError_InvalidArguments:<br>
+ fprintf(stderr, "Failure: invalid arguments passed to a libclang routine\n");<br>
+ return;<br>
+<br>
+ case CXError_ASTReadError:<br>
+ fprintf(stderr, "Failure: AST deserialization error occurred\n");<br>
+ return;<br>
+ }<br>
+}<br>
+<br>
static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column,<br>
unsigned end_line, unsigned end_column) {<br>
fprintf(out, "[%d:%d - %d:%d]", begin_line, begin_column,<br>
@@ -89,10 +114,11 @@ static void PrintExtent(FILE *out, unsig<br>
<br>
static unsigned CreateTranslationUnit(CXIndex Idx, const char *file,<br>
CXTranslationUnit *TU) {<br>
-<br>
- *TU = clang_createTranslationUnit(Idx, file);<br>
- if (!*TU) {<br>
+ enum CXErrorCode Err = clang_createTranslationUnit2(Idx, file, TU);<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "Unable to load translation unit from '%s'!\n", file);<br>
+ describeLibclangFailure(Err);<br>
+ *TU = 0;<br>
return 0;<br>
}<br>
return 1;<br>
@@ -1420,8 +1446,9 @@ int perform_test_load_source(int argc, c<br>
const char *CommentSchemaFile;<br>
struct CXUnsavedFile *unsaved_files = 0;<br>
int num_unsaved_files = 0;<br>
+ enum CXErrorCode Err;<br>
int result;<br>
-<br>
+<br>
Idx = clang_createIndex(/* excludeDeclsFromPCH */<br>
(!strcmp(filter, "local") ||<br>
!strcmp(filter, "local-display"))? 1 : 0,<br>
@@ -1437,13 +1464,14 @@ int perform_test_load_source(int argc, c<br>
return -1;<br>
}<br>
<br>
- TU = clang_parseTranslationUnit(Idx, 0,<br>
- argv + num_unsaved_files,<br>
- argc - num_unsaved_files,<br>
- unsaved_files, num_unsaved_files,<br>
- getDefaultParsingOptions());<br>
- if (!TU) {<br>
+ Err = clang_parseTranslationUnit2(Idx, 0,<br>
+ argv + num_unsaved_files,<br>
+ argc - num_unsaved_files,<br>
+ unsaved_files, num_unsaved_files,<br>
+ getDefaultParsingOptions(), &TU);<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "Unable to load translation unit!\n");<br>
+ describeLibclangFailure(Err);<br>
free_remapped_files(unsaved_files, num_unsaved_files);<br>
clang_disposeIndex(Idx);<br>
return 1;<br>
@@ -1464,6 +1492,7 @@ int perform_test_reparse_source(int argc<br>
struct CXUnsavedFile *unsaved_files = 0;<br>
int num_unsaved_files = 0;<br>
int compiler_arg_idx = 0;<br>
+ enum CXErrorCode Err;<br>
int result, i;<br>
int trial;<br>
int remap_after_trial = 0;<br>
@@ -1489,12 +1518,13 @@ int perform_test_reparse_source(int argc<br>
<br>
/* Load the initial translation unit -- we do this without honoring remapped<br>
* files, so that we have a way to test results after changing the source. */<br>
- TU = clang_parseTranslationUnit(Idx, 0,<br>
- argv + compiler_arg_idx,<br>
- argc - compiler_arg_idx,<br>
- 0, 0, getDefaultParsingOptions());<br>
- if (!TU) {<br>
+ Err = clang_parseTranslationUnit2(Idx, 0,<br>
+ argv + compiler_arg_idx,<br>
+ argc - compiler_arg_idx,<br>
+ 0, 0, getDefaultParsingOptions(), &TU);<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "Unable to load translation unit!\n");<br>
+ describeLibclangFailure(Err);<br>
free_remapped_files(unsaved_files, num_unsaved_files);<br>
clang_disposeIndex(Idx);<br>
return 1;<br>
@@ -1517,11 +1547,14 @@ int perform_test_reparse_source(int argc<br>
return -1;<br>
}<br>
<br>
- if (clang_reparseTranslationUnit(TU,<br>
- trial >= remap_after_trial ? num_unsaved_files : 0,<br>
- trial >= remap_after_trial ? unsaved_files : 0,<br>
- clang_defaultReparseOptions(TU))) {<br>
+ Err = clang_reparseTranslationUnit(<br>
+ TU,<br>
+ trial >= remap_after_trial ? num_unsaved_files : 0,<br>
+ trial >= remap_after_trial ? unsaved_files : 0,<br>
+ clang_defaultReparseOptions(TU));<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "Unable to reparse translation unit!\n");<br>
+ describeLibclangFailure(Err);<br>
clang_disposeTranslationUnit(TU);<br>
free_remapped_files(unsaved_files, num_unsaved_files);<br>
clang_disposeIndex(Idx);<br>
@@ -1943,7 +1976,8 @@ int perform_code_completion(int argc, co<br>
struct CXUnsavedFile *unsaved_files = 0;<br>
int num_unsaved_files = 0;<br>
CXCodeCompleteResults *results = 0;<br>
- CXTranslationUnit TU = 0;<br>
+ enum CXErrorCode Err;<br>
+ CXTranslationUnit TU;<br>
unsigned I, Repeats = 1;<br>
unsigned completionOptions = clang_defaultCodeCompleteOptions();<br>
<br>
@@ -1968,21 +2002,27 @@ int perform_code_completion(int argc, co<br>
<br>
if (getenv("CINDEXTEST_EDITING"))<br>
Repeats = 5;<br>
-<br>
- TU = clang_parseTranslationUnit(CIdx, 0,<br>
- argv + num_unsaved_files + 2,<br>
- argc - num_unsaved_files - 2,<br>
- 0, 0, getDefaultParsingOptions());<br>
- if (!TU) {<br>
+<br>
+ Err = clang_parseTranslationUnit2(CIdx, 0,<br>
+ argv + num_unsaved_files + 2,<br>
+ argc - num_unsaved_files - 2,<br>
+ 0, 0, getDefaultParsingOptions(), &TU);<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "Unable to load translation unit!\n");<br>
+ describeLibclangFailure(Err);<br>
return 1;<br>
}<br>
<br>
- if (clang_reparseTranslationUnit(TU, 0, 0, clang_defaultReparseOptions(TU))) {<br>
+ Err = clang_reparseTranslationUnit(TU, 0, 0,<br>
+ clang_defaultReparseOptions(TU));<br>
+<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "Unable to reparse translation init!\n");<br>
+ describeLibclangFailure(Err);<br>
+ clang_disposeTranslationUnit(TU);<br>
return 1;<br>
}<br>
-<br>
+<br>
for (I = 0; I != Repeats; ++I) {<br>
results = clang_codeCompleteAt(TU, filename, line, column,<br>
unsaved_files, num_unsaved_files,<br>
@@ -2069,6 +2109,7 @@ static int inspect_cursor_at(int argc, c<br>
int errorCode;<br>
struct CXUnsavedFile *unsaved_files = 0;<br>
int num_unsaved_files = 0;<br>
+ enum CXErrorCode Err;<br>
CXTranslationUnit TU;<br>
CXCursor Cursor;<br>
CursorSourceLocation *Locations = 0;<br>
@@ -2102,15 +2143,15 @@ static int inspect_cursor_at(int argc, c<br>
/* Parse the translation unit. When we're testing clang_getCursor() after<br>
reparsing, don't remap unsaved files until the second parse. */<br>
CIdx = clang_createIndex(1, 1);<br>
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],<br>
- argv + num_unsaved_files + 1 + NumLocations,<br>
- argc - num_unsaved_files - 2 - NumLocations,<br>
- unsaved_files,<br>
- Repeats > 1? 0 : num_unsaved_files,<br>
- getDefaultParsingOptions());<br>
-<br>
- if (!TU) {<br>
+ Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],<br>
+ argv + num_unsaved_files + 1 + NumLocations,<br>
+ argc - num_unsaved_files - 2 - NumLocations,<br>
+ unsaved_files,<br>
+ Repeats > 1? 0 : num_unsaved_files,<br>
+ getDefaultParsingOptions(), &TU);<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "unable to parse input\n");<br>
+ describeLibclangFailure(Err);<br>
return -1;<br>
}<br>
<br>
@@ -2118,11 +2159,14 @@ static int inspect_cursor_at(int argc, c<br>
return -1;<br>
<br>
for (I = 0; I != Repeats; ++I) {<br>
- if (Repeats > 1 &&<br>
- clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,<br>
- clang_defaultReparseOptions(TU))) {<br>
- clang_disposeTranslationUnit(TU);<br>
- return 1;<br>
+ if (Repeats > 1) {<br>
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,<br>
+ clang_defaultReparseOptions(TU));<br>
+ if (Err != CXError_Success) {<br>
+ describeLibclangFailure(Err);<br>
+ clang_disposeTranslationUnit(TU);<br>
+ return 1;<br>
+ }<br>
}<br>
<br>
if (checkForErrors(TU) != 0)<br>
@@ -2235,6 +2279,7 @@ static int find_file_refs_at(int argc, c<br>
int errorCode;<br>
struct CXUnsavedFile *unsaved_files = 0;<br>
int num_unsaved_files = 0;<br>
+ enum CXErrorCode Err;<br>
CXTranslationUnit TU;<br>
CXCursor Cursor;<br>
CursorSourceLocation *Locations = 0;<br>
@@ -2268,15 +2313,16 @@ static int find_file_refs_at(int argc, c<br>
/* Parse the translation unit. When we're testing clang_getCursor() after<br>
reparsing, don't remap unsaved files until the second parse. */<br>
CIdx = clang_createIndex(1, 1);<br>
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],<br>
- argv + num_unsaved_files + 1 + NumLocations,<br>
- argc - num_unsaved_files - 2 - NumLocations,<br>
- unsaved_files,<br>
- Repeats > 1? 0 : num_unsaved_files,<br>
- getDefaultParsingOptions());<br>
-<br>
- if (!TU) {<br>
+ Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],<br>
+ argv + num_unsaved_files + 1 + NumLocations,<br>
+ argc - num_unsaved_files - 2 - NumLocations,<br>
+ unsaved_files,<br>
+ Repeats > 1? 0 : num_unsaved_files,<br>
+ getDefaultParsingOptions(), &TU);<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "unable to parse input\n");<br>
+ describeLibclangFailure(Err);<br>
+ clang_disposeTranslationUnit(TU);<br>
return -1;<br>
}<br>
<br>
@@ -2284,11 +2330,14 @@ static int find_file_refs_at(int argc, c<br>
return -1;<br>
<br>
for (I = 0; I != Repeats; ++I) {<br>
- if (Repeats > 1 &&<br>
- clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,<br>
- clang_defaultReparseOptions(TU))) {<br>
- clang_disposeTranslationUnit(TU);<br>
- return 1;<br>
+ if (Repeats > 1) {<br>
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,<br>
+ clang_defaultReparseOptions(TU));<br>
+ if (Err != CXError_Success) {<br>
+ describeLibclangFailure(Err);<br>
+ clang_disposeTranslationUnit(TU);<br>
+ return 1;<br>
+ }<br>
}<br>
<br>
if (checkForErrors(TU) != 0)<br>
@@ -2339,6 +2388,7 @@ static int find_file_includes_in(int arg<br>
CXIndex CIdx;<br>
struct CXUnsavedFile *unsaved_files = 0;<br>
int num_unsaved_files = 0;<br>
+ enum CXErrorCode Err;<br>
CXTranslationUnit TU;<br>
const char **Filenames = 0;<br>
unsigned NumFilenames = 0;<br>
@@ -2368,15 +2418,17 @@ static int find_file_includes_in(int arg<br>
/* Parse the translation unit. When we're testing clang_getCursor() after<br>
reparsing, don't remap unsaved files until the second parse. */<br>
CIdx = clang_createIndex(1, 1);<br>
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],<br>
- argv + num_unsaved_files + 1 + NumFilenames,<br>
- argc - num_unsaved_files - 2 - NumFilenames,<br>
- unsaved_files,<br>
- Repeats > 1? 0 : num_unsaved_files,<br>
- getDefaultParsingOptions());<br>
+ Err = clang_parseTranslationUnit2(<br>
+ CIdx, argv[argc - 1],<br>
+ argv + num_unsaved_files + 1 + NumFilenames,<br>
+ argc - num_unsaved_files - 2 - NumFilenames,<br>
+ unsaved_files,<br>
+ Repeats > 1 ? 0 : num_unsaved_files, getDefaultParsingOptions(), &TU);<br>
<br>
- if (!TU) {<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "unable to parse input\n");<br>
+ describeLibclangFailure(Err);<br>
+ clang_disposeTranslationUnit(TU);<br>
return -1;<br>
}<br>
<br>
@@ -2384,11 +2436,14 @@ static int find_file_includes_in(int arg<br>
return -1;<br>
<br>
for (I = 0; I != Repeats; ++I) {<br>
- if (Repeats > 1 &&<br>
- clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,<br>
- clang_defaultReparseOptions(TU))) {<br>
- clang_disposeTranslationUnit(TU);<br>
- return 1;<br>
+ if (Repeats > 1) {<br>
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,<br>
+ clang_defaultReparseOptions(TU));<br>
+ if (Err != CXError_Success) {<br>
+ describeLibclangFailure(Err);<br>
+ clang_disposeTranslationUnit(TU);<br>
+ return 1;<br>
+ }<br>
}<br>
<br>
if (checkForErrors(TU) != 0)<br>
@@ -2933,6 +2988,9 @@ static int index_compile_args(int num_ar<br>
&IndexCB,sizeof(IndexCB), index_opts,<br>
0, args, num_args, 0, 0, 0,<br>
getDefaultParsingOptions());<br>
+ if (result != CXError_Success)<br>
+ describeLibclangFailure(result);<br>
+<br>
if (index_data.fail_for_error)<br>
result = -1;<br>
<br>
@@ -3185,6 +3243,7 @@ int perform_token_annotation(int argc, c<br>
CXFile file = 0;<br>
CXCursor *cursors = 0;<br>
CXSourceRangeList *skipped_ranges = 0;<br>
+ enum CXErrorCode Err;<br>
unsigned i;<br>
<br>
input += strlen("-test-annotate-tokens=");<br>
@@ -3198,14 +3257,15 @@ int perform_token_annotation(int argc, c<br>
}<br>
<br>
CIdx = clang_createIndex(0, 1);<br>
- TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],<br>
- argv + num_unsaved_files + 2,<br>
- argc - num_unsaved_files - 3,<br>
- unsaved_files,<br>
- num_unsaved_files,<br>
- getDefaultParsingOptions());<br>
- if (!TU) {<br>
+ Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],<br>
+ argv + num_unsaved_files + 2,<br>
+ argc - num_unsaved_files - 3,<br>
+ unsaved_files,<br>
+ num_unsaved_files,<br>
+ getDefaultParsingOptions(), &TU);<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "unable to parse input\n");<br>
+ describeLibclangFailure(Err);<br>
clang_disposeIndex(CIdx);<br>
free(filename);<br>
free_remapped_files(unsaved_files, num_unsaved_files);<br>
@@ -3220,9 +3280,11 @@ int perform_token_annotation(int argc, c<br>
<br>
if (getenv("CINDEXTEST_EDITING")) {<br>
for (i = 0; i < 5; ++i) {<br>
- if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,<br>
- clang_defaultReparseOptions(TU))) {<br>
+ Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,<br>
+ clang_defaultReparseOptions(TU));<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "Unable to reparse translation unit!\n");<br>
+ describeLibclangFailure(Err);<br>
errorCode = -1;<br>
goto teardown;<br>
}<br>
@@ -3586,6 +3648,7 @@ int write_pch_file(const char *filename,<br>
CXTranslationUnit TU;<br>
struct CXUnsavedFile *unsaved_files = 0;<br>
int num_unsaved_files = 0;<br>
+ enum CXErrorCode Err;<br>
int result = 0;<br>
<br>
Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnostics=*/1);<br>
@@ -3594,18 +3657,19 @@ int write_pch_file(const char *filename,<br>
clang_disposeIndex(Idx);<br>
return -1;<br>
}<br>
-<br>
- TU = clang_parseTranslationUnit(Idx, 0,<br>
- argv + num_unsaved_files,<br>
- argc - num_unsaved_files,<br>
- unsaved_files,<br>
- num_unsaved_files,<br>
- CXTranslationUnit_Incomplete |<br>
- CXTranslationUnit_DetailedPreprocessingRecord|<br>
- CXTranslationUnit_ForSerialization);<br>
- if (!TU) {<br>
+<br>
+ Err = clang_parseTranslationUnit2(<br>
+ Idx, 0, argv + num_unsaved_files, argc - num_unsaved_files,<br>
+ unsaved_files, num_unsaved_files,<br>
+ CXTranslationUnit_Incomplete |<br>
+ CXTranslationUnit_DetailedPreprocessingRecord |<br>
+ CXTranslationUnit_ForSerialization,<br>
+ &TU);<br>
+ if (Err != CXError_Success) {<br>
fprintf(stderr, "Unable to load translation unit!\n");<br>
+ describeLibclangFailure(Err);<br>
free_remapped_files(unsaved_files, num_unsaved_files);<br>
+ clang_disposeTranslationUnit(TU);<br>
clang_disposeIndex(Idx);<br>
return 1;<br>
}<br>
<br>
Modified: cfe/trunk/tools/libclang/CIndex.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=201249&r1=201248&r2=201249&view=diff" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=201249&r1=201248&r2=201249&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/tools/libclang/CIndex.cpp (original)<br>
+++ cfe/trunk/tools/libclang/CIndex.cpp Wed Feb 12 13:12:37 2014<br>
@@ -25,6 +25,8 @@<br>
#include "clang/AST/Attr.h"<br>
#include "clang/AST/StmtVisitor.h"<br>
#include "clang/Basic/Diagnostic.h"<br>
+#include "clang/Basic/DiagnosticCategories.h"<br>
+#include "clang/Basic/DiagnosticIDs.h"<br>
#include "clang/Basic/Version.h"<br>
#include "clang/Frontend/ASTUnit.h"<br>
#include "clang/Frontend/CompilerInstance.h"<br>
@@ -34,6 +36,7 @@<br>
#include "clang/Lex/Lexer.h"<br>
#include "clang/Lex/PreprocessingRecord.h"<br>
#include "clang/Lex/Preprocessor.h"<br>
+#include "clang/Serialization/SerializationDiagnostic.h"<br>
#include "llvm/ADT/Optional.h"<br>
#include "llvm/ADT/STLExtras.h"<br>
#include "llvm/ADT/StringSwitch.h"<br>
@@ -62,6 +65,7 @@ using namespace clang::cxindex;<br>
CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {<br>
if (!AU)<br>
return 0;<br>
+ assert(CIdx);<br>
CXTranslationUnit D = new CXTranslationUnitImpl();<br>
D->CIdx = CIdx;<br>
D->TheASTUnit = AU;<br>
@@ -72,6 +76,18 @@ CXTranslationUnit cxtu::MakeCXTranslatio<br>
return D;<br>
}<br>
<br>
+bool cxtu::isASTReadError(ASTUnit *AU) {<br>
+ for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),<br>
+ DEnd = AU->stored_diag_end();<br>
+ D != DEnd; ++D) {<br>
+ if (D->getLevel() >= DiagnosticsEngine::Error &&<br>
+ DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==<br>
+ diag::DiagCat_AST_Deserialization_Issue)<br>
+ return true;<br>
+ }<br>
+ return false;<br>
+}<br>
+<br>
cxtu::CXTUOwner::~CXTUOwner() {<br>
if (TU)<br>
clang_disposeTranslationUnit(TU);<br>
@@ -2589,11 +2605,22 @@ void clang_toggleCrashRecovery(unsigned<br>
else<br>
llvm::CrashRecoveryContext::Disable();<br>
}<br>
-<br>
+<br>
CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,<br>
const char *ast_filename) {<br>
- if (!CIdx || !ast_filename)<br>
- return 0;<br>
+ CXTranslationUnit TU;<br>
+ enum CXErrorCode Result =<br>
+ clang_createTranslationUnit2(CIdx, ast_filename, &TU);<br>
+ assert((TU && Result == CXError_Success) ||<br>
+ (!TU && Result != CXError_Success));<br></blockquote><div><br></div><div>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.</div>
<div><br></div><div>Cheers,</div><div>Daniel</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+ return TU;<br>
+}<br>
+<br>
+enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,<br>
+ const char *ast_filename,<br>
+ CXTranslationUnit *out_TU) {<br>
+ if (!CIdx || !ast_filename || !out_TU)<br>
+ return CXError_InvalidArguments;<br>
<br>
LOG_FUNC_SECTION {<br>
*Log << ast_filename;<br>
@@ -2603,19 +2630,20 @@ CXTranslationUnit clang_createTranslatio<br>
FileSystemOptions FileSystemOpts;<br>
<br>
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;<br>
- ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,<br>
+ ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,<br>
CXXIdx->getOnlyLocalDecls(), None,<br>
/*CaptureDiagnostics=*/true,<br>
/*AllowPCHWithCompilerErrors=*/true,<br>
/*UserFilesAreVolatile=*/true);<br>
- return MakeCXTranslationUnit(CXXIdx, TU);<br>
+ *out_TU = MakeCXTranslationUnit(CXXIdx, AU);<br>
+ return *out_TU ? CXError_Success : CXError_Failure;<br>
}<br>
<br>
unsigned clang_defaultEditingTranslationUnitOptions() {<br>
return CXTranslationUnit_PrecompiledPreamble |<br>
CXTranslationUnit_CacheCompletionResults;<br>
}<br>
-<br>
+<br>
CXTranslationUnit<br>
clang_createTranslationUnitFromSourceFile(CXIndex CIdx,<br>
const char *source_filename,<br>
@@ -2638,7 +2666,8 @@ struct ParseTranslationUnitInfo {<br>
struct CXUnsavedFile *unsaved_files;<br>
unsigned num_unsaved_files;<br>
unsigned options;<br>
- CXTranslationUnit result;<br>
+ CXTranslationUnit *out_TU;<br>
+ CXErrorCode result;<br>
};<br>
static void clang_parseTranslationUnit_Impl(void *UserData) {<br>
ParseTranslationUnitInfo *PTUI =<br>
@@ -2650,10 +2679,18 @@ static void clang_parseTranslationUnit_I<br>
struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;<br>
unsigned num_unsaved_files = PTUI->num_unsaved_files;<br>
unsigned options = PTUI->options;<br>
- PTUI->result = 0;<br>
+ CXTranslationUnit *out_TU = PTUI->out_TU;<br>
<br>
- if (!CIdx)<br>
+ // Check arguments.<br>
+ if (!CIdx || !out_TU ||<br>
+ (unsaved_files == NULL && num_unsaved_files != 0)) {<br>
+ PTUI->result = CXError_InvalidArguments;<br>
return;<br>
+ }<br>
+<br>
+ // Set up the initial return values.<br>
+ *out_TU = NULL;<br>
+ PTUI->result = CXError_Failure;<br>
<br>
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);<br>
<br>
@@ -2763,15 +2800,40 @@ static void clang_parseTranslationUnit_I<br>
printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());<br>
}<br>
<br>
- PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());<br>
+ if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {<br>
+ PTUI->result = CXError_ASTReadError;<br>
+ } else {<br>
+ *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.take());<br>
+ PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;<br>
+ }<br>
}<br>
-CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,<br>
- const char *source_filename,<br>
- const char * const *command_line_args,<br>
- int num_command_line_args,<br>
- struct CXUnsavedFile *unsaved_files,<br>
- unsigned num_unsaved_files,<br>
- unsigned options) {<br>
+<br>
+CXTranslationUnit<br>
+clang_parseTranslationUnit(CXIndex CIdx,<br>
+ const char *source_filename,<br>
+ const char *const *command_line_args,<br>
+ int num_command_line_args,<br>
+ struct CXUnsavedFile *unsaved_files,<br>
+ unsigned num_unsaved_files,<br>
+ unsigned options) {<br>
+ CXTranslationUnit TU;<br>
+ enum CXErrorCode Result = clang_parseTranslationUnit2(<br>
+ CIdx, source_filename, command_line_args, num_command_line_args,<br>
+ unsaved_files, num_unsaved_files, options, &TU);<br>
+ assert((TU && Result == CXError_Success) ||<br>
+ (!TU && Result != CXError_Success));<br>
+ return TU;<br>
+}<br>
+<br>
+enum CXErrorCode clang_parseTranslationUnit2(<br>
+ CXIndex CIdx,<br>
+ const char *source_filename,<br>
+ const char *const *command_line_args,<br>
+ int num_command_line_args,<br>
+ struct CXUnsavedFile *unsaved_files,<br>
+ unsigned num_unsaved_files,<br>
+ unsigned options,<br>
+ CXTranslationUnit *out_TU) {<br>
LOG_FUNC_SECTION {<br>
*Log << source_filename << ": ";<br>
for (int i = 0; i != num_command_line_args; ++i)<br>
@@ -2780,7 +2842,8 @@ CXTranslationUnit clang_parseTranslation<br>
<br>
ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,<br>
num_command_line_args, unsaved_files,<br>
- num_unsaved_files, options, 0 };<br>
+ num_unsaved_files, options, out_TU,<br>
+ CXError_Failure };<br>
llvm::CrashRecoveryContext CRC;<br>
<br>
if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {<br>
@@ -2803,10 +2866,11 @@ CXTranslationUnit clang_parseTranslation<br>
fprintf(stderr, "],\n");<br>
fprintf(stderr, " 'options' : %d,\n", options);<br>
fprintf(stderr, "}\n");<br>
-<br>
- return 0;<br>
+<br>
+ return CXError_Crashed;<br>
} else if (getenv("LIBCLANG_RESOURCE_USAGE")) {<br>
- PrintLibclangResourceUsage(PTUI.result);<br>
+ if (CXTranslationUnit *TU = PTUI.out_TU)<br>
+ PrintLibclangResourceUsage(*TU);<br>
}<br>
<br>
return PTUI.result;<br>
@@ -2891,7 +2955,8 @@ void clang_disposeTranslationUnit(CXTran<br>
if (CTUnit) {<br>
// If the translation unit has been marked as unsafe to free, just discard<br>
// it.<br>
- if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())<br>
+ ASTUnit *Unit = cxtu::getASTUnit(CTUnit);<br>
+ if (Unit && Unit->isUnsafeToFree())<br>
return;<br>
<br>
delete cxtu::getASTUnit(CTUnit);<br>
@@ -2918,11 +2983,22 @@ struct ReparseTranslationUnitInfo {<br>
static void clang_reparseTranslationUnit_Impl(void *UserData) {<br>
ReparseTranslationUnitInfo *RTUI =<br>
static_cast<ReparseTranslationUnitInfo*>(UserData);<br>
- RTUI->result = 1; // Error.<br>
+ RTUI->result = CXError_Failure;<br>
<br>
CXTranslationUnit TU = RTUI->TU;<br>
+ unsigned num_unsaved_files = RTUI->num_unsaved_files;<br>
+ struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;<br>
+ unsigned options = RTUI->options;<br>
+ (void) options;<br>
+<br>
+ // Check arguments.<br>
if (isNotUsableTU(TU)) {<br>
LOG_BAD_TU(TU);<br>
+ RTUI->result = CXError_InvalidArguments;<br>
+ return;<br>
+ }<br>
+ if (unsaved_files == NULL && num_unsaved_files != 0) {<br>
+ RTUI->result = CXError_InvalidArguments;<br>
return;<br>
}<br>
<br>
@@ -2930,11 +3006,6 @@ static void clang_reparseTranslationUnit<br>
delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);<br>
TU->Diagnostics = 0;<br>
<br>
- unsigned num_unsaved_files = RTUI->num_unsaved_files;<br>
- struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;<br>
- unsigned options = RTUI->options;<br>
- (void) options;<br>
-<br>
CIndexer *CXXIdx = TU->CIdx;<br>
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))<br>
setThreadBackgroundPriority();<br>
@@ -2956,9 +3027,11 @@ static void clang_reparseTranslationUnit<br>
RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,<br>
Buffer));<br>
}<br>
-<br>
+<br>
if (!CXXUnit->Reparse(*RemappedFiles.get()))<br>
- RTUI->result = 0;<br>
+ RTUI->result = CXError_Success;<br>
+ else if (isASTReadError(CXXUnit))<br>
+ RTUI->result = CXError_ASTReadError;<br>
}<br>
<br>
int clang_reparseTranslationUnit(CXTranslationUnit TU,<br>
@@ -2970,7 +3043,7 @@ int clang_reparseTranslationUnit(CXTrans<br>
}<br>
<br>
ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,<br>
- options, 0 };<br>
+ options, CXError_Failure };<br>
<br>
if (getenv("LIBCLANG_NOTHREADS")) {<br>
clang_reparseTranslationUnit_Impl(&RTUI);<br>
@@ -2982,7 +3055,7 @@ int clang_reparseTranslationUnit(CXTrans<br>
if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {<br>
fprintf(stderr, "libclang: crash detected during reparsing\n");<br>
cxtu::getASTUnit(TU)->setUnsafeToFree(true);<br>
- return 1;<br>
+ return CXError_Crashed;<br>
} else if (getenv("LIBCLANG_RESOURCE_USAGE"))<br>
PrintLibclangResourceUsage(TU);<br>
<br>
@@ -6747,9 +6820,9 @@ Logger &cxindex::Logger::operator<<(CXTr<br>
LogOS << " (" << Unit->getASTFileName() << ')';<br>
return *this;<br>
}<br>
+ } else {<br>
+ LogOS << "<NULL TU>";<br>
}<br>
-<br>
- LogOS << "<NULL TU>";<br>
return *this;<br>
}<br>
<br>
<br>
Modified: cfe/trunk/tools/libclang/CXTranslationUnit.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXTranslationUnit.h?rev=201249&r1=201248&r2=201249&view=diff" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXTranslationUnit.h?rev=201249&r1=201248&r2=201249&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/tools/libclang/CXTranslationUnit.h (original)<br>
+++ cfe/trunk/tools/libclang/CXTranslationUnit.h Wed Feb 12 13:12:37 2014<br>
@@ -46,6 +46,10 @@ static inline ASTUnit *getASTUnit(CXTran<br>
return TU->TheASTUnit;<br>
}<br>
<br>
+/// \returns true if the ASTUnit has a diagnostic about the AST file being<br>
+/// corrupted.<br>
+bool isASTReadError(ASTUnit *AU);<br>
+<br>
static inline bool isNotUsableTU(CXTranslationUnit TU) {<br>
return !TU;<br>
}<br>
<br>
Modified: cfe/trunk/tools/libclang/Indexing.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Indexing.cpp?rev=201249&r1=201248&r2=201249&view=diff" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Indexing.cpp?rev=201249&r1=201248&r2=201249&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/tools/libclang/Indexing.cpp (original)<br>
+++ cfe/trunk/tools/libclang/Indexing.cpp Wed Feb 12 13:12:37 2014<br>
@@ -514,16 +514,22 @@ static void clang_indexSourceFile_Impl(v<br>
unsigned num_unsaved_files = ITUI->num_unsaved_files;<br>
CXTranslationUnit *out_TU = ITUI->out_TU;<br>
unsigned TU_options = ITUI->TU_options;<br>
- ITUI->result = 1; // init as error.<br>
-<br>
+<br>
+ // Set up the initial return value.<br>
+ ITUI->result = CXError_Failure;<br>
+<br>
if (out_TU)<br>
*out_TU = 0;<br>
- bool requestedToGetTU = (out_TU != 0);<br>
+ bool requestedToGetTU = (out_TU != 0);<br>
<br>
- if (!cxIdxAction)<br>
+ if (!cxIdxAction) {<br>
+ ITUI->result = CXError_InvalidArguments;<br>
return;<br>
- if (!client_index_callbacks || index_callbacks_size == 0)<br>
+ }<br>
+ if (!client_index_callbacks || index_callbacks_size == 0) {<br>
+ ITUI->result = CXError_InvalidArguments;<br>
return;<br>
+ }<br>
<br>
IndexerCallbacks CB;<br>
memset(&CB, 0, sizeof(CB));<br>
@@ -671,13 +677,18 @@ static void clang_indexSourceFile_Impl(v<br>
if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())<br>
printDiagsToStderr(Unit);<br>
<br>
+ if (isASTReadError(Unit)) {<br>
+ ITUI->result = CXError_ASTReadError;<br>
+ return;<br>
+ }<br>
+<br>
if (!Success)<br>
return;<br>
<br>
if (out_TU)<br>
*out_TU = CXTU->takeTU();<br>
<br>
- ITUI->result = 0; // success.<br>
+ ITUI->result = CXError_Success;<br>
}<br>
<br>
//===----------------------------------------------------------------------===//<br>
@@ -754,14 +765,20 @@ static void clang_indexTranslationUnit_I<br>
IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;<br>
unsigned index_callbacks_size = ITUI->index_callbacks_size;<br>
unsigned index_options = ITUI->index_options;<br>
- ITUI->result = 1; // init as error.<br>
<br>
+ // Set up the initial return value.<br>
+ ITUI->result = CXError_Failure;<br>
+<br>
+ // Check arguments.<br>
if (isNotUsableTU(TU)) {<br>
LOG_BAD_TU(TU);<br>
+ ITUI->result = CXError_InvalidArguments;<br>
return;<br>
}<br>
- if (!client_index_callbacks || index_callbacks_size == 0)<br>
+ if (!client_index_callbacks || index_callbacks_size == 0) {<br>
+ ITUI->result = CXError_InvalidArguments;<br>
return;<br>
+ }<br>
<br>
CIndexer *CXXIdx = TU->CIdx;<br>
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))<br>
@@ -809,7 +826,7 @@ static void clang_indexTranslationUnit_I<br>
indexTranslationUnit(*Unit, *IndexCtx);<br>
indexDiagnostics(TU, *IndexCtx);<br>
<br>
- ITUI->result = 0;<br>
+ ITUI->result = CXError_Success;<br>
}<br>
<br>
//===----------------------------------------------------------------------===//<br>
@@ -981,7 +998,8 @@ int clang_indexSourceFile(CXIndexAction<br>
index_callbacks_size, index_options,<br>
source_filename, command_line_args,<br>
num_command_line_args, unsaved_files,<br>
- num_unsaved_files, out_TU, TU_options, 0 };<br>
+ num_unsaved_files, out_TU, TU_options,<br>
+ CXError_Failure };<br>
<br>
if (getenv("LIBCLANG_NOTHREADS")) {<br>
clang_indexSourceFile_Impl(&ITUI);<br>
<br>
Modified: cfe/trunk/tools/libclang/libclang.exports<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=201249&r1=201248&r2=201249&view=diff" target="_blank" class="cremed">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=201249&r1=201248&r2=201249&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/tools/libclang/libclang.exports (original)<br>
+++ cfe/trunk/tools/libclang/libclang.exports Wed Feb 12 13:12:37 2014<br>
@@ -87,6 +87,7 @@ clang_constructUSR_ObjCProtocol<br>
clang_createCXCursorSet<br>
clang_createIndex<br>
clang_createTranslationUnit<br>
+clang_createTranslationUnit2<br>
clang_createTranslationUnitFromSourceFile<br>
clang_defaultCodeCompleteOptions<br>
clang_defaultDiagnosticDisplayOptions<br>
@@ -262,6 +263,7 @@ clang_loadDiagnostics<br>
clang_Location_isInSystemHeader<br>
clang_Location_isFromMainFile<br>
clang_parseTranslationUnit<br>
+clang_parseTranslationUnit2<br>
clang_remap_dispose<br>
clang_remap_getFilenames<br>
clang_remap_getNumFiles<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" class="cremed">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank" class="cremed">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>