summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-12-14 22:01:50 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-12-14 22:01:50 +0000
commit2e8732d1c668d518d3799a141051f7b8db0b5f74 (patch)
tree84e038b616b7d0485dbd1967ca072a7c2d2018e1
parentd32e8534a612dedd328b5c4546123211c97ee265 (diff)
[libclang] Add support for checking abstractness of records
This patch allows checking whether a C++ record declaration is abstract through libclang and clang.cindex (Python). Patch by Johann Klähn! Differential Revision: https://reviews.llvm.org/D36952 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@320748 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--bindings/python/clang/cindex.py20
-rw-r--r--bindings/python/tests/cindex/test_cursor.py22
-rw-r--r--include/clang-c/Index.h8
-rw-r--r--test/Index/load-classes.cpp2
-rw-r--r--tools/c-index-test/c-index-test.c2
-rw-r--r--tools/libclang/CIndex.cpp11
-rw-r--r--tools/libclang/libclang.exports1
7 files changed, 64 insertions, 2 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index d72dd14ef9..6cdb10ef08 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -1479,6 +1479,18 @@ class Cursor(Structure):
"""
return conf.lib.clang_CXXMethod_isVirtual(self)
+ def is_abstract_record(self):
+ """Returns True if the cursor refers to a C++ record declaration
+ that has pure virtual member functions.
+ """
+ return conf.lib.clang_CXXRecord_isAbstract(self)
+
+ def is_abstract_record(self):
+ """Returns True if the cursor refers to a C++ record declaration
+ that has pure virtual member functions.
+ """
+ return conf.lib.clang_CXXRecord_isAbstract(self)
+
def is_scoped_enum(self):
"""Returns True if the cursor refers to a scoped enum declaration.
"""
@@ -3401,6 +3413,14 @@ functionList = [
[Cursor],
bool),
+ ("clang_CXXRecord_isAbstract",
+ [Cursor],
+ bool),
+
+ ("clang_CXXRecord_isAbstract",
+ [Cursor],
+ bool),
+
("clang_EnumDecl_isScoped",
[Cursor],
bool),
diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py
index 41ef62757a..80f023912a 100644
--- a/bindings/python/tests/cindex/test_cursor.py
+++ b/bindings/python/tests/cindex/test_cursor.py
@@ -275,6 +275,28 @@ class TestCursor(unittest.TestCase):
self.assertTrue(foo.is_virtual_method())
self.assertFalse(bar.is_virtual_method())
+ def test_is_abstract_record(self):
+ """Ensure Cursor.is_abstract_record works."""
+ source = 'struct X { virtual void x() = 0; }; struct Y : X { void x(); };'
+ tu = get_tu(source, lang='cpp')
+
+ cls = get_cursor(tu, 'X')
+ self.assertTrue(cls.is_abstract_record())
+
+ cls = get_cursor(tu, 'Y')
+ self.assertFalse(cls.is_abstract_record())
+
+ def test_is_abstract_record(self):
+ """Ensure Cursor.is_abstract_record works."""
+ source = 'struct X { virtual void x() = 0; }; struct Y : X { void x(); };'
+ tu = get_tu(source, lang='cpp')
+
+ cls = get_cursor(tu, 'X')
+ self.assertTrue(cls.is_abstract_record())
+
+ cls = get_cursor(tu, 'Y')
+ self.assertFalse(cls.is_abstract_record())
+
def test_is_scoped_enum(self):
"""Ensure Cursor.is_scoped_enum works."""
source = 'class X {}; enum RegularEnum {}; enum class ScopedEnum {};'
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 1204d6a5d8..587008a721 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 44
+#define CINDEX_VERSION_MINOR 45
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -4467,6 +4467,12 @@ CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C);
/**
+ * \brief Determine if a C++ record is abstract, i.e. whether a class or struct
+ * has a pure virtual member function.
+ */
+CINDEX_LINKAGE unsigned clang_CXXRecord_isAbstract(CXCursor C);
+
+/**
* \brief Determine if an enum declaration refers to a scoped enum.
*/
CINDEX_LINKAGE unsigned clang_EnumDecl_isScoped(CXCursor C);
diff --git a/test/Index/load-classes.cpp b/test/Index/load-classes.cpp
index 8b1ed317e3..b6c25b4f75 100644
--- a/test/Index/load-classes.cpp
+++ b/test/Index/load-classes.cpp
@@ -29,7 +29,7 @@ X::X(int value) {
}
// RUN: c-index-test -test-load-source all %s | FileCheck %s
-// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 26:2]
+// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) (abstract) Extent=[3:1 - 26:2]
// CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 (converting constructor) Extent=[4:3 - 4:15] [access=public]
// FIXME: missing TypeRef in the constructor name
// CHECK: load-classes.cpp:4:9: ParmDecl=value:4:9 (Definition) Extent=[4:5 - 4:14]
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 91afbe219a..99f05669b6 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -804,6 +804,8 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
printf(" (const)");
if (clang_CXXMethod_isPureVirtual(Cursor))
printf(" (pure)");
+ if (clang_CXXRecord_isAbstract(Cursor))
+ printf(" (abstract)");
if (clang_EnumDecl_isScoped(Cursor))
printf(" (scoped)");
if (clang_Cursor_isVariadic(Cursor))
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 656df9b09b..f4d347108c 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -7919,6 +7919,17 @@ unsigned clang_CXXMethod_isVirtual(CXCursor C) {
return (Method && Method->isVirtual()) ? 1 : 0;
}
+unsigned clang_CXXRecord_isAbstract(CXCursor C) {
+ if (!clang_isDeclaration(C.kind))
+ return 0;
+
+ const auto *D = cxcursor::getCursorDecl(C);
+ const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
+ if (RD)
+ RD = RD->getDefinition();
+ return (RD && RD->isAbstract()) ? 1 : 0;
+}
+
unsigned clang_EnumDecl_isScoped(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index bd262ee1a0..4d3a029567 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -13,6 +13,7 @@ clang_CXXMethod_isConst
clang_CXXMethod_isPureVirtual
clang_CXXMethod_isStatic
clang_CXXMethod_isVirtual
+clang_CXXRecord_isAbstract
clang_EnumDecl_isScoped
clang_Cursor_getArgument
clang_Cursor_getNumTemplateArguments