]> granicus.if.org Git - clang/commitdiff
[libclang] Add support for querying cursor availability
authorJonathan Coe <jbcoe@me.com>
Mon, 16 Oct 2017 23:46:02 +0000 (23:46 +0000)
committerJonathan Coe <jbcoe@me.com>
Mon, 16 Oct 2017 23:46:02 +0000 (23:46 +0000)
Summary:
This patch allows checking the availability of cursors through libclang and clang.cindex (Python).
This e.g. allows to check whether a C++ member function has been marked as deleted.

Reviewers: arphaman, jbcoe

Reviewed By: jbcoe

Subscribers: cfe-commits

Tags: #clang

Patch by jklaehn (Johann Klähn)

Differential Revision: https://reviews.llvm.org/D36973

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315959 91177308-0d34-0410-b5e6-96231b3b80d8

bindings/python/clang/cindex.py
bindings/python/tests/cindex/test_cursor.py

index c236a47651dcf5bfd0827ed228f8813211b3b7e4..1dc1760e4f8804a675543dea12716e000a463422 100644 (file)
@@ -1586,6 +1586,16 @@ class Cursor(Structure):
 
         return StorageClass.from_id(self._storage_class)
 
+    @property
+    def availability(self):
+        """
+        Retrieves the availability of the entity pointed at by the cursor.
+        """
+        if not hasattr(self, '_availability'):
+            self._availability = conf.lib.clang_getCursorAvailability(self)
+
+        return AvailabilityKind.from_id(self._availability)
+
     @property
     def access_specifier(self):
         """
@@ -1923,6 +1933,24 @@ StorageClass.OPENCLWORKGROUPLOCAL = StorageClass(5)
 StorageClass.AUTO = StorageClass(6)
 StorageClass.REGISTER = StorageClass(7)
 
+### Availability Kinds ###
+
+class AvailabilityKind(BaseEnumeration):
+    """
+    Describes the availability of an entity.
+    """
+
+    # The unique kind objects, indexed by id.
+    _kinds = []
+    _name_map = None
+
+    def __repr__(self):
+        return 'AvailabilityKind.%s' % (self.name,)
+
+AvailabilityKind.AVAILABLE = AvailabilityKind(0)
+AvailabilityKind.DEPRECATED = AvailabilityKind(1)
+AvailabilityKind.NOT_AVAILABLE = AvailabilityKind(2)
+AvailabilityKind.NOT_ACCESSIBLE = AvailabilityKind(3)
 
 ### C++ access specifiers ###
 
@@ -3491,6 +3519,10 @@ functionList = [
    [TranslationUnit, SourceLocation],
    Cursor),
 
+  ("clang_getCursorAvailability",
+   [Cursor],
+   c_int),
+
   ("clang_getCursorDefinition",
    [Cursor],
    Cursor,
@@ -4106,6 +4138,7 @@ conf = Config()
 register_enumerations()
 
 __all__ = [
+    'AvailabilityKind',
     'Config',
     'CodeCompletionResults',
     'CompilationDatabase',
index 4dd42fc84bdd53ca76b47f4e7a7a2c07445f6b8c..8ff06951546edb483906c8873e0d617c6510adc0 100644 (file)
@@ -1,6 +1,7 @@
 import ctypes
 import gc
 
+from clang.cindex import AvailabilityKind
 from clang.cindex import CursorKind
 from clang.cindex import TemplateArgumentKind
 from clang.cindex import TranslationUnit
@@ -405,6 +406,30 @@ def test_result_type():
     t = foo.result_type
     assert t.kind == TypeKind.INT
 
+def test_availability():
+    tu = get_tu('class A { A(A const&) = delete; };', lang='cpp')
+
+    # AvailabilityKind.AVAILABLE
+    cursor = get_cursor(tu, 'A')
+    assert cursor.kind == CursorKind.CLASS_DECL
+    assert cursor.availability == AvailabilityKind.AVAILABLE
+
+    # AvailabilityKind.NOT_AVAILABLE
+    cursors = get_cursors(tu, 'A')
+    for c in cursors:
+        if c.kind == CursorKind.CONSTRUCTOR:
+            assert c.availability == AvailabilityKind.NOT_AVAILABLE
+            break
+    else:
+        assert False, "Could not find cursor for deleted constructor"
+
+    # AvailabilityKind.DEPRECATED
+    tu = get_tu('void test() __attribute__((deprecated));', lang='cpp')
+    cursor = get_cursor(tu, 'test')
+    assert cursor.availability == AvailabilityKind.DEPRECATED
+
+    # AvailabilityKind.NOT_ACCESSIBLE is only used in the code completion results
+
 def test_get_tokens():
     """Ensure we can map cursors back to tokens."""
     tu = get_tu('int foo(int i);')