libclang: Allow callers of clang_saveTranslationUnit() to distinguish
between different classes of errors. Addresses most of
<rdar://problem/9660328>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134495 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 01e7bce..5bf2031 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -933,6 +933,41 @@
CINDEX_LINKAGE unsigned clang_defaultSaveOptions(CXTranslationUnit TU);
/**
+ * \brief Describes the kind of error that occurred (if any) in a call to
+ * \c clang_saveTranslationUnit().
+ */
+enum CXSaveError {
+ /**
+ * \brief Indicates that no error occurred while saving a translation unit.
+ */
+ CXSaveError_None = 0,
+
+ /**
+ * \brief Indicates that an unknown error occurred while attempting to save
+ * the file.
+ *
+ * This error typically indicates that file I/O failed when attempting to
+ * write the file.
+ */
+ CXSaveError_Unknown = 1,
+
+ /**
+ * \brief Indicates that errors during translation prevented this attempt
+ * to save the translation unit.
+ *
+ * Errors that prevent the translation unit from being saved can be
+ * extracted using \c clang_getNumDiagnostics() and \c clang_getDiagnostic().
+ */
+ CXSaveError_TranslationErrors = 2,
+
+ /**
+ * \brief Indicates that the translation unit to be saved was somehow
+ * invalid (e.g., NULL).
+ */
+ CXSaveError_InvalidTU = 3
+};
+
+/**
* \brief Saves a translation unit into a serialized representation of
* that translation unit on disk.
*
@@ -951,8 +986,9 @@
* is saved. This should be a bitwise OR of the
* CXSaveTranslationUnit_XXX flags.
*
- * \returns Zero if the translation unit was saved successfully, a
- * non-zero value otherwise.
+ * \returns A value that will match one of the enumerators of the CXSaveError
+ * enumeration. Zero (CXSaveError_None) indicates that the translation unit was
+ * saved successfully, while a non-zero value indicates that a problem occurred.
*/
CINDEX_LINKAGE int clang_saveTranslationUnit(CXTranslationUnit TU,
const char *FileName,
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index b441995..b475880 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -680,8 +680,8 @@
/// \brief Save this translation unit to a file with the given name.
///
- /// \returns True if an error occurred, false otherwise.
- bool Save(llvm::StringRef File);
+ /// \returns An indication of whether the save was successful or not.
+ CXSaveError Save(llvm::StringRef File);
/// \brief Serialize this translation unit with the given output stream.
///
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 86a9a35..8f61d6a 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -2287,9 +2287,9 @@
}
}
-bool ASTUnit::Save(llvm::StringRef File) {
+CXSaveError ASTUnit::Save(llvm::StringRef File) {
if (getDiagnostics().hasErrorOccurred())
- return true;
+ return CXSaveError_TranslationErrors;
// FIXME: Can we somehow regenerate the stat cache here, or do we need to
// unconditionally create a stat cache when we parse the file?
@@ -2297,11 +2297,11 @@
llvm::raw_fd_ostream Out(File.str().c_str(), ErrorInfo,
llvm::raw_fd_ostream::F_Binary);
if (!ErrorInfo.empty() || Out.has_error())
- return true;
+ return CXSaveError_Unknown;
serialize(Out);
Out.close();
- return Out.has_error();
+ return Out.has_error()? CXSaveError_Unknown : CXSaveError_None;
}
bool ASTUnit::serialize(llvm::raw_ostream &OS) {
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 837fc89..d1bdf96 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1517,12 +1517,36 @@
return 1;
}
- if (clang_saveTranslationUnit(TU, filename, clang_defaultSaveOptions(TU)))
- fprintf(stderr, "Unable to write PCH file %s\n", filename);
+ int result = 0;
+
+ switch (clang_saveTranslationUnit(TU, filename,
+ clang_defaultSaveOptions(TU))) {
+ case CXSaveError_None:
+ break;
+
+ case CXSaveError_TranslationErrors:
+ fprintf(stderr, "Unable to write PCH file %s: translation errors\n",
+ filename);
+ result = 2;
+ break;
+
+ case CXSaveError_InvalidTU:
+ fprintf(stderr, "Unable to write PCH file %s: invalid translation unit\n",
+ filename);
+ result = 3;
+ break;
+
+ case CXSaveError_Unknown:
+ default:
+ fprintf(stderr, "Unable to write PCH file %s: unknown error \n", filename);
+ result = 1;
+ break;
+ }
+
clang_disposeTranslationUnit(TU);
free_remapped_files(unsaved_files, num_unsaved_files);
clang_disposeIndex(Idx);
- return 0;
+ return result;
}
/******************************************************************************/
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index fc331d0..b75850d 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -2594,9 +2594,9 @@
int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
unsigned options) {
if (!TU)
- return 1;
+ return CXSaveError_InvalidTU;
- int result = static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
+ CXSaveError result = static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
if (getenv("LIBCLANG_RESOURCE_USAGE"))
PrintLibclangResourceUsage(TU);
return result;