diff options
author | Jonathan Coe <jbcoe@me.com> | 2017-06-27 22:54:56 +0000 |
---|---|---|
committer | Jonathan Coe <jbcoe@me.com> | 2017-06-27 22:54:56 +0000 |
commit | 34efc84dff3e2cb91e6afdf460a7893a4a886029 (patch) | |
tree | 8e9b74edbd34bfca8650e42434927043d872044d /bindings | |
parent | 563c0ec65e052e93085d4e3b7fede21da5ea768f (diff) |
[libclang] Support for querying the exception specification type through libclang
Summary: This patch exposes the exception specification type (noexcept,
etc.) of a C++ function through libclang and Python clang.cindex.
Reviewers: rsmith, aaron.ballman
Reviewed By: aaron.ballman
Subscribers: jbcoe, cfe-commits
Differential Revision: https://reviews.llvm.org/D34091
Patch by Andrew Bennieston
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306483 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'bindings')
-rw-r--r-- | bindings/python/clang/cindex.py | 44 | ||||
-rw-r--r-- | bindings/python/tests/test_exception_specification_kind.py | 27 |
2 files changed, 71 insertions, 0 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index 8440b0aabe..5e70bde770 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -1367,6 +1367,30 @@ TemplateArgumentKind.DECLARATION = TemplateArgumentKind(2) TemplateArgumentKind.NULLPTR = TemplateArgumentKind(3) TemplateArgumentKind.INTEGRAL = TemplateArgumentKind(4) +### Exception Specification Kinds ### +class ExceptionSpecificationKind(BaseEnumeration): + """ + An ExceptionSpecificationKind describes the kind of exception specification + that a function has. + """ + + # The required BaseEnumeration declarations. + _kinds = [] + _name_map = None + + def __repr__(self): + return 'ExceptionSpecificationKind.{}'.format(self.name) + +ExceptionSpecificationKind.NONE = ExceptionSpecificationKind(0) +ExceptionSpecificationKind.DYNAMIC_NONE = ExceptionSpecificationKind(1) +ExceptionSpecificationKind.DYNAMIC = ExceptionSpecificationKind(2) +ExceptionSpecificationKind.MS_ANY = ExceptionSpecificationKind(3) +ExceptionSpecificationKind.BASIC_NOEXCEPT = ExceptionSpecificationKind(4) +ExceptionSpecificationKind.COMPUTED_NOEXCEPT = ExceptionSpecificationKind(5) +ExceptionSpecificationKind.UNEVALUATED = ExceptionSpecificationKind(6) +ExceptionSpecificationKind.UNINSTANTIATED = ExceptionSpecificationKind(7) +ExceptionSpecificationKind.UNPARSED = ExceptionSpecificationKind(8) + ### Cursors ### class Cursor(Structure): @@ -1587,6 +1611,18 @@ class Cursor(Structure): return self._result_type @property + def exception_specification_kind(self): + ''' + Retrieve the exception specification kind, which is one of the values + from the ExceptionSpecificationKind enumeration. + ''' + if not hasattr(self, '_exception_specification_kind'): + exc_kind = conf.lib.clang_getCursorExceptionSpecificationType(self) + self._exception_specification_kind = ExceptionSpecificationKind.from_id(exc_kind) + + return self._exception_specification_kind + + @property def underlying_typedef_type(self): """Return the underlying type of a typedef declaration. @@ -2254,6 +2290,14 @@ class Type(Structure): callbacks['fields_visit'](visitor), fields) return iter(fields) + def get_exception_specification_kind(self): + """ + Return the kind of the exception specification; a value from + the ExceptionSpecificationKind enumeration. + """ + return ExceptionSpecificationKind.from_id( + conf.lib.clang.getExceptionSpecificationType(self)) + @property def spelling(self): """Retrieve the spelling of this Type.""" diff --git a/bindings/python/tests/test_exception_specification_kind.py b/bindings/python/tests/test_exception_specification_kind.py new file mode 100644 index 0000000000..543d47f7db --- /dev/null +++ b/bindings/python/tests/test_exception_specification_kind.py @@ -0,0 +1,27 @@ +import clang.cindex +from clang.cindex import ExceptionSpecificationKind +from .util import get_tu + + +def find_function_declarations(node, declarations=[]): + if node.kind == clang.cindex.CursorKind.FUNCTION_DECL: + declarations.append((node.spelling, node.exception_specification_kind)) + for child in node.get_children(): + declarations = find_function_declarations(child, declarations) + return declarations + + +def test_exception_specification_kind(): + source = """int square1(int x); + int square2(int x) noexcept; + int square3(int x) noexcept(noexcept(x * x));""" + + tu = get_tu(source, lang='cpp', flags=['-std=c++14']) + + declarations = find_function_declarations(tu.cursor) + expected = [ + ('square1', ExceptionSpecificationKind.NONE), + ('square2', ExceptionSpecificationKind.BASIC_NOEXCEPT), + ('square3', ExceptionSpecificationKind.COMPUTED_NOEXCEPT) + ] + assert declarations == expected |