Skip to content

Commit e570ede

Browse files
committedApr 7, 2014
libclang: add clang_CXXMethod_isConst API that allows to determine if a C++
member function or member function template is declared 'const' Patch by Kevin Funk with testcase updates by me. llvm-svn: 205714
1 parent 4841827 commit e570ede

File tree

6 files changed

+54
-13
lines changed

6 files changed

+54
-13
lines changed
 

‎clang/include/clang-c/Index.h

+6
Original file line numberDiff line numberDiff line change
@@ -4192,6 +4192,12 @@ CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
41924192
*/
41934193
CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C);
41944194

4195+
/**
4196+
* \brief Determine if a C++ member function or member function template is
4197+
* declared 'const'.
4198+
*/
4199+
CINDEX_LINKAGE unsigned clang_CXXMethod_isConst(CXCursor C);
4200+
41954201
/**
41964202
* \brief Given a cursor that represents a template, determine
41974203
* the cursor kind of the specializations would be generated by instantiating

‎clang/test/Index/load-classes.cpp

+26-4
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,46 @@ struct X {
77
~X();
88
private:
99
operator X*();
10+
11+
void constMemberFunction() const;
12+
template<typename T>
13+
void constMemberFunctionTemplate() const;
14+
15+
static void staticMemberFunction();
16+
template<typename T>
17+
static void staticMemberFunctionTemplate();
18+
19+
virtual void virtualMemberFunction();
20+
virtual void pureVirtualMemberFunction() = 0;
1021
};
1122

1223
X::X(int value) {
1324
}
1425

1526
// RUN: c-index-test -test-load-source all %s | FileCheck %s
16-
// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 10:2]
27+
// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 21:2]
1728
// CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 Extent=[4:3 - 4:15] [access=public]
1829
// FIXME: missing TypeRef in the constructor name
1930
// CHECK: load-classes.cpp:4:9: ParmDecl=value:4:9 (Definition) Extent=[4:5 - 4:14]
2031
// CHECK: load-classes.cpp:5:3: CXXConstructor=X:5:3 Extent=[5:3 - 5:16] [access=public]
2132
// FIXME: missing TypeRef in the constructor name
2233
// CHECK: load-classes.cpp:5:14: ParmDecl=x:5:14 (Definition) Extent=[5:5 - 5:15]
2334
// CHECK: load-classes.cpp:5:11: TypeRef=struct X:3:8 Extent=[5:11 - 5:12]
35+
// CHECK: load-classes.cpp:6:1: CXXAccessSpecifier=:6:1 (Definition) Extent=[6:1 - 6:11] [access=protected]
2436
// CHECK: load-classes.cpp:7:3: CXXDestructor=~X:7:3 Extent=[7:3 - 7:7] [access=protected]
2537
// FIXME: missing TypeRef in the destructor name
38+
// CHECK: load-classes.cpp:8:1: CXXAccessSpecifier=:8:1 (Definition) Extent=[8:1 - 8:9] [access=private]
2639
// CHECK: load-classes.cpp:9:3: CXXConversion=operator X *:9:3 Extent=[9:3 - 9:16] [access=private]
2740
// CHECK: load-classes.cpp:9:12: TypeRef=struct X:3:8 Extent=[9:12 - 9:13]
28-
// CHECK: load-classes.cpp:12:4: CXXConstructor=X:12:4 (Definition) Extent=[12:1 - 13:2] [access=public]
29-
// CHECK: load-classes.cpp:12:1: TypeRef=struct X:3:8 Extent=[12:1 - 12:2]
30-
// CHECK: load-classes.cpp:12:10: ParmDecl=value:12:10 (Definition) Extent=[12:6 - 12:15]
41+
// CHECK: load-classes.cpp:11:8: CXXMethod=constMemberFunction:11:8 (const) Extent=[11:3 - 11:35] [access=private]
42+
// CHECK: load-classes.cpp:13:8: FunctionTemplate=constMemberFunctionTemplate:13:8 (const) Extent=[12:3 - 13:43] [access=private]
43+
// CHECK: load-classes.cpp:12:21: TemplateTypeParameter=T:12:21 (Definition) Extent=[12:12 - 12:22] [access=public]
44+
// CHECK: load-classes.cpp:15:15: CXXMethod=staticMemberFunction:15:15 (static) Extent=[15:3 - 15:37] [access=private]
45+
// CHECK: load-classes.cpp:17:15: FunctionTemplate=staticMemberFunctionTemplate:17:15 (static) Extent=[16:3 - 17:45] [access=private]
46+
// CHECK: load-classes.cpp:16:21: TemplateTypeParameter=T:16:21 (Definition) Extent=[16:12 - 16:22] [access=public]
47+
// CHECK: load-classes.cpp:19:16: CXXMethod=virtualMemberFunction:19:16 (virtual) Extent=[19:3 - 19:39] [access=private]
48+
// CHECK: load-classes.cpp:20:16: CXXMethod=pureVirtualMemberFunction:20:16 (virtual) (pure) Extent=[20:3 - 20:47] [access=private]
49+
// CHECK: load-classes.cpp:23:4: CXXConstructor=X:23:4 (Definition) Extent=[23:1 - 24:2] [access=public]
50+
// CHECK: load-classes.cpp:23:1: TypeRef=struct X:3:8 Extent=[23:1 - 23:2]
51+
// CHECK: load-classes.cpp:23:10: ParmDecl=value:23:10 (Definition) Extent=[23:6 - 23:15]
52+
// CHECK: load-classes.cpp:23:17: CompoundStmt= Extent=[23:17 - 24:2]

‎clang/test/Index/recursive-cxx-member-calls.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -1680,17 +1680,17 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
16801680
// CHECK: 49:60: MemberRef=Length:44:10 Extent=[49:60 - 49:66]
16811681
// CHECK: 49:67: DeclRefExpr=length:49:38 Extent=[49:67 - 49:73]
16821682
// CHECK: 49:75: CompoundStmt= Extent=[49:75 - 49:77]
1683-
// CHECK: 50:12: CXXMethod=end:50:12 (Definition) Extent=[50:3 - 50:40]
1683+
// CHECK: 50:12: CXXMethod=end:50:12 (Definition) (const) Extent=[50:3 - 50:40] [access=public]
16841684
// CHECK: 50:3: TypeRef=iterator:40:23 Extent=[50:3 - 50:11]
16851685
// CHECK: 50:24: CompoundStmt= Extent=[50:24 - 50:40]
16861686
// CHECK: 50:26: ReturnStmt= Extent=[50:26 - 50:37]
16871687
// CHECK: 50:33: MemberRefExpr=Data:43:15 Extent=[50:33 - 50:37]
1688-
// CHECK: 51:10: CXXMethod=size:51:10 (Definition) Extent=[51:3 - 51:41]
1688+
// CHECK: 51:10: CXXMethod=size:51:10 (Definition) (const) Extent=[51:3 - 51:41] [access=public]
16891689
// CHECK: 51:3: TypeRef=size_t:2:25 Extent=[51:3 - 51:9]
16901690
// CHECK: 51:23: CompoundStmt= Extent=[51:23 - 51:41]
16911691
// CHECK: 51:25: ReturnStmt= Extent=[51:25 - 51:38]
16921692
// CHECK: 51:32: MemberRefExpr=Length:44:10 Extent=[51:32 - 51:38]
1693-
// CHECK: 52:8: CXXMethod=startswith:52:8 (Definition) Extent=[52:3 - 55:4]
1693+
// CHECK: 52:8: CXXMethod=startswith:52:8 (Definition) (const) Extent=[52:3 - 55:4] [access=public]
16941694
// CHECK: 52:29: ParmDecl=Prefix:52:29 (Definition) Extent=[52:19 - 52:35]
16951695
// CHECK: 52:19: TypeRef=class llvm::StringRef:38:7 Extent=[52:19 - 52:28]
16961696
// CHECK: 52:43: CompoundStmt= Extent=[52:43 - 55:4]
@@ -1713,7 +1713,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
17131713
// CHECK: 54:44: MemberRefExpr=Length:44:10 SingleRefName=[54:44 - 54:50] RefName=[54:44 - 54:50] Extent=[54:37 - 54:50]
17141714
// CHECK: 54:37: DeclRefExpr=Prefix:52:29 Extent=[54:37 - 54:43]
17151715
// CHECK: 54:55: IntegerLiteral= Extent=[54:55 - 54:56]
1716-
// CHECK: 56:8: CXXMethod=endswith:56:8 (Definition) Extent=[56:3 - 59:4]
1716+
// CHECK: 56:8: CXXMethod=endswith:56:8 (Definition) (const) Extent=[56:3 - 59:4] [access=public]
17171717
// CHECK: 56:27: ParmDecl=Suffix:56:27 (Definition) Extent=[56:17 - 56:33]
17181718
// CHECK: 56:17: TypeRef=class llvm::StringRef:38:7 Extent=[56:17 - 56:26]
17191719
// CHECK: 56:41: CompoundStmt= Extent=[56:41 - 59:4]
@@ -1740,7 +1740,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
17401740
// CHECK: 58:57: MemberRefExpr=Length:44:10 SingleRefName=[58:57 - 58:63] RefName=[58:57 - 58:63] Extent=[58:50 - 58:63]
17411741
// CHECK: 58:50: DeclRefExpr=Suffix:56:27 Extent=[58:50 - 58:56]
17421742
// CHECK: 58:68: IntegerLiteral= Extent=[58:68 - 58:69]
1743-
// CHECK: 60:13: CXXMethod=substr:60:13 (Definition) Extent=[60:3 - 62:4]
1743+
// CHECK: 60:13: CXXMethod=substr:60:13 (Definition) (const) Extent=[60:3 - 62:4] [access=public]
17441744
// CHECK: 60:3: TypeRef=class llvm::StringRef:38:7 Extent=[60:3 - 60:12]
17451745
// CHECK: 60:27: ParmDecl=Start:60:27 (Definition) Extent=[60:20 - 60:32]
17461746
// CHECK: 60:20: TypeRef=size_t:2:25 Extent=[60:20 - 60:26]
@@ -1769,7 +1769,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
17691769
// CHECK: 66:7: ClassDecl=IdentifierInfo:66:7 (Definition) Extent=[66:1 - 80:2]
17701770
// CHECK: 67:1: CXXAccessSpecifier=:67:1 (Definition) Extent=[67:1 - 67:8]
17711771
// CHECK: 67:8: CXXConstructor=IdentifierInfo:67:8 Extent=[67:8 - 67:24]
1772-
// CHECK: 68:15: CXXMethod=getNameStart:68:15 (Definition) Extent=[68:3 - 71:4]
1772+
// CHECK: 68:15: CXXMethod=getNameStart:68:15 (Definition) (const) Extent=[68:3 - 71:4] [access=public]
17731773
// CHECK: 68:36: CompoundStmt= Extent=[68:36 - 71:4]
17741774
// CHECK: 69:5: DeclStmt= Extent=[69:5 - 69:65]
17751775
// CHECK: 69:54: TypedefDecl=actualtype:69:54 (Definition) Extent=[69:5 - 69:64]
@@ -1781,7 +1781,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
17811781
// CHECK: 70:13: CStyleCastExpr= Extent=[70:13 - 70:38]
17821782
// CHECK: 70:20: TypeRef=actualtype:69:54 Extent=[70:20 - 70:30]
17831783
// CHECK: 70:34: CXXThisExpr= Extent=[70:34 - 70:38]
1784-
// CHECK: 72:12: CXXMethod=getLength:72:12 (Definition) Extent=[72:3 - 76:4]
1784+
// CHECK: 72:12: CXXMethod=getLength:72:12 (Definition) (const) Extent=[72:3 - 76:4] [access=public]
17851785
// CHECK: 72:30: CompoundStmt= Extent=[72:30 - 76:4]
17861786
// CHECK: 73:5: DeclStmt= Extent=[73:5 - 73:65]
17871787
// CHECK: 73:54: TypedefDecl=actualtype:73:54 (Definition) Extent=[73:5 - 73:64]
@@ -1820,7 +1820,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
18201820
// CHECK: 75:55: IntegerLiteral= Extent=[75:55 - 75:56]
18211821
// CHECK: 75:61: UnexposedExpr= Extent=[75:61 - 75:62]
18221822
// CHECK: 75:61: IntegerLiteral= Extent=[75:61 - 75:62]
1823-
// CHECK: 77:19: CXXMethod=getName:77:19 (Definition) Extent=[77:3 - 79:4]
1823+
// CHECK: 77:19: CXXMethod=getName:77:19 (Definition) (const) Extent=[77:3 - 79:4] [access=public]
18241824
// CHECK: 77:35: CompoundStmt= Extent=[77:35 - 79:4]
18251825
// CHECK: 78:5: ReturnStmt= Extent=[78:5 - 78:56]
18261826
// CHECK: 78:12: CallExpr= Extent=[78:12 - 78:56]
@@ -1858,7 +1858,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
18581858
// CHECK: 90:5: ReturnStmt= Extent=[90:5 - 90:17]
18591859
// CHECK: 90:12: UnaryOperator= Extent=[90:12 - 90:17]
18601860
// CHECK: 90:13: CXXThisExpr= Extent=[90:13 - 90:17]
1861-
// CHECK: 92:5: CXXMethod=Default:92:5 (Definition) Extent=[92:3 - 94:4]
1861+
// CHECK: 92:5: CXXMethod=Default:92:5 (Definition) (const) Extent=[92:3 - 94:4] [access=public]
18621862
// CHECK: 92:23: ParmDecl=Value:92:23 (Definition) Extent=[92:13 - 92:28]
18631863
// CHECK: 92:36: CompoundStmt= Extent=[92:36 - 94:4]
18641864
// CHECK: 93:5: ReturnStmt= Extent=[93:5 - 93:17]

‎clang/tools/c-index-test/c-index-test.c

+2
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,8 @@ static void PrintCursor(CXCursor Cursor,
768768
printf(" (static)");
769769
if (clang_CXXMethod_isVirtual(Cursor))
770770
printf(" (virtual)");
771+
if (clang_CXXMethod_isConst(Cursor))
772+
printf(" (const)");
771773
if (clang_CXXMethod_isPureVirtual(Cursor))
772774
printf(" (pure)");
773775
if (clang_Cursor_isVariadic(Cursor))

‎clang/tools/libclang/CIndex.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -6403,6 +6403,16 @@ unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
64036403
return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
64046404
}
64056405

6406+
unsigned clang_CXXMethod_isConst(CXCursor C) {
6407+
if (!clang_isDeclaration(C.kind))
6408+
return 0;
6409+
6410+
const Decl *D = cxcursor::getCursorDecl(C);
6411+
const CXXMethodDecl *Method =
6412+
D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
6413+
return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6414+
}
6415+
64066416
unsigned clang_CXXMethod_isStatic(CXCursor C) {
64076417
if (!clang_isDeclaration(C.kind))
64086418
return 0;

‎clang/tools/libclang/libclang.exports

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ clang_CXCursorSet_contains
22
clang_CXCursorSet_insert
33
clang_CXIndex_getGlobalOptions
44
clang_CXIndex_setGlobalOptions
5+
clang_CXXMethod_isConst
56
clang_CXXMethod_isPureVirtual
67
clang_CXXMethod_isStatic
78
clang_CXXMethod_isVirtual

0 commit comments

Comments
 (0)