Index: bindings/python/clang/cindex.py =================================================================== --- bindings/python/clang/cindex.py +++ bindings/python/clang/cindex.py @@ -1171,6 +1171,39 @@ """ return conf.lib.clang_CXXMethod_isConst(self) + def is_converting_constructor(self, consider_explicit): + """Returns True if the cursor refers to a C++ converting constructor. + `consider_explicit` determines whether constructors declared 'explicit' are considered. + """ + return conf.lib.clang_CXXConstructor_isConvertingConstructor(self, consider_explicit) + + def is_copy_constructor(self): + """Returns True if the cursor refers to a C++ copy constructor. + """ + return conf.lib.clang_CXXConstructor_isCopyConstructor(self) + + def is_default_constructor(self): + """Returns True if the cursor refers to a C++ default constructor. + """ + return conf.lib.clang_CXXConstructor_isDefaultConstructor(self) + + def is_move_constructor(self): + """Returns True if the cursor refers to a C++ move constructor. + """ + return conf.lib.clang_CXXConstructor_isMoveConstructor(self) + + def is_default_method(self): + """Returns True if the cursor refers to a C++ member function or member + function template that is declared '= default'. + """ + return conf.lib.clang_CXXMethod_isDefaulted(self) + + def is_deleted_method(self): + """Returns True if the cursor refers to a C++ member function or member + function template that is declared '= delete'. + """ + return conf.lib.clang_CXXMethod_isDeleted(self) + def is_mutable_field(self): """Returns True if the cursor refers to a C++ field that is declared 'mutable'. @@ -2905,6 +2938,22 @@ [Index, c_char_p], c_object_p), + ("clang_CXXConstructor_isConvertingConstructor", + [Cursor, c_int], + bool), + + ("clang_CXXConstructor_isCopyConstructor", + [Cursor], + bool), + + ("clang_CXXConstructor_isDefaultConstructor", + [Cursor], + bool), + + ("clang_CXXConstructor_isMoveConstructor", + [Cursor], + bool), + ("clang_CXXField_isMutable", [Cursor], bool), @@ -2913,6 +2962,14 @@ [Cursor], bool), + ("clang_CXXMethod_isDefaulted", + [Cursor], + bool), + + ("clang_CXXMethod_isDeleted", + [Cursor], + bool), + ("clang_CXXMethod_isPureVirtual", [Cursor], bool), Index: bindings/python/tests/cindex/test_cursor.py =================================================================== --- bindings/python/tests/cindex/test_cursor.py +++ bindings/python/tests/cindex/test_cursor.py @@ -112,6 +112,102 @@ assert foo.is_const_method() assert not bar.is_const_method() +def test_is_converting_constructor(): + """Ensure Cursor.is_converting_constructor works.""" + source = 'class X { explicit X(int); X(double); X(); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + + assert len(xs) == 4 + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + assert cs[2].kind == CursorKind.CONSTRUCTOR + + assert not cs[0].is_converting_constructor(False) + assert cs[0].is_converting_constructor(True) + assert cs[1].is_converting_constructor(False) + assert not cs[2].is_converting_constructor(False) + + +def test_is_copy_constructor(): + """Ensure Cursor.is_copy_constructor works.""" + source = 'class X { X(); X(const X&); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + + assert not cs[0].is_copy_constructor() + assert cs[1].is_copy_constructor() + +def test_is_default_constructor(): + """Ensure Cursor.is_default_constructor works.""" + source = 'class X { X(); X(int); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + + assert cs[0].is_default_constructor() + assert not cs[1].is_default_constructor() + + +def test_is_move_constructor(): + """Ensure Cursor.is_move_constructor works.""" + source = 'class X { X(); X(const X&); X(X&&); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + assert xs[0].kind == CursorKind.CLASS_DECL + cs = xs[1:] + assert cs[0].kind == CursorKind.CONSTRUCTOR + assert cs[1].kind == CursorKind.CONSTRUCTOR + assert cs[2].kind == CursorKind.CONSTRUCTOR + + assert not cs[0].is_move_constructor() + assert not cs[1].is_move_constructor() + assert cs[2].is_move_constructor() + + +def test_is_default_method(): + """Ensure Cursor.is_default_method works.""" + source = 'class X { X() = default; }; class Y { Y(); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + ys = get_cursors(tu, 'Y') + + assert len(xs) == 2 + assert len(ys) == 2 + + xc = xs[1] + yc = ys[1] + + assert xc.is_default_method() + assert not yc.is_default_method() + + +def test_is_deleted_method(): + """Ensure Cursor.is_deleted_method works.""" + source = 'class X { void foo() = delete; }; class Y { void bar(); };' + tu = get_tu(source, lang='cpp') + + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + + assert foo.is_deleted_method() + assert not bar.is_deleted_method() + + def test_is_mutable_field(): """Ensure Cursor.is_mutable_field works.""" source = 'class X { int x_; mutable int y_; };' Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -4002,11 +4002,41 @@ */ /** + * \brief Determine if a C++ constructor is a converting constructor. + */ +CINDEX_LINKAGE unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C, unsigned ConsiderExplicit); + +/** + * \brief Determine if a C++ constructor is a copy constructor. + */ +CINDEX_LINKAGE unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C); + +/** + * \brief Determine if a C++ constructor is the default constructor. + */ +CINDEX_LINKAGE unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C); + +/** + * \brief Determine if a C++ constructor is a move constructor. + */ +CINDEX_LINKAGE unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C); + +/** * \brief Determine if a C++ field is declared 'mutable'. */ CINDEX_LINKAGE unsigned clang_CXXField_isMutable(CXCursor C); /** + * \brief Determine if a C++ method is declared '= default'. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C); + +/** + * \brief Determine if a C++ method is declared '= delete'. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isDeleted(CXCursor C); + +/** * \brief Determine if a C++ member function or member function template is * pure virtual. */ Index: test/Index/availability.cpp =================================================================== --- test/Index/availability.cpp +++ test/Index/availability.cpp @@ -9,5 +9,5 @@ // RUN: c-index-test -test-print-type --std=c++11 %s | FileCheck %s // CHECK: FunctionDecl=foo:1:6 (unavailable) [type=void ()] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] // CHECK: StructDecl=Foo:3:8 (Definition) [type=Foo] [typekind=Record] [isPOD=1] -// CHECK: CXXMethod=foo:4:7 (unavailable) [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] -// CHECK: CXXConstructor=Foo:5:3 (unavailable) [type=void (){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] +// CHECK: CXXMethod=foo:4:7 (unavailable) (deleted) [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXConstructor=Foo:5:3 (unavailable) (default constructor) (deleted) [type=void (){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] Index: test/Index/file-refs.cpp =================================================================== --- test/Index/file-refs.cpp +++ test/Index/file-refs.cpp @@ -59,7 +59,7 @@ // RUN: -file-refs-at=%s:2:9 \ // CHECK-NEXT: ClassDecl=C:2:9 (Definition) // CHECK-NEXT: ClassDecl=C:2:9 (Definition) =[2:9 - 2:10] -// CHECK-NEXT: CXXConstructor=C:4:5 (Definition) =[4:5 - 4:6] +// CHECK-NEXT: CXXConstructor=C:4:5 (Definition) (default constructor) =[4:5 - 4:6] // CHECK-NEXT: TypeRef=class NS::C:2:9 =[9:10 - 9:11] // CHECK-NEXT: TypeRef=class NS::C:2:9 =[10:3 - 10:4] // CHECK-NEXT: TypeRef=class NS::C:2:9 =[15:7 - 15:8] @@ -69,7 +69,7 @@ // RUN: -file-refs-at=%s:16:18 \ // CHECK-NEXT: CallExpr=C:4:5 // CHECK-NEXT: ClassDecl=C:2:9 (Definition) =[2:9 - 2:10] -// CHECK-NEXT: CXXConstructor=C:4:5 (Definition) =[4:5 - 4:6] +// CHECK-NEXT: CXXConstructor=C:4:5 (Definition) (default constructor) =[4:5 - 4:6] // CHECK-NEXT: TypeRef=class NS::C:2:9 =[9:10 - 9:11] // CHECK-NEXT: TypeRef=class NS::C:2:9 =[10:3 - 10:4] // CHECK-NEXT: TypeRef=class NS::C:2:9 =[15:7 - 15:8] @@ -91,7 +91,7 @@ // CHECK-NEXT: CallExpr=S:35:3 // CHECK-NEXT: StructDecl=S:34:8 (Definition) =[34:8 - 34:9] // CHECK-NEXT: CXXConstructor=S:35:3 =[35:3 - 35:4] -// CHECK-NEXT: CXXConstructor=S:36:3 =[36:3 - 36:4] +// CHECK-NEXT: CXXConstructor=S:36:3 (default constructor) =[36:3 - 36:4] // CHECK-NEXT: TypeRef=struct Test2::S:34:8 =[39:9 - 39:10] // CHECK-NEXT: TypeRef=struct Test2::S:34:8 =[43:14 - 43:15] Index: test/Index/get-cursor.cpp =================================================================== --- test/Index/get-cursor.cpp +++ test/Index/get-cursor.cpp @@ -208,7 +208,7 @@ // CHECK-TEMPLSPEC: 66:23 ClassDecl=TC:66:23 (Definition) [Specialization of TC:59:7] Extent=[66:1 - 66:31] Spelling=TC ([66:23 - 66:25]) // RUN: c-index-test -cursor-at=%s:69:3 -cursor-at=%s:70:11 -cursor-at=%s:73:6 -cursor-at=%s:74:6 -cursor-at=%s:77:8 -cursor-at=%s:78:8 -cursor-at=%s:79:8 -cursor-at=%s:80:8 -cursor-at=%s:81:8 -cursor-at=%s:82:8 -cursor-at=%s:85:6 -cursor-at=%s:86:6 -cursor-at=%s:87:6 -cursor-at=%s:88:6 -cursor-at=%s:91:5 -cursor-at=%s:92:5 -cursor-at=%s:93:5 -cursor-at=%s:94:5 -cursor-at=%s:95:5 -cursor-at=%s:96:5 -cursor-at=%s:97:5 -cursor-at=%s:98:5 -cursor-at=%s:100:5 -cursor-at=%s:101:5 -cursor-at=%s:104:6 -cursor-at=%s:105:6 -cursor-at=%s:106:6 -cursor-at=%s:107:6 -cursor-at=%s:108:6 -cursor-at=%s:109:6 -cursor-at=%s:110:6 -cursor-at=%s:111:6 -cursor-at=%s:113:6 -cursor-at=%s:114:6 -cursor-at=%s:117:8 -cursor-at=%s:118:8 -cursor-at=%s:120:8 -cursor-at=%s:121:8 -cursor-at=%s:122:8 -cursor-at=%s:123:8 -cursor-at=%s:124:8 -cursor-at=%s:125:8 -cursor-at=%s:128:6 -cursor-at=%s:129:6 -cursor-at=%s:130:6 -cursor-at=%s:132:3 -std=c++11 %s | FileCheck -check-prefix=CHECK-SPELLING %s -// CHECK-SPELLING: 69:3 CXXConstructor=A:69:3 Extent=[69:3 - 69:6] Spelling=A ([69:3 - 69:4]) +// CHECK-SPELLING: 69:3 CXXConstructor=A:69:3 (default constructor) Extent=[69:3 - 69:6] Spelling=A ([69:3 - 69:4]) // CHECK-SPELLING: 70:11 CXXDestructor=~A:70:11 (virtual) Extent=[70:3 - 70:15] Spelling=~A ([70:11 - 70:13]) // CHECK-SPELLING: 73:6 CXXMethod=operator=:73:6 Extent=[73:3 - 73:25] Spelling=operator= ([73:6 - 73:15]) // CHECK-SPELLING: 74:6 CXXMethod=operator=:74:6 Extent=[74:3 - 74:29] Spelling=operator= ([74:6 - 74:15]) Index: test/Index/index-file.cpp =================================================================== --- test/Index/index-file.cpp +++ test/Index/index-file.cpp @@ -27,6 +27,13 @@ class B { mutable int x_; int y_; + + B() = default; + B(int); + explicit B(double); + B(const B&); + B(B&&); + void foo() = delete; }; // RUN: c-index-test -index-file %s > %t // RUN: FileCheck %s -input-file=%t @@ -37,3 +44,9 @@ // 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 +// CHECK: [indexDeclaration]: kind: constructor | name: B | {{.*}} (defaulted) | loc: 31:3 +// CHECK: [indexDeclaration]: kind: constructor | name: B | {{.*}} (implicit converting constructor) | loc: 32:3 +// CHECK: [indexDeclaration]: kind: constructor | name: B | {{.*}} (explicit converting constructor) | loc: 33:12 +// CHECK: [indexDeclaration]: kind: constructor | name: B | {{.*}} (copy constructor) (implicit converting constructor) | loc: 34:3 +// CHECK: [indexDeclaration]: kind: constructor | name: B | {{.*}} (move constructor) (implicit converting constructor) | loc: 35:3 +// CHECK: [indexDeclaration]: kind: c++-instance-method | name: foo | {{.*}} (deleted) | loc: 36:8 Index: test/Index/load-classes.cpp =================================================================== --- test/Index/load-classes.cpp +++ test/Index/load-classes.cpp @@ -25,10 +25,10 @@ // 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 - 21:2] -// CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 Extent=[4:3 - 4:15] [access=public] +// CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 (implicit 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] -// CHECK: load-classes.cpp:5:3: CXXConstructor=X:5:3 Extent=[5:3 - 5:16] [access=public] +// CHECK: load-classes.cpp:5:3: CXXConstructor=X:5:3 (copy constructor) (implicit converting constructor) Extent=[5:3 - 5:16] [access=public] // 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] @@ -46,7 +46,7 @@ // 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:4: CXXConstructor=X:23:4 (Definition) (implicit converting constructor) 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] Index: test/Index/print-type.cpp =================================================================== --- test/Index/print-type.cpp +++ test/Index/print-type.cpp @@ -68,7 +68,7 @@ // CHECK: TemplateTemplateParameter=W:8:60 (Definition) [type=] [typekind=Invalid] [isPOD=0] // CHECK: Namespace=inner:14:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] // CHECK: StructDecl=Bar:16:8 (Definition) [type=outer::inner::Bar] [typekind=Record] [isPOD=0] [nbFields=3] -// CHECK: CXXConstructor=Bar:17:3 (Definition) [type=void (outer::Foo *){{.*}}] [typekind=FunctionProto] [canonicaltype=void (outer::Foo *){{.*}}] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [outer::Foo *] [Pointer]] [isPOD=0] +// CHECK: CXXConstructor=Bar:17:3 (Definition) (implicit converting constructor) [type=void (outer::Foo *){{.*}}] [typekind=FunctionProto] [canonicaltype=void (outer::Foo *){{.*}}] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [outer::Foo *] [Pointer]] [isPOD=0] // CHECK: ParmDecl=foo:17:25 (Definition) [type=outer::Foo *] [typekind=Pointer] [canonicaltype=outer::Foo *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=outer::Foo] [pointeekind=Unexposed] // CHECK: NamespaceRef=outer:1:11 [type=] [typekind=Invalid] [isPOD=0] // CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0] Index: test/Index/recursive-cxx-member-calls.cpp =================================================================== --- test/Index/recursive-cxx-member-calls.cpp +++ test/Index/recursive-cxx-member-calls.cpp @@ -1653,7 +1653,7 @@ // CHECK: 45:58: DeclRefExpr=a:45:28 Extent=[45:58 - 45:59] // CHECK: 45:62: DeclRefExpr=b:45:38 Extent=[45:62 - 45:63] // CHECK: 46:1: CXXAccessSpecifier=:46:1 (Definition) Extent=[46:1 - 46:8] -// CHECK: 47:3: CXXConstructor=StringRef:47:3 (Definition) Extent=[47:3 - 47:37] +// CHECK: 47:3: CXXConstructor=StringRef:47:3 (Definition) (default constructor) Extent=[47:3 - 47:37] // CHECK: 47:16: MemberRef=Data:43:15 Extent=[47:16 - 47:20] // CHECK: 47:21: UnexposedExpr= Extent=[47:21 - 47:22] // CHECK: 47:21: IntegerLiteral= Extent=[47:21 - 47:22] @@ -1661,7 +1661,7 @@ // CHECK: 47:32: UnexposedExpr= Extent=[47:32 - 47:33] // CHECK: 47:32: IntegerLiteral= Extent=[47:32 - 47:33] // CHECK: 47:35: CompoundStmt= Extent=[47:35 - 47:37] -// CHECK: 48:3: CXXConstructor=StringRef:48:3 (Definition) Extent=[48:3 - 48:71] +// CHECK: 48:3: CXXConstructor=StringRef:48:3 (Definition) (implicit converting constructor) Extent=[48:3 - 48:71] // CHECK: 48:25: ParmDecl=Str:48:25 (Definition) Extent=[48:13 - 48:28] // CHECK: 48:32: MemberRef=Data:43:15 Extent=[48:32 - 48:36] // CHECK: 48:37: DeclRefExpr=Str:48:25 Extent=[48:37 - 48:40] @@ -1768,7 +1768,7 @@ // CHECK: 65:11: Namespace=clang:65:11 (Definition) Extent=[65:1 - 81:2] // 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: 67:8: CXXConstructor=IdentifierInfo:67:8 (default constructor) Extent=[67:8 - 67:24] // 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] @@ -1839,7 +1839,7 @@ // CHECK: 84:3: TypeRef=class llvm::StringRef:38:7 Extent=[84:3 - 84:12] // CHECK: 85:12: FieldDecl=Result:85:12 (Definition) Extent=[85:3 - 85:18] // CHECK: 86:1: CXXAccessSpecifier=:86:1 (Definition) Extent=[86:1 - 86:8] -// CHECK: 87:12: CXXConstructor=StringSwitch:87:12 (Definition) Extent=[87:3 - 87:64] +// CHECK: 87:12: CXXConstructor=StringSwitch:87:12 (Definition) (explicit converting constructor) Extent=[87:3 - 87:64] // CHECK: 87:35: ParmDecl=Str:87:35 (Definition) Extent=[87:25 - 87:38] // CHECK: 87:25: TypeRef=class llvm::StringRef:38:7 Extent=[87:25 - 87:34] // CHECK: 87:42: MemberRef=Str:84:13 Extent=[87:42 - 87:45] Index: test/Parser/skip-function-bodies.mm =================================================================== --- test/Parser/skip-function-bodies.mm +++ test/Parser/skip-function-bodies.mm @@ -30,7 +30,7 @@ // CHECK: skip-function-bodies.mm:3:7: ClassDecl=A:3:7 (Definition) Extent=[3:1 - 14:2] // CHECK: skip-function-bodies.mm:4:9: ClassDecl=B:4:9 (Definition) Extent=[4:3 - 4:13] // CHECK: skip-function-bodies.mm:6:1: CXXAccessSpecifier=:6:1 (Definition) Extent=[6:1 - 6:8] -// CHECK: skip-function-bodies.mm:7:3: CXXConstructor=A:7:3 Extent=[7:3 - 7:6] +// CHECK: skip-function-bodies.mm:7:3: CXXConstructor=A:7:3 (default constructor) Extent=[7:3 - 7:6] // CHECK-NOT: skip-function-bodies.mm:8:12: StructDecl=C:8:12 (Definition) Extent=[8:5 - 10:6] // CHECK-NOT: skip-function-bodies.mm:9:12: CXXMethod=d:9:12 (Definition) Extent=[9:7 - 9:18] // CHECK: skip-function-bodies.mm:13:13: TypedefDecl=E:13:13 (Definition) Extent=[13:3 - 13:14] Index: tools/c-index-test/c-index-test.c =================================================================== --- tools/c-index-test/c-index-test.c +++ tools/c-index-test/c-index-test.c @@ -766,9 +766,26 @@ clang_disposeString(DeprecatedMessage); clang_disposeString(UnavailableMessage); - + + if (clang_CXXConstructor_isDefaultConstructor(Cursor)) + printf(" (default constructor)"); + + if (clang_CXXConstructor_isMoveConstructor(Cursor)) + printf(" (move constructor)"); + if (clang_CXXConstructor_isCopyConstructor(Cursor)) + printf(" (copy constructor)"); + + if (clang_CXXConstructor_isConvertingConstructor(Cursor,0)) + printf(" (implicit converting constructor)"); + else if (clang_CXXConstructor_isConvertingConstructor(Cursor,1)) + printf(" (explicit converting constructor)"); + if (clang_CXXField_isMutable(Cursor)) printf(" (mutable)"); + if (clang_CXXMethod_isDeleted(Cursor)) + printf(" (deleted)"); + if (clang_CXXMethod_isDefaulted(Cursor)) + printf(" (defaulted)"); if (clang_CXXMethod_isStatic(Cursor)) printf(" (static)"); if (clang_CXXMethod_isVirtual(Cursor)) Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -7039,6 +7039,47 @@ //===----------------------------------------------------------------------===// extern "C" { + +unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return 0; + + const Decl *D = cxcursor::getCursorDecl(C); + const CXXConstructorDecl *Constructor = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0; +} + +unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return 0; + + const Decl *D = cxcursor::getCursorDecl(C); + const CXXConstructorDecl *Constructor = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0; +} + +unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return 0; + + const Decl *D = cxcursor::getCursorDecl(C); + const CXXConstructorDecl *Constructor = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0; +} + +unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C, unsigned AllowExplicit) { + if (!clang_isDeclaration(C.kind)) + return 0; + + const Decl *D = cxcursor::getCursorDecl(C); + const CXXConstructorDecl *Constructor = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return (Constructor && Constructor->isConvertingConstructor(AllowExplicit)) ? 1 : 0; +} + unsigned clang_CXXField_isMutable(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; @@ -7069,6 +7110,26 @@ return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0; } +unsigned clang_CXXMethod_isDefaulted(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return 0; + + const Decl *D = cxcursor::getCursorDecl(C); + const CXXMethodDecl *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return (Method && Method->isDefaulted()) ? 1 : 0; +} + +unsigned clang_CXXMethod_isDeleted(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return 0; + + const Decl *D = cxcursor::getCursorDecl(C); + const CXXMethodDecl *Method = + D ? dyn_cast_or_null(D->getAsFunction()) : nullptr; + return (Method && Method->isDeleted()) ? 1 : 0; +} + unsigned clang_CXXMethod_isStatic(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; Index: tools/libclang/libclang.exports =================================================================== --- tools/libclang/libclang.exports +++ tools/libclang/libclang.exports @@ -2,7 +2,13 @@ clang_CXCursorSet_insert clang_CXIndex_getGlobalOptions clang_CXIndex_setGlobalOptions +clang_CXXConstructor_isConvertingConstructor +clang_CXXConstructor_isCopyConstructor +clang_CXXConstructor_isDefaultConstructor +clang_CXXConstructor_isMoveConstructor clang_CXXField_isMutable +clang_CXXMethod_isDefaulted +clang_CXXMethod_isDeleted clang_CXXMethod_isConst clang_CXXMethod_isPureVirtual clang_CXXMethod_isStatic