summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bindings/python/clang/cindex.py10
-rw-r--r--bindings/python/tests/cindex/test_cursor.py15
-rw-r--r--include/clang-c/Index.h5
-rw-r--r--test/Index/index-file.cpp6
-rw-r--r--tools/c-index-test/c-index-test.c2
-rw-r--r--tools/libclang/CIndex.cpp10
-rw-r--r--tools/libclang/libclang.exports1
7 files changed, 49 insertions, 0 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 62b8596dea..49b2fd873f 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -1170,6 +1170,12 @@ class Cursor(Structure):
"""
return conf.lib.clang_CXXMethod_isConst(self)
+ def is_mutable_field(self):
+ """Returns True if the cursor refers to a C++ field that is declared
+ 'mutable'.
+ """
+ return conf.lib.clang_CXXField_isMutable(self)
+
def is_pure_virtual_method(self):
"""Returns True if the cursor refers to a C++ member function or member
function template that is declared pure virtual.
@@ -2897,6 +2903,10 @@ functionList = [
[Index, c_char_p],
c_object_p),
+ ("clang_CXXField_isMutable",
+ [Cursor],
+ bool),
+
("clang_CXXMethod_isConst",
[Cursor],
bool),
diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py
index 68fc8fa4ac..c5ea50516a 100644
--- a/bindings/python/tests/cindex/test_cursor.py
+++ b/bindings/python/tests/cindex/test_cursor.py
@@ -112,6 +112,21 @@ def test_is_const_method():
assert foo.is_const_method()
assert not bar.is_const_method()
+def test_is_mutable_field():
+ """Ensure Cursor.is_mutable_field works."""
+ source = 'class X { int x_; mutable int y_; };'
+ tu = get_tu(source, lang='cpp')
+
+ cls = get_cursor(tu, 'X')
+ x_ = get_cursor(tu, 'x_')
+ y_ = get_cursor(tu, 'y_')
+ assert cls is not None
+ assert x_ is not None
+ assert y_ is not None
+
+ assert not x_.is_mutable_field()
+ assert y_.is_mutable_field()
+
def test_is_static_method():
"""Ensure Cursor.is_static_method works."""
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index af5b93c733..cd5eb4e4d2 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -3957,6 +3957,11 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit,
*/
/**
+ * \brief Determine if a C++ field is declared 'mutable'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXField_isMutable(CXCursor C);
+
+/**
* \brief Determine if a C++ member function or member function template is
* pure virtual.
*/
diff --git a/test/Index/index-file.cpp b/test/Index/index-file.cpp
index d42b4b2de7..f1ae68a250 100644
--- a/test/Index/index-file.cpp
+++ b/test/Index/index-file.cpp
@@ -24,6 +24,10 @@ template <> void A<int>::meth();
template class A<int>;
}
+class B {
+ mutable int x_;
+ int y_;
+};
// RUN: c-index-test -index-file %s > %t
// RUN: FileCheck %s -input-file=%t
@@ -31,3 +35,5 @@ template class A<int>;
// CHECK: [indexDeclaration]: kind: struct-template-spec | name: TS | {{.*}} | loc: 11:8
// CHECK: [indexDeclaration]: kind: function-template-spec | name: tfoo | {{.*}} | loc: 15:6
// CHECK: [indexDeclaration]: kind: c++-instance-method | name: meth | {{.*}} | loc: 23:26
+// CHECK: [indexDeclaration]: kind: field | name: x_ | USR: c:@S@B@FI@x_ | lang: C++ | cursor: FieldDecl=x_:28:15 (Definition) (mutable) | loc: 28:15 | semantic-container: [B:27:7] | lexical-container: [B:27:7] | isRedecl: 0 | isDef: 1 | isContainer: 0 | isImplicit: 0
+// CHECK: [indexDeclaration]: kind: field | name: y_ | USR: c:@S@B@FI@y_ | lang: C++ | cursor: FieldDecl=y_:29:7 (Definition) | loc: 29:7 | semantic-container: [B:27:7] | lexical-container: [B:27:7] | isRedecl: 0 | isDef: 1 | isContainer: 0 | isImplicit: 0
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 7155d8c780..26ef5f204b 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -767,6 +767,8 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
clang_disposeString(DeprecatedMessage);
clang_disposeString(UnavailableMessage);
+ if (clang_CXXField_isMutable(Cursor))
+ printf(" (mutable)");
if (clang_CXXMethod_isStatic(Cursor))
printf(" (static)");
if (clang_CXXMethod_isVirtual(Cursor))
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 96923dc7de..be53b82274 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -6888,6 +6888,16 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
//===----------------------------------------------------------------------===//
extern "C" {
+unsigned clang_CXXField_isMutable(CXCursor C) {
+ if (!clang_isDeclaration(C.kind))
+ return 0;
+
+ if (const auto D = cxcursor::getCursorDecl(C))
+ if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
+ return FD->isMutable() ? 1 : 0;
+ return 0;
+}
+
unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 5179b96fc6..fd157bc495 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -2,6 +2,7 @@ clang_CXCursorSet_contains
clang_CXCursorSet_insert
clang_CXIndex_getGlobalOptions
clang_CXIndex_setGlobalOptions
+clang_CXXField_isMutable
clang_CXXMethod_isConst
clang_CXXMethod_isPureVirtual
clang_CXXMethod_isStatic