mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-05 00:49:43 +00:00
[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 llvm-svn: 320748
This commit is contained in:
parent
5b0c3ad564
commit
34ccadcea9
@ -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),
|
||||
|
@ -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 {};'
|
||||
|
@ -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) \
|
||||
@ -4466,6 +4466,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.
|
||||
*/
|
||||
|
@ -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]
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user