https://github.com/TsXor updated https://github.com/llvm/llvm-project/pull/102410
>From 4858eef099dbca66b2e3d36fc17aef574c1f3d58 Mon Sep 17 00:00:00 2001 From: TsXor <zhang050...@outlook.com> Date: Thu, 8 Aug 2024 09:25:52 +0800 Subject: [PATCH 1/2] fix error handling of TranslationUnit.reparse --- clang/bindings/python/clang/cindex.py | 42 +++++++++++++++++++++++---- clang/docs/ReleaseNotes.rst | 3 ++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 2038ef6045c7df..e4591828f91968 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -149,8 +149,8 @@ def b(x: str | bytes) -> bytes: # this by marshalling object arguments as void**. c_object_p: TType[_Pointer[Any]] = POINTER(c_void_p) -### Exception Classes ### +### Exception Classes ### class TranslationUnitLoadError(Exception): """Represents an error that occurred when loading a TranslationUnit. @@ -161,7 +161,35 @@ class TranslationUnitLoadError(Exception): FIXME: Make libclang expose additional error information in this scenario. """ - pass + # A generic error code, no further details are available. + # + # Errors of this kind can get their own specific error codes in future + # libclang versions. + ERROR_FAILURE = 1 + + # libclang crashed while performing the requested operation. + ERROR_CRASHED = 2 + + # The function detected that the arguments violate the function + # contract. + ERROR_INVALID_ARGUMENTS = 3 + + # An AST deserialization error has occurred. + ERROR_AST_READ_ERROR = 4 + + def __init__(self, enumeration: int | None, message: str): + if enumeration is not None: + assert isinstance(enumeration, int) + + if enumeration < 1 or enumeration > 4: + raise Exception( + "Encountered undefined CXError " + "constant: %d. Please file a bug to have this " + "value supported." % enumeration + ) + + self.error_code = enumeration + Exception.__init__(self, "Error %d: %s" % (enumeration or 0, message)) class TranslationUnitSaveError(Exception): @@ -3094,7 +3122,8 @@ def from_source( ) if not ptr: - raise TranslationUnitLoadError("Error parsing translation unit.") + # FIXME: use clang_parseTranslationUnit2 to preserve error code + raise TranslationUnitLoadError(None, "Error parsing translation unit.") return cls(ptr, index=index) @@ -3118,7 +3147,8 @@ def from_ast_file(cls, filename, index=None): ptr = conf.lib.clang_createTranslationUnit(index, os.fspath(filename)) if not ptr: - raise TranslationUnitLoadError(filename) + # FIXME: use clang_createTranslationUnit2 to preserve error code + raise TranslationUnitLoadError(None, filename) return cls(ptr=ptr, index=index) @@ -3263,9 +3293,11 @@ def reparse(self, unsaved_files=None, options=0): unsaved_files = [] unsaved_files_array = self.process_unsaved_files(unsaved_files) - ptr = conf.lib.clang_reparseTranslationUnit( + result = conf.lib.clang_reparseTranslationUnit( self, len(unsaved_files), unsaved_files_array, options ) + if result != 0: + raise TranslationUnitLoadError(result, 'Error reparsing TranslationUnit.') def save(self, filename): """Saves the TranslationUnit to a file. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ba70b138a04c4a..33a8c493e5e998 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -59,6 +59,9 @@ Clang Python Bindings Potentially Breaking Changes - Calling a property on the `CompletionChunk` or `CompletionString` class statically now leads to an error, instead of returning a `CachedProperty` object that is used internally. Properties are only available on instances. +- `TranslationUnitLoadError` now contains an optional error code in `error_code` + attribute. Also, `TranslationUnit.reparse` will throw `TranslationUnitLoadError` + when operation fails. What's New in Clang |release|? ============================== >From c168a55356d94ffcccbd960b189b5b15feb272cb Mon Sep 17 00:00:00 2001 From: TsXor <zhang050...@outlook.com> Date: Sat, 10 Aug 2024 19:20:56 +0800 Subject: [PATCH 2/2] preserve error code in TU parsing APIs --- clang/bindings/python/clang/cindex.py | 51 ++++++++++++++++----------- clang/docs/ReleaseNotes.rst | 2 +- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index e4591828f91968..63d23f55a5a742 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -177,16 +177,15 @@ class TranslationUnitLoadError(Exception): # An AST deserialization error has occurred. ERROR_AST_READ_ERROR = 4 - def __init__(self, enumeration: int | None, message: str): - if enumeration is not None: - assert isinstance(enumeration, int) + def __init__(self, enumeration: int, message: str): + assert isinstance(enumeration, int) - if enumeration < 1 or enumeration > 4: - raise Exception( - "Encountered undefined CXError " - "constant: %d. Please file a bug to have this " - "value supported." % enumeration - ) + if enumeration < 1 or enumeration > 4: + raise Exception( + "Encountered undefined CXError " + "constant: %d. Please file a bug to have this " + "value supported." % enumeration + ) self.error_code = enumeration Exception.__init__(self, "Error %d: %s" % (enumeration or 0, message)) @@ -3111,7 +3110,8 @@ def from_source( unsaved_array = cls.process_unsaved_files(unsaved_files) - ptr = conf.lib.clang_parseTranslationUnit( + ptr = c_object_p() + errc = conf.lib.clang_parseTranslationUnit2( index, os.fspath(filename) if filename is not None else None, args_array, @@ -3119,11 +3119,11 @@ def from_source( unsaved_array, len(unsaved_files), options, + byref(ptr), ) - if not ptr: - # FIXME: use clang_parseTranslationUnit2 to preserve error code - raise TranslationUnitLoadError(None, "Error parsing translation unit.") + if errc != 0: + raise TranslationUnitLoadError(errc, "Error parsing translation unit.") return cls(ptr, index=index) @@ -3145,10 +3145,15 @@ def from_ast_file(cls, filename, index=None): if index is None: index = Index.create() - ptr = conf.lib.clang_createTranslationUnit(index, os.fspath(filename)) - if not ptr: - # FIXME: use clang_createTranslationUnit2 to preserve error code - raise TranslationUnitLoadError(None, filename) + ptr = c_object_p() + errc = conf.lib.clang_createTranslationUnit2( + index, + os.fspath(filename), + byref(ptr) + ) + + if errc != 0: + raise TranslationUnitLoadError(errc, filename) return cls(ptr=ptr, index=index) @@ -3293,11 +3298,11 @@ def reparse(self, unsaved_files=None, options=0): unsaved_files = [] unsaved_files_array = self.process_unsaved_files(unsaved_files) - result = conf.lib.clang_reparseTranslationUnit( + errc = conf.lib.clang_reparseTranslationUnit( self, len(unsaved_files), unsaved_files_array, options ) - if result != 0: - raise TranslationUnitLoadError(result, 'Error reparsing TranslationUnit.') + if errc != 0: + raise TranslationUnitLoadError(errc, 'Error reparsing TranslationUnit.') def save(self, filename): """Saves the TranslationUnit to a file. @@ -3751,6 +3756,7 @@ def write_main_file_to_stdout(self): ("clang_codeCompleteGetNumDiagnostics", [CodeCompletionResults], c_int), ("clang_createIndex", [c_int, c_int], c_object_p), ("clang_createTranslationUnit", [Index, c_interop_string], c_object_p), + ("clang_createTranslationUnit2", [Index, c_interop_string, POINTER(c_object_p)], c_int), ("clang_CXRewriter_create", [TranslationUnit], c_object_p), ("clang_CXRewriter_dispose", [Rewriter]), ("clang_CXRewriter_insertTextBefore", [Rewriter, SourceLocation, c_interop_string]), @@ -3945,6 +3951,11 @@ def write_main_file_to_stdout(self): [Index, c_interop_string, c_void_p, c_int, c_void_p, c_int, c_int], c_object_p, ), + ( + "clang_parseTranslationUnit2", + [Index, c_interop_string, c_void_p, c_int, c_void_p, c_int, c_int, POINTER(c_object_p)], + c_int, + ), ("clang_reparseTranslationUnit", [TranslationUnit, c_int, c_void_p, c_int], c_int), ("clang_saveTranslationUnit", [TranslationUnit, c_interop_string, c_uint], c_int), ( diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 33a8c493e5e998..1f42fc732fd292 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -59,7 +59,7 @@ Clang Python Bindings Potentially Breaking Changes - Calling a property on the `CompletionChunk` or `CompletionString` class statically now leads to an error, instead of returning a `CachedProperty` object that is used internally. Properties are only available on instances. -- `TranslationUnitLoadError` now contains an optional error code in `error_code` +- `TranslationUnitLoadError` now contains an error code in `error_code` attribute. Also, `TranslationUnit.reparse` will throw `TranslationUnitLoadError` when operation fails. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits