Skip to content

[libclang/python] Improve error reporting of TranslationUnit creating functions #102410

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 62 additions & 13 deletions clang/bindings/python/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,36 @@ class TranslationUnitLoadError(Exception):

This is raised in the case where a TranslationUnit could not be
instantiated due to failure in the libclang library.

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, 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
)

self.error_code = enumeration
Exception.__init__(self, "Error %d: %s" % (enumeration, message))


class TranslationUnitSaveError(Exception):
Expand Down Expand Up @@ -617,7 +642,6 @@ class BaseEnumeration(Enum):
Common base class for named enumerations held in sync with Index.h values.
"""


def from_param(self):
return self.value

Expand Down Expand Up @@ -693,7 +717,6 @@ def is_unexposed(self):
"""Test if this is an unexposed kind."""
return conf.lib.clang_isUnexposed(self) # type: ignore [no-any-return]


###
# Declaration Kinds

Expand Down Expand Up @@ -820,7 +843,6 @@ def is_unexposed(self):
# A C++ access specifier decl.
CXX_ACCESS_SPEC_DECL = 39


###
# Reference Kinds

Expand Down Expand Up @@ -3083,18 +3105,20 @@ 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,
len(args),
unsaved_array,
len(unsaved_files),
options,
byref(ptr),
)

if not ptr:
raise TranslationUnitLoadError("Error parsing translation unit.")
if errc != 0:
raise TranslationUnitLoadError(errc, "Error parsing translation unit.")

return cls(ptr, index=index)

Expand All @@ -3116,9 +3140,13 @@ 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:
raise TranslationUnitLoadError(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)

Expand Down Expand Up @@ -3263,9 +3291,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(
errc = conf.lib.clang_reparseTranslationUnit(
self, len(unsaved_files), unsaved_files_array, options
)
if errc != 0:
raise TranslationUnitLoadError(errc, "Error reparsing TranslationUnit.")

def save(self, filename):
"""Saves the TranslationUnit to a file.
Expand Down Expand Up @@ -3719,6 +3749,11 @@ 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]),
Expand Down Expand Up @@ -3913,6 +3948,20 @@ 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),
(
Expand Down
9 changes: 6 additions & 3 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,13 @@ Clang Frontend Potentially Breaking Changes
Clang Python Bindings Potentially Breaking Changes
--------------------------------------------------
- Parts of the interface returning string results will now return
the empty string `""` when no result is available, instead of `None`.
- Calling a property on the `CompletionChunk` or `CompletionString` class
statically now leads to an error, instead of returning a `CachedProperty` object
the empty string ``""`` when no result is available, instead of ``None``.
- 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 error code in ``error_code``
attribute. Also, ``TranslationUnit.reparse`` will throw ``TranslationUnitLoadError``
when operation fails.

What's New in Clang |release|?
==============================
Expand Down
Loading