libclang: Allow callers of clang_saveTranslationUnit() to distinguish

between different classes of errors. Addresses most of
<rdar://problem/9660328>.

llvm-svn: 134495
This commit is contained in:
Douglas Gregor 2011-07-06 16:43:36 +00:00
parent b4836ea7a8
commit 30c80fa3eb
5 changed files with 73 additions and 13 deletions

View File

@ -932,6 +932,41 @@ enum CXSaveTranslationUnit_Flags {
*/
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 @@ CINDEX_LINKAGE unsigned clang_defaultSaveOptions(CXTranslationUnit TU);
* 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,

View File

@ -680,8 +680,8 @@ public:
/// \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.
///

View File

@ -2287,9 +2287,9 @@ void ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column,
}
}
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 @@ bool ASTUnit::Save(llvm::StringRef File) {
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) {

View File

@ -1517,12 +1517,36 @@ int write_pch_file(const char *filename, int argc, const char *argv[]) {
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;
}
/******************************************************************************/

View File

@ -2594,9 +2594,9 @@ unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
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;