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
This commit is contained in:
Dmitri Gribenko 2014-04-07 14:59:13 +00:00
parent 484182779d
commit e570ede5d1
6 changed files with 54 additions and 13 deletions

View File

@ -4192,6 +4192,12 @@ CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
*/
CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C);
/**
* \brief Determine if a C++ member function or member function template is
* declared 'const'.
*/
CINDEX_LINKAGE unsigned clang_CXXMethod_isConst(CXCursor C);
/**
* \brief Given a cursor that represents a template, determine
* the cursor kind of the specializations would be generated by instantiating

View File

@ -7,13 +7,24 @@ protected:
~X();
private:
operator X*();
void constMemberFunction() const;
template<typename T>
void constMemberFunctionTemplate() const;
static void staticMemberFunction();
template<typename T>
static void staticMemberFunctionTemplate();
virtual void virtualMemberFunction();
virtual void pureVirtualMemberFunction() = 0;
};
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 - 10:2]
// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 21:2]
// CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 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]
@ -21,10 +32,21 @@ X::X(int value) {
// FIXME: missing TypeRef in the constructor name
// CHECK: load-classes.cpp:5:14: ParmDecl=x:5:14 (Definition) Extent=[5:5 - 5:15]
// CHECK: load-classes.cpp:5:11: TypeRef=struct X:3:8 Extent=[5:11 - 5:12]
// CHECK: load-classes.cpp:6:1: CXXAccessSpecifier=:6:1 (Definition) Extent=[6:1 - 6:11] [access=protected]
// CHECK: load-classes.cpp:7:3: CXXDestructor=~X:7:3 Extent=[7:3 - 7:7] [access=protected]
// FIXME: missing TypeRef in the destructor name
// CHECK: load-classes.cpp:8:1: CXXAccessSpecifier=:8:1 (Definition) Extent=[8:1 - 8:9] [access=private]
// CHECK: load-classes.cpp:9:3: CXXConversion=operator X *:9:3 Extent=[9:3 - 9:16] [access=private]
// CHECK: load-classes.cpp:9:12: TypeRef=struct X:3:8 Extent=[9:12 - 9:13]
// CHECK: load-classes.cpp:12:4: CXXConstructor=X:12:4 (Definition) Extent=[12:1 - 13:2] [access=public]
// CHECK: load-classes.cpp:12:1: TypeRef=struct X:3:8 Extent=[12:1 - 12:2]
// CHECK: load-classes.cpp:12:10: ParmDecl=value:12:10 (Definition) Extent=[12:6 - 12:15]
// CHECK: load-classes.cpp:11:8: CXXMethod=constMemberFunction:11:8 (const) Extent=[11:3 - 11:35] [access=private]
// CHECK: load-classes.cpp:13:8: FunctionTemplate=constMemberFunctionTemplate:13:8 (const) Extent=[12:3 - 13:43] [access=private]
// CHECK: load-classes.cpp:12:21: TemplateTypeParameter=T:12:21 (Definition) Extent=[12:12 - 12:22] [access=public]
// CHECK: load-classes.cpp:15:15: CXXMethod=staticMemberFunction:15:15 (static) Extent=[15:3 - 15:37] [access=private]
// CHECK: load-classes.cpp:17:15: FunctionTemplate=staticMemberFunctionTemplate:17:15 (static) Extent=[16:3 - 17:45] [access=private]
// CHECK: load-classes.cpp:16:21: TemplateTypeParameter=T:16:21 (Definition) Extent=[16:12 - 16:22] [access=public]
// CHECK: load-classes.cpp:19:16: CXXMethod=virtualMemberFunction:19:16 (virtual) Extent=[19:3 - 19:39] [access=private]
// CHECK: load-classes.cpp:20:16: CXXMethod=pureVirtualMemberFunction:20:16 (virtual) (pure) Extent=[20:3 - 20:47] [access=private]
// CHECK: load-classes.cpp:23:4: CXXConstructor=X:23:4 (Definition) Extent=[23:1 - 24:2] [access=public]
// CHECK: load-classes.cpp:23:1: TypeRef=struct X:3:8 Extent=[23:1 - 23:2]
// CHECK: load-classes.cpp:23:10: ParmDecl=value:23:10 (Definition) Extent=[23:6 - 23:15]
// CHECK: load-classes.cpp:23:17: CompoundStmt= Extent=[23:17 - 24:2]

View File

@ -1680,17 +1680,17 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 49:60: MemberRef=Length:44:10 Extent=[49:60 - 49:66]
// CHECK: 49:67: DeclRefExpr=length:49:38 Extent=[49:67 - 49:73]
// CHECK: 49:75: CompoundStmt= Extent=[49:75 - 49:77]
// CHECK: 50:12: CXXMethod=end:50:12 (Definition) Extent=[50:3 - 50:40]
// CHECK: 50:12: CXXMethod=end:50:12 (Definition) (const) Extent=[50:3 - 50:40] [access=public]
// CHECK: 50:3: TypeRef=iterator:40:23 Extent=[50:3 - 50:11]
// CHECK: 50:24: CompoundStmt= Extent=[50:24 - 50:40]
// CHECK: 50:26: ReturnStmt= Extent=[50:26 - 50:37]
// CHECK: 50:33: MemberRefExpr=Data:43:15 Extent=[50:33 - 50:37]
// CHECK: 51:10: CXXMethod=size:51:10 (Definition) Extent=[51:3 - 51:41]
// CHECK: 51:10: CXXMethod=size:51:10 (Definition) (const) Extent=[51:3 - 51:41] [access=public]
// CHECK: 51:3: TypeRef=size_t:2:25 Extent=[51:3 - 51:9]
// CHECK: 51:23: CompoundStmt= Extent=[51:23 - 51:41]
// CHECK: 51:25: ReturnStmt= Extent=[51:25 - 51:38]
// CHECK: 51:32: MemberRefExpr=Length:44:10 Extent=[51:32 - 51:38]
// CHECK: 52:8: CXXMethod=startswith:52:8 (Definition) Extent=[52:3 - 55:4]
// CHECK: 52:8: CXXMethod=startswith:52:8 (Definition) (const) Extent=[52:3 - 55:4] [access=public]
// CHECK: 52:29: ParmDecl=Prefix:52:29 (Definition) Extent=[52:19 - 52:35]
// CHECK: 52:19: TypeRef=class llvm::StringRef:38:7 Extent=[52:19 - 52:28]
// CHECK: 52:43: CompoundStmt= Extent=[52:43 - 55:4]
@ -1713,7 +1713,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 54:44: MemberRefExpr=Length:44:10 SingleRefName=[54:44 - 54:50] RefName=[54:44 - 54:50] Extent=[54:37 - 54:50]
// CHECK: 54:37: DeclRefExpr=Prefix:52:29 Extent=[54:37 - 54:43]
// CHECK: 54:55: IntegerLiteral= Extent=[54:55 - 54:56]
// CHECK: 56:8: CXXMethod=endswith:56:8 (Definition) Extent=[56:3 - 59:4]
// CHECK: 56:8: CXXMethod=endswith:56:8 (Definition) (const) Extent=[56:3 - 59:4] [access=public]
// CHECK: 56:27: ParmDecl=Suffix:56:27 (Definition) Extent=[56:17 - 56:33]
// CHECK: 56:17: TypeRef=class llvm::StringRef:38:7 Extent=[56:17 - 56:26]
// CHECK: 56:41: CompoundStmt= Extent=[56:41 - 59:4]
@ -1740,7 +1740,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 58:57: MemberRefExpr=Length:44:10 SingleRefName=[58:57 - 58:63] RefName=[58:57 - 58:63] Extent=[58:50 - 58:63]
// CHECK: 58:50: DeclRefExpr=Suffix:56:27 Extent=[58:50 - 58:56]
// CHECK: 58:68: IntegerLiteral= Extent=[58:68 - 58:69]
// CHECK: 60:13: CXXMethod=substr:60:13 (Definition) Extent=[60:3 - 62:4]
// CHECK: 60:13: CXXMethod=substr:60:13 (Definition) (const) Extent=[60:3 - 62:4] [access=public]
// CHECK: 60:3: TypeRef=class llvm::StringRef:38:7 Extent=[60:3 - 60:12]
// CHECK: 60:27: ParmDecl=Start:60:27 (Definition) Extent=[60:20 - 60:32]
// CHECK: 60:20: TypeRef=size_t:2:25 Extent=[60:20 - 60:26]
@ -1769,7 +1769,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 66:7: ClassDecl=IdentifierInfo:66:7 (Definition) Extent=[66:1 - 80:2]
// CHECK: 67:1: CXXAccessSpecifier=:67:1 (Definition) Extent=[67:1 - 67:8]
// CHECK: 67:8: CXXConstructor=IdentifierInfo:67:8 Extent=[67:8 - 67:24]
// CHECK: 68:15: CXXMethod=getNameStart:68:15 (Definition) Extent=[68:3 - 71:4]
// CHECK: 68:15: CXXMethod=getNameStart:68:15 (Definition) (const) Extent=[68:3 - 71:4] [access=public]
// CHECK: 68:36: CompoundStmt= Extent=[68:36 - 71:4]
// CHECK: 69:5: DeclStmt= Extent=[69:5 - 69:65]
// CHECK: 69:54: TypedefDecl=actualtype:69:54 (Definition) Extent=[69:5 - 69:64]
@ -1781,7 +1781,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 70:13: CStyleCastExpr= Extent=[70:13 - 70:38]
// CHECK: 70:20: TypeRef=actualtype:69:54 Extent=[70:20 - 70:30]
// CHECK: 70:34: CXXThisExpr= Extent=[70:34 - 70:38]
// CHECK: 72:12: CXXMethod=getLength:72:12 (Definition) Extent=[72:3 - 76:4]
// CHECK: 72:12: CXXMethod=getLength:72:12 (Definition) (const) Extent=[72:3 - 76:4] [access=public]
// CHECK: 72:30: CompoundStmt= Extent=[72:30 - 76:4]
// CHECK: 73:5: DeclStmt= Extent=[73:5 - 73:65]
// CHECK: 73:54: TypedefDecl=actualtype:73:54 (Definition) Extent=[73:5 - 73:64]
@ -1820,7 +1820,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 75:55: IntegerLiteral= Extent=[75:55 - 75:56]
// CHECK: 75:61: UnexposedExpr= Extent=[75:61 - 75:62]
// CHECK: 75:61: IntegerLiteral= Extent=[75:61 - 75:62]
// CHECK: 77:19: CXXMethod=getName:77:19 (Definition) Extent=[77:3 - 79:4]
// CHECK: 77:19: CXXMethod=getName:77:19 (Definition) (const) Extent=[77:3 - 79:4] [access=public]
// CHECK: 77:35: CompoundStmt= Extent=[77:35 - 79:4]
// CHECK: 78:5: ReturnStmt= Extent=[78:5 - 78:56]
// CHECK: 78:12: CallExpr= Extent=[78:12 - 78:56]
@ -1858,7 +1858,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 90:5: ReturnStmt= Extent=[90:5 - 90:17]
// CHECK: 90:12: UnaryOperator= Extent=[90:12 - 90:17]
// CHECK: 90:13: CXXThisExpr= Extent=[90:13 - 90:17]
// CHECK: 92:5: CXXMethod=Default:92:5 (Definition) Extent=[92:3 - 94:4]
// CHECK: 92:5: CXXMethod=Default:92:5 (Definition) (const) Extent=[92:3 - 94:4] [access=public]
// CHECK: 92:23: ParmDecl=Value:92:23 (Definition) Extent=[92:13 - 92:28]
// CHECK: 92:36: CompoundStmt= Extent=[92:36 - 94:4]
// CHECK: 93:5: ReturnStmt= Extent=[93:5 - 93:17]

View File

@ -768,6 +768,8 @@ static void PrintCursor(CXCursor Cursor,
printf(" (static)");
if (clang_CXXMethod_isVirtual(Cursor))
printf(" (virtual)");
if (clang_CXXMethod_isConst(Cursor))
printf(" (const)");
if (clang_CXXMethod_isPureVirtual(Cursor))
printf(" (pure)");
if (clang_Cursor_isVariadic(Cursor))

View File

@ -6403,6 +6403,16 @@ unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
}
unsigned clang_CXXMethod_isConst(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
const Decl *D = cxcursor::getCursorDecl(C);
const CXXMethodDecl *Method =
D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
}
unsigned clang_CXXMethod_isStatic(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;

View File

@ -2,6 +2,7 @@ clang_CXCursorSet_contains
clang_CXCursorSet_insert
clang_CXIndex_getGlobalOptions
clang_CXIndex_setGlobalOptions
clang_CXXMethod_isConst
clang_CXXMethod_isPureVirtual
clang_CXXMethod_isStatic
clang_CXXMethod_isVirtual