[PATCH] D133924: add clang_CXXMethod_isDeleted function
anderslanglands created this revision. Herald added a subscriber: arphaman. Herald added a project: All. anderslanglands requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D133924 Files: clang/bindings/python/clang/cindex.py clang/include/clang-c/Index.h clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CIndex.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -409,6 +409,7 @@ global: clang_getUnqualifiedType; clang_getNonReferenceType; +clang_CXXMethod_isDeleted; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CIndex.cpp === --- clang/tools/libclang/CIndex.cpp +++ clang/tools/libclang/CIndex.cpp @@ -8861,6 +8861,16 @@ 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: clang/tools/c-index-test/c-index-test.c === --- clang/tools/c-index-test/c-index-test.c +++ clang/tools/c-index-test/c-index-test.c @@ -900,6 +900,8 @@ printf(" (mutable)"); if (clang_CXXMethod_isDefaulted(Cursor)) printf(" (defaulted)"); +if (clang_CXXMethod_isDeleted(Cursor)) + printf(" (deleted)"); if (clang_CXXMethod_isStatic(Cursor)) printf(" (static)"); if (clang_CXXMethod_isVirtual(Cursor)) Index: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -4924,6 +4924,11 @@ */ CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C); +/** + * Determine if a C++ method is declared '= default'. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isDeleted(CXCursor C); + /** * Determine if a C++ member function or member function template is * pure virtual. Index: clang/bindings/python/clang/cindex.py === --- clang/bindings/python/clang/cindex.py +++ clang/bindings/python/clang/cindex.py @@ -1473,6 +1473,12 @@ """ 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'. @@ -3426,6 +3432,10 @@ [Cursor], bool), + ("clang_CXXMethod_isDeleted", + [Cursor], + bool), + ("clang_CXXMethod_isPureVirtual", [Cursor], bool), Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -409,6 +409,7 @@ global: clang_getUnqualifiedType; clang_getNonReferenceType; +clang_CXXMethod_isDeleted; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CIndex.cpp === --- clang/tools/libclang/CIndex.cpp +++ clang/tools/libclang/CIndex.cpp @@ -8861,6 +8861,16 @@ 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: clang/tools/c-index-test/c-index-test.c === --- clang/tools/c-index-test/c-index-test.c +++ clang/tools/c-index-test/c-index-test.c @@ -900,6 +900,8 @@ printf(" (mutable)"); if (clang_CXXMethod_isDefaulted(Cursor)) printf(" (defaulted)"); +if (clang_CXXMethod_isDeleted(Cursor)) + printf(" (deleted)"); if (clang_CXXMethod_isStatic(Cursor)) printf(" (static)"); if (clang_CXXMethod_isVirtual(Cursor)) Index: clang/include
[PATCH] D135557: Add needsImplicitDefaultConstructor and friends
anderslanglands added inline comments. Comment at: clang/bindings/python/clang/cindex.py:1530 + +def record_needs_implicit_default_constructor(self): +"""Returns True if the cursor refers to a C++ record declaration dblaikie wrote: > aaron.ballman wrote: > > dblaikie wrote: > > > anderslanglands wrote: > > > > dblaikie wrote: > > > > > aaron.ballman wrote: > > > > > > royjacobson wrote: > > > > > > > anderslanglands wrote: > > > > > > > > royjacobson wrote: > > > > > > > > > anderslanglands wrote: > > > > > > > > > > royjacobson wrote: > > > > > > > > > > > aaron.ballman wrote: > > > > > > > > > > > > aaron.ballman wrote: > > > > > > > > > > > > > I don't think we should expose any of the "needs" > > > > > > > > > > > > > functions like this -- those are internal > > > > > > > > > > > > > implementation details of the class and I don't think > > > > > > > > > > > > > we want to calcify that into something we have to > > > > > > > > > > > > > support forever. As we add members to a class, we > > > > > > > > > > > > > recalculate whether the added member causes us to > > > > > > > > > > > > > delete defaulted special members (among other > > > > > > > > > > > > > things), and the "needs" functions are basically used > > > > > > > > > > > > > when the class is completed to handle lazily created > > > > > > > > > > > > > special members. I'm pretty sure that lazy creation > > > > > > > > > > > > > is not mandated by the standard, which is why I think > > > > > > > > > > > > > the "needs" functions are more of an implementation > > > > > > > > > > > > > detail. > > > > > > > > > > > > CC @erichkeane and @royjacobson as folks who have been > > > > > > > > > > > > in this same area of the compiler to see if they agree > > > > > > > > > > > > or disagree with my assessment there. > > > > > > > > > > > I think so. The 'needs_*' functions query > > > > > > > > > > > `DeclaredSpecialMembers` and I'm pretty sure it's > > > > > > > > > > > modified when we add the implicit definitions in the > > > > > > > > > > > class completion code. So this looks a bit suspicious. Is > > > > > > > > > > > this API //meant// to be used with incomplete classes? > > > > > > > > > > > For complete classes I think looking up the > > > > > > > > > > > default/move/copy constructor and calling `isImplicit()` > > > > > > > > > > > is the way to do it. > > > > > > > > > > > > > > > > > > > > > > About the 'is deleted' API - can't the same be done for > > > > > > > > > > > those functions as well so we have a smaller API? > > > > > > > > > > > > > > > > > > > > > > If this //is// meant to be used with incomplete classes > > > > > > > > > > > for efficiency that would be another thing, I guess. > > > > > > > > > > > > > > > > > > > > > So the intended use case here is I'm using libclang to > > > > > > > > > > parse an existing C++ libray's headers and generate a C > > > > > > > > > > interface to it. To do that I need to know if I need to > > > > > > > > > > generate default constructors etc, which the needs* methods > > > > > > > > > > do for me (I believe). The alternative is I have to check > > > > > > > > > > manually whether all the constructors/assignment operators > > > > > > > > > > exist, then implement the implicit declaration rules myself > > > > > > > > > > correctly for each version of the standard, which I'd > > > > > > > > > > rather avoid. > > > > > > > > > > > > > > > > > > > > Would putting a note in the doc comment about the behaviour > > > > > > > > > > differing when the class is being constructed as originally > > > > > > > > > > suggested work for everyone? > > > > > > > > > Why is the `__is_default_constructible` builtin type trait > > > > > > > > > not enough? Do you have different behavior for user provided > > > > > > > > > and implicit default constructors? > > > > > > > > > > > > > > > > > Can I evaluate that from libclang somewhow? I can't modify the > > > > > > > > C++ libraries I'm wrapping. > > > > > > > > > > > > > > > > Basically, given: > > > > > > > > ``` > > > > > > > > struct Foo { /* ... */ }; > > > > > > > > ``` > > > > > > > > > > > > > > > > I want to generate: > > > > > > > > > > > > > > > > ``` > > > > > > > > typedef struct Foo_t; > > > > > > > > > > > > > > > > Foo_t* Foo_ctor(); > > > > > > > > Foo_t* Foo_copy_ctor(Foo_t*); > > > > > > > > /* etc... */ > > > > > > > > Foo_dtor(Foo_t*); > > > > > > > > ``` > > > > > > > > > > > > > > > > In order to know which ones to generate for an arbitrary struct > > > > > > > > that may or may not have any combination of ctor/assignments > > > > > > > > defined, I need to know which ones exist and follow the > > > > > > > > implicit generation rules for the ones that don't. I can do > > > > > > > > this myself with a whole bunch of version-dependent logic, but > > > > > > > > I'd rather just rely on libclang since it already knows all > > > > > > > > this muc
[PATCH] D135557: Add needsImplicitDefaultConstructor and friends
anderslanglands added inline comments. Comment at: clang/bindings/python/clang/cindex.py:1530 + +def record_needs_implicit_default_constructor(self): +"""Returns True if the cursor refers to a C++ record declaration dblaikie wrote: > royjacobson wrote: > > anderslanglands wrote: > > > dblaikie wrote: > > > > aaron.ballman wrote: > > > > > dblaikie wrote: > > > > > > anderslanglands wrote: > > > > > > > dblaikie wrote: > > > > > > > > aaron.ballman wrote: > > > > > > > > > royjacobson wrote: > > > > > > > > > > anderslanglands wrote: > > > > > > > > > > > royjacobson wrote: > > > > > > > > > > > > anderslanglands wrote: > > > > > > > > > > > > > royjacobson wrote: > > > > > > > > > > > > > > aaron.ballman wrote: > > > > > > > > > > > > > > > aaron.ballman wrote: > > > > > > > > > > > > > > > > I don't think we should expose any of the > > > > > > > > > > > > > > > > "needs" functions like this -- those are > > > > > > > > > > > > > > > > internal implementation details of the class > > > > > > > > > > > > > > > > and I don't think we want to calcify that into > > > > > > > > > > > > > > > > something we have to support forever. As we add > > > > > > > > > > > > > > > > members to a class, we recalculate whether the > > > > > > > > > > > > > > > > added member causes us to delete defaulted > > > > > > > > > > > > > > > > special members (among other things), and the > > > > > > > > > > > > > > > > "needs" functions are basically used when the > > > > > > > > > > > > > > > > class is completed to handle lazily created > > > > > > > > > > > > > > > > special members. I'm pretty sure that lazy > > > > > > > > > > > > > > > > creation is not mandated by the standard, which > > > > > > > > > > > > > > > > is why I think the "needs" functions are more > > > > > > > > > > > > > > > > of an implementation detail. > > > > > > > > > > > > > > > CC @erichkeane and @royjacobson as folks who have > > > > > > > > > > > > > > > been in this same area of the compiler to see if > > > > > > > > > > > > > > > they agree or disagree with my assessment there. > > > > > > > > > > > > > > I think so. The 'needs_*' functions query > > > > > > > > > > > > > > `DeclaredSpecialMembers` and I'm pretty sure it's > > > > > > > > > > > > > > modified when we add the implicit definitions in > > > > > > > > > > > > > > the class completion code. So this looks a bit > > > > > > > > > > > > > > suspicious. Is this API //meant// to be used with > > > > > > > > > > > > > > incomplete classes? > > > > > > > > > > > > > > For complete classes I think looking up the > > > > > > > > > > > > > > default/move/copy constructor and calling > > > > > > > > > > > > > > `isImplicit()` is the way to do it. > > > > > > > > > > > > > > > > > > > > > > > > > > > > About the 'is deleted' API - can't the same be done > > > > > > > > > > > > > > for those functions as well so we have a smaller > > > > > > > > > > > > > > API? > > > > > > > > > > > > > > > > > > > > > > > > > > > > If this //is// meant to be used with incomplete > > > > > > > > > > > > > > classes for efficiency that would be another thing, > > > > > > > > > > > > > > I guess. > > > > > > > > > > > > > > > > > > > > > > > > > > > So the intended use case here is I'm using libclang > > > > > > > > > > > > > to parse an existing C++ libray's headers and > > > > > > > > > > > > > generate a C interface to it. To do that I need to > > > > > > > > > > > > > know if I need to generate default constructors etc, > > > > > > > > > > > > > which the needs* methods do for me (I believe). The > > > > > > > > > > > > > alternative is I have to check manually whether all > > > > > > > > > > > > > the constructors/assignment operators exist, then > > > > > > > > > > > > > implement the implicit declaration rules myself > > > > > > > > > > > > > correctly for each version of the standard, which I'd > > > > > > > > > > > > > rather avoid. > > > > > > > > > > > > > > > > > > > > > > > > > > Would putting a note in the doc comment about the > > > > > > > > > > > > > behaviour differing when the class is being > > > > > > > > > > > > > constructed as originally suggested work for everyone? > > > > > > > > > > > > Why is the `__is_default_constructible` builtin type > > > > > > > > > > > > trait not enough? Do you have different behavior for > > > > > > > > > > > > user provided and implicit default constructors? > > > > > > > > > > > > > > > > > > > > > > > Can I evaluate that from libclang somewhow? I can't > > > > > > > > > > > modify the C++ libraries I'm wrapping. > > > > > > > > > > > > > > > > > > > > > > Basically, given: > > > > > > > > > > > ``` > > > > > > > > > > > struct Foo { /* ... */ }; > > > > > > > > > > > ``` > > > > > > > > > > > > > > > > > > > > > > I want to generate: > > > > > > > > > > > > > > > > > > > > > > ``` > > > > > > > > > > > typedef struct Foo_t; > > > > > > > > > > > > > > > > > > >
[PATCH] D135557: Add needsImplicitDefaultConstructor and friends
anderslanglands added inline comments. Comment at: clang/bindings/python/clang/cindex.py:1530 + +def record_needs_implicit_default_constructor(self): +"""Returns True if the cursor refers to a C++ record declaration dblaikie wrote: > aaron.ballman wrote: > > dblaikie wrote: > > > anderslanglands wrote: > > > > dblaikie wrote: > > > > > royjacobson wrote: > > > > > > anderslanglands wrote: > > > > > > > dblaikie wrote: > > > > > > > > aaron.ballman wrote: > > > > > > > > > dblaikie wrote: > > > > > > > > > > anderslanglands wrote: > > > > > > > > > > > dblaikie wrote: > > > > > > > > > > > > aaron.ballman wrote: > > > > > > > > > > > > > royjacobson wrote: > > > > > > > > > > > > > > anderslanglands wrote: > > > > > > > > > > > > > > > royjacobson wrote: > > > > > > > > > > > > > > > > anderslanglands wrote: > > > > > > > > > > > > > > > > > royjacobson wrote: > > > > > > > > > > > > > > > > > > aaron.ballman wrote: > > > > > > > > > > > > > > > > > > > aaron.ballman wrote: > > > > > > > > > > > > > > > > > > > > I don't think we should expose any of > > > > > > > > > > > > > > > > > > > > the "needs" functions like this -- > > > > > > > > > > > > > > > > > > > > those are internal implementation > > > > > > > > > > > > > > > > > > > > details of the class and I don't think > > > > > > > > > > > > > > > > > > > > we want to calcify that into something > > > > > > > > > > > > > > > > > > > > we have to support forever. As we add > > > > > > > > > > > > > > > > > > > > members to a class, we recalculate > > > > > > > > > > > > > > > > > > > > whether the added member causes us to > > > > > > > > > > > > > > > > > > > > delete defaulted special members (among > > > > > > > > > > > > > > > > > > > > other things), and the "needs" > > > > > > > > > > > > > > > > > > > > functions are basically used when the > > > > > > > > > > > > > > > > > > > > class is completed to handle lazily > > > > > > > > > > > > > > > > > > > > created special members. I'm pretty > > > > > > > > > > > > > > > > > > > > sure that lazy creation is not mandated > > > > > > > > > > > > > > > > > > > > by the standard, which is why I think > > > > > > > > > > > > > > > > > > > > the "needs" functions are more of an > > > > > > > > > > > > > > > > > > > > implementation detail. > > > > > > > > > > > > > > > > > > > CC @erichkeane and @royjacobson as folks > > > > > > > > > > > > > > > > > > > who have been in this same area of the > > > > > > > > > > > > > > > > > > > compiler to see if they agree or disagree > > > > > > > > > > > > > > > > > > > with my assessment there. > > > > > > > > > > > > > > > > > > I think so. The 'needs_*' functions query > > > > > > > > > > > > > > > > > > `DeclaredSpecialMembers` and I'm pretty > > > > > > > > > > > > > > > > > > sure it's modified when we add the implicit > > > > > > > > > > > > > > > > > > definitions in the class completion code. > > > > > > > > > > > > > > > > > > So this looks a bit suspicious. Is this API > > > > > > > > > > > > > > > > > > //meant// to be used with incomplete > > > > > > > > > > > > > > > > > > classes? > > > > > > > > > > > > > > > > > > For complete classes I think looking up the > > > > > > > > > > > > > > > > > > default/move/copy constructor and calling > > > > > > > > > > > > > > > > > > `isImplicit()` is the way to do it. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > About the 'is deleted' API - can't the same > > > > > > > > > > > > > > > > > > be done for those functions as well so we > > > > > > > > > > > > > > > > > > have a smaller API? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > If this //is// meant to be used with > > > > > > > > > > > > > > > > > > incomplete classes for efficiency that > > > > > > > > > > > > > > > > > > would be another thing, I guess. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > So the intended use case here is I'm using > > > > > > > > > > > > > > > > > libclang to parse an existing C++ libray's > > > > > > > > > > > > > > > > > headers and generate a C interface to it. To > > > > > > > > > > > > > > > > > do that I need to know if I need to generate > > > > > > > > > > > > > > > > > default constructors etc, which the needs* > > > > > > > > > > > > > > > > > methods do for me (I believe). The > > > > > > > > > > > > > > > > > alternative is I have to check manually > > > > > > > > > > > > > > > > > whether all the constructors/assignment > > > > > > > > > > > > > > > > > operators exist, then implement the implicit > > > > > > > > > > > > > > > > > declaration rules myself correctly for each > > > > > > > > > > > > > > > > > version of the standard, which I'd rather > > > > > > > > > > > > > > > > > avoid. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Would putting a note in the doc comment about > > > > > > > > > > > > > > > > > the behaviour
[PATCH] D133991: add new function to release notes
anderslanglands created this revision. Herald added a subscriber: arphaman. Herald added a project: All. anderslanglands requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. fix copy/paste error in doc comment fix failing test now deleted is supported add new test for clang_CXXMethod_isDeleted Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D133991 Files: clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/availability.cpp clang/test/Index/deletion.cpp Index: clang/test/Index/deletion.cpp === --- /dev/null +++ clang/test/Index/deletion.cpp @@ -0,0 +1,14 @@ +struct Foo { + int foo() = delete; + int bar(); + Foo() = delete; + Foo(int); +}; + + +// RUN: c-index-test -test-print-type --std=c++11 %s | FileCheck %s +// CHECK: StructDecl=Foo:1:8 (Definition) [type=Foo] [typekind=Record] [isPOD=1] +// CHECK: CXXMethod=foo:2:7 (unavailable) (deleted) [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXMethod=bar:3:7 [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXConstructor=Foo:4:3 (unavailable) (default constructor) (deleted) [type=void (){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] +// CHECK: CXXConstructor=Foo:5:3 (converting constructor) [type=void (int){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [int] [Int]] [isPOD=0] Index: clang/test/Index/availability.cpp === --- clang/test/Index/availability.cpp +++ clang/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) (default constructor) [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: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -4925,7 +4925,7 @@ CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C); /** - * Determine if a C++ method is declared '= default'. + * Determine if a C++ method is declared '= delete'. */ CINDEX_LINKAGE unsigned clang_CXXMethod_isDeleted(CXCursor C); Index: clang/docs/ReleaseNotes.rst === --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -319,6 +319,8 @@ the behavior of `QualType::getUnqualifiedType` for `CXType`. - Introduced the new function `clang_getNonReferenceType`, which mimics the behavior of `QualType::getNonReferenceType` for `CXType`. +- Introduced the new function `clang_CXXMethod_isDeleted`, which queries + whether the method is declared `= delete. Static Analyzer --- Index: clang/test/Index/deletion.cpp === --- /dev/null +++ clang/test/Index/deletion.cpp @@ -0,0 +1,14 @@ +struct Foo { + int foo() = delete; + int bar(); + Foo() = delete; + Foo(int); +}; + + +// RUN: c-index-test -test-print-type --std=c++11 %s | FileCheck %s +// CHECK: StructDecl=Foo:1:8 (Definition) [type=Foo] [typekind=Record] [isPOD=1] +// CHECK: CXXMethod=foo:2:7 (unavailable) (deleted) [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXMethod=bar:3:7 [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXConstructor=Foo:4:3 (unavailable) (default constructor) (deleted) [type=void (){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] +// CHECK: CXXConstructor=Foo:5:3 (converting constructor) [type=void (int){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [int] [Int]] [isPOD=0] Index: clang/test/Index/availability.cpp === --- clang/test/Index/availability.cpp +++ clang/test/Index/availability.cpp @@ -9,5 +9,5 @@ // RUN: c-index-test -test-print-type --std
[PATCH] D133924: add clang_CXXMethod_isDeleted function
anderslanglands updated this revision to Diff 460549. anderslanglands added a comment. Updating based on review - Add new function to release notes - Fix failing test and add a new test specifically for this function Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D133924/new/ https://reviews.llvm.org/D133924 Files: clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/availability.cpp clang/test/Index/deletion.cpp Index: clang/test/Index/deletion.cpp === --- /dev/null +++ clang/test/Index/deletion.cpp @@ -0,0 +1,14 @@ +struct Foo { + int foo() = delete; + int bar(); + Foo() = delete; + Foo(int); +}; + + +// RUN: c-index-test -test-print-type --std=c++11 %s | FileCheck %s +// CHECK: StructDecl=Foo:1:8 (Definition) [type=Foo] [typekind=Record] [isPOD=1] +// CHECK: CXXMethod=foo:2:7 (unavailable) (deleted) [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXMethod=bar:3:7 [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXConstructor=Foo:4:3 (unavailable) (default constructor) (deleted) [type=void (){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] +// CHECK: CXXConstructor=Foo:5:3 (converting constructor) [type=void (int){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [int] [Int]] [isPOD=0] Index: clang/test/Index/availability.cpp === --- clang/test/Index/availability.cpp +++ clang/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) (default constructor) [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: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -4925,7 +4925,7 @@ CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C); /** - * Determine if a C++ method is declared '= default'. + * Determine if a C++ method is declared '= delete'. */ CINDEX_LINKAGE unsigned clang_CXXMethod_isDeleted(CXCursor C); Index: clang/docs/ReleaseNotes.rst === --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -319,6 +319,8 @@ the behavior of `QualType::getUnqualifiedType` for `CXType`. - Introduced the new function `clang_getNonReferenceType`, which mimics the behavior of `QualType::getNonReferenceType` for `CXType`. +- Introduced the new function `clang_CXXMethod_isDeleted`, which queries + whether the method is declared `= delete. Static Analyzer --- Index: clang/test/Index/deletion.cpp === --- /dev/null +++ clang/test/Index/deletion.cpp @@ -0,0 +1,14 @@ +struct Foo { + int foo() = delete; + int bar(); + Foo() = delete; + Foo(int); +}; + + +// RUN: c-index-test -test-print-type --std=c++11 %s | FileCheck %s +// CHECK: StructDecl=Foo:1:8 (Definition) [type=Foo] [typekind=Record] [isPOD=1] +// CHECK: CXXMethod=foo:2:7 (unavailable) (deleted) [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXMethod=bar:3:7 [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXConstructor=Foo:4:3 (unavailable) (default constructor) (deleted) [type=void (){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] +// CHECK: CXXConstructor=Foo:5:3 (converting constructor) [type=void (int){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [int] [Int]] [isPOD=0] Index: clang/test/Index/availability.cpp === --- clang/test/Index/availability.cpp +++ clang/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 (unavail
[PATCH] D133991: add new function to release notes
anderslanglands added a comment. Sorry, this was supposed to update https://reviews.llvm.org/D13392. How do I delete this? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D133991/new/ https://reviews.llvm.org/D133991 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D133924: add clang_CXXMethod_isDeleted function
anderslanglands updated this revision to Diff 460663. anderslanglands added a comment. squashing all commits into one to hopefully fix the revision Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D133924/new/ https://reviews.llvm.org/D133924 Files: clang/bindings/python/clang/cindex.py clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/availability.cpp clang/test/Index/deletion.cpp clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CIndex.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -409,6 +409,7 @@ global: clang_getUnqualifiedType; clang_getNonReferenceType; +clang_CXXMethod_isDeleted; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CIndex.cpp === --- clang/tools/libclang/CIndex.cpp +++ clang/tools/libclang/CIndex.cpp @@ -8861,6 +8861,16 @@ 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: clang/tools/c-index-test/c-index-test.c === --- clang/tools/c-index-test/c-index-test.c +++ clang/tools/c-index-test/c-index-test.c @@ -900,6 +900,8 @@ printf(" (mutable)"); if (clang_CXXMethod_isDefaulted(Cursor)) printf(" (defaulted)"); +if (clang_CXXMethod_isDeleted(Cursor)) + printf(" (deleted)"); if (clang_CXXMethod_isStatic(Cursor)) printf(" (static)"); if (clang_CXXMethod_isVirtual(Cursor)) Index: clang/test/Index/deletion.cpp === --- /dev/null +++ clang/test/Index/deletion.cpp @@ -0,0 +1,14 @@ +struct Foo { + int foo() = delete; + int bar(); + Foo() = delete; + Foo(int); +}; + + +// RUN: c-index-test -test-print-type --std=c++11 %s | FileCheck %s +// CHECK: StructDecl=Foo:1:8 (Definition) [type=Foo] [typekind=Record] [isPOD=1] +// CHECK: CXXMethod=foo:2:7 (unavailable) (deleted) [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXMethod=bar:3:7 [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXConstructor=Foo:4:3 (unavailable) (default constructor) (deleted) [type=void (){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] +// CHECK: CXXConstructor=Foo:5:3 (converting constructor) [type=void (int){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [int] [Int]] [isPOD=0] Index: clang/test/Index/availability.cpp === --- clang/test/Index/availability.cpp +++ clang/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) (default constructor) [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: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -4924,6 +4924,11 @@ */ CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C); +/** + * Determine if a C++ method is declared '= delete'. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isDeleted(CXCursor C); + /** * Determine if a C++ member function or member function template is * pure virtual. Index: clang/docs/ReleaseNotes.rst === --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -319,6 +319,8 @@ the behavior of
[PATCH] D133924: add clang_CXXMethod_isDeleted function
anderslanglands updated this revision to Diff 460672. anderslanglands added a comment. Adding in the dyn_cast_is_present change I missed on the previous one Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D133924/new/ https://reviews.llvm.org/D133924 Files: clang/bindings/python/clang/cindex.py clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/availability.cpp clang/test/Index/deletion.cpp clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CIndex.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -409,6 +409,7 @@ global: clang_getUnqualifiedType; clang_getNonReferenceType; +clang_CXXMethod_isDeleted; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CIndex.cpp === --- clang/tools/libclang/CIndex.cpp +++ clang/tools/libclang/CIndex.cpp @@ -8861,6 +8861,16 @@ 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_if_present(D->getAsFunction()) : nullptr; + return (Method && Method->isDeleted()) ? 1 : 0; +} + unsigned clang_CXXMethod_isStatic(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; Index: clang/tools/c-index-test/c-index-test.c === --- clang/tools/c-index-test/c-index-test.c +++ clang/tools/c-index-test/c-index-test.c @@ -900,6 +900,8 @@ printf(" (mutable)"); if (clang_CXXMethod_isDefaulted(Cursor)) printf(" (defaulted)"); +if (clang_CXXMethod_isDeleted(Cursor)) + printf(" (deleted)"); if (clang_CXXMethod_isStatic(Cursor)) printf(" (static)"); if (clang_CXXMethod_isVirtual(Cursor)) Index: clang/test/Index/deletion.cpp === --- /dev/null +++ clang/test/Index/deletion.cpp @@ -0,0 +1,14 @@ +struct Foo { + int foo() = delete; + int bar(); + Foo() = delete; + Foo(int); +}; + + +// RUN: c-index-test -test-print-type --std=c++11 %s | FileCheck %s +// CHECK: StructDecl=Foo:1:8 (Definition) [type=Foo] [typekind=Record] [isPOD=1] +// CHECK: CXXMethod=foo:2:7 (unavailable) (deleted) [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXMethod=bar:3:7 [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXConstructor=Foo:4:3 (unavailable) (default constructor) (deleted) [type=void (){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] +// CHECK: CXXConstructor=Foo:5:3 (converting constructor) [type=void (int){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [int] [Int]] [isPOD=0] Index: clang/test/Index/availability.cpp === --- clang/test/Index/availability.cpp +++ clang/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) (default constructor) [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: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -4924,6 +4924,11 @@ */ CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C); +/** + * Determine if a C++ method is declared '= delete'. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isDeleted(CXCursor C); + /** * Determine if a C++ member function or member function template is * pure virtual. Index: clang/docs/ReleaseNotes.rst === --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -319,6 +319,8 @@ the
[PATCH] D133924: add clang_CXXMethod_isDeleted function
anderslanglands added a comment. OK that should all be good now. Thanks for your patience, it's my first time doing all this. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D133924/new/ https://reviews.llvm.org/D133924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D133924: add clang_CXXMethod_isDeleted function
anderslanglands updated this revision to Diff 460865. anderslanglands added a comment. Adding missing backtick Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D133924/new/ https://reviews.llvm.org/D133924 Files: clang/bindings/python/clang/cindex.py clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/availability.cpp clang/test/Index/deletion.cpp clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CIndex.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -409,6 +409,7 @@ global: clang_getUnqualifiedType; clang_getNonReferenceType; +clang_CXXMethod_isDeleted; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CIndex.cpp === --- clang/tools/libclang/CIndex.cpp +++ clang/tools/libclang/CIndex.cpp @@ -8861,6 +8861,16 @@ 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_if_present(D->getAsFunction()) : nullptr; + return (Method && Method->isDeleted()) ? 1 : 0; +} + unsigned clang_CXXMethod_isStatic(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; Index: clang/tools/c-index-test/c-index-test.c === --- clang/tools/c-index-test/c-index-test.c +++ clang/tools/c-index-test/c-index-test.c @@ -900,6 +900,8 @@ printf(" (mutable)"); if (clang_CXXMethod_isDefaulted(Cursor)) printf(" (defaulted)"); +if (clang_CXXMethod_isDeleted(Cursor)) + printf(" (deleted)"); if (clang_CXXMethod_isStatic(Cursor)) printf(" (static)"); if (clang_CXXMethod_isVirtual(Cursor)) Index: clang/test/Index/deletion.cpp === --- /dev/null +++ clang/test/Index/deletion.cpp @@ -0,0 +1,14 @@ +struct Foo { + int foo() = delete; + int bar(); + Foo() = delete; + Foo(int); +}; + + +// RUN: c-index-test -test-print-type --std=c++11 %s | FileCheck %s +// CHECK: StructDecl=Foo:1:8 (Definition) [type=Foo] [typekind=Record] [isPOD=1] +// CHECK: CXXMethod=foo:2:7 (unavailable) (deleted) [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXMethod=bar:3:7 [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXConstructor=Foo:4:3 (unavailable) (default constructor) (deleted) [type=void (){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] +// CHECK: CXXConstructor=Foo:5:3 (converting constructor) [type=void (int){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [int] [Int]] [isPOD=0] Index: clang/test/Index/availability.cpp === --- clang/test/Index/availability.cpp +++ clang/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) (default constructor) [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: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -4924,6 +4924,11 @@ */ CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C); +/** + * Determine if a C++ method is declared '= delete'. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isDeleted(CXCursor C); + /** * Determine if a C++ member function or member function template is * pure virtual. Index: clang/docs/ReleaseNotes.rst === --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -319,6 +319,8 @@ the behavior of `QualType::getUnqualifiedType` fo
[PATCH] D133924: add clang_CXXMethod_isDeleted function
anderslanglands added a comment. Yes it's probably safest if someone commits on my behalf, unless someone's got time to walk me through it. Just use Anders Langlands anderslanga...@gmail.com for attribution please. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D133924/new/ https://reviews.llvm.org/D133924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D134416: Allow getting template args for ClassTemplateSpecializations
anderslanglands created this revision. Herald added a project: All. anderslanglands requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Modifies clang_Cursor_getNumTemplateArguments() and friends to work on Struct, Class and ClassTemplatePartialSpecialization decls as well as functions Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D134416 Files: clang/docs/ReleaseNotes.rst clang/tools/libclang/CXCursor.cpp Index: clang/tools/libclang/CXCursor.cpp === --- clang/tools/libclang/CXCursor.cpp +++ clang/tools/libclang/CXCursor.cpp @@ -1353,34 +1353,42 @@ } int clang_Cursor_getNumTemplateArguments(CXCursor C) { - if (clang_getCursorKind(C) != CXCursor_FunctionDecl) { + CXCursorKind kind = clang_getCursorKind(C); + if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl && + kind != CXCursor_ClassDecl && + kind != CXCursor_ClassTemplatePartialSpecialization) { return -1; } - const FunctionDecl *FD = - llvm::dyn_cast_or_null(getCursorDecl(C)); - if (!FD) { -return -1; - } - - const FunctionTemplateSpecializationInfo *SpecInfo = - FD->getTemplateSpecializationInfo(); - if (!SpecInfo) { + if (const FunctionDecl *FD = + llvm::dyn_cast_if_present(getCursorDecl(C))) { +const FunctionTemplateSpecializationInfo *SpecInfo = +FD->getTemplateSpecializationInfo(); +if (!SpecInfo) { + return -1; +} +return SpecInfo->TemplateArguments->size(); + } else if (const ClassTemplateSpecializationDecl *SD = + llvm::dyn_cast_if_present< + clang::ClassTemplateSpecializationDecl>( + getCursorDecl(C))) { +return SD->getTemplateArgs().size(); + } else { return -1; } - - return SpecInfo->TemplateArguments->size(); } enum CXGetTemplateArgumentStatus { /** The operation completed successfully */ CXGetTemplateArgumentStatus_Success = 0, - /** The specified cursor did not represent a FunctionDecl. */ - CXGetTemplateArgumentStatus_CursorNotFunctionDecl = -1, + /** The specified cursor did not represent a FunctionDecl or + ClassTemplateSpecializationDecl. */ + CXGetTemplateArgumentStatus_CursorNotCompatibleDecl = -1, - /** The specified cursor was not castable to a FunctionDecl. */ - CXGetTemplateArgumentStatus_BadFunctionDeclCast = -2, + /** The specified cursor was not castable to a FunctionDecl or + ClassTemplateSpecializationDecl. */ + CXGetTemplateArgumentStatus_BadDeclCast = -2, /** A NULL FunctionTemplateSpecializationInfo was retrieved. */ CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3, @@ -1391,28 +1399,43 @@ static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I, TemplateArgument *TA) { - if (clang_getCursorKind(C) != CXCursor_FunctionDecl) { -return CXGetTemplateArgumentStatus_CursorNotFunctionDecl; + CXCursorKind kind = clang_getCursorKind(C); + if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl && + kind != CXCursor_ClassDecl && + kind != CXCursor_ClassTemplatePartialSpecialization) { +return -1; } - const FunctionDecl *FD = - llvm::dyn_cast_or_null(getCursorDecl(C)); - if (!FD) { -return CXGetTemplateArgumentStatus_BadFunctionDeclCast; - } + if (const FunctionDecl *FD = + llvm::dyn_cast_if_present(getCursorDecl(C))) { - const FunctionTemplateSpecializationInfo *SpecInfo = - FD->getTemplateSpecializationInfo(); - if (!SpecInfo) { -return CXGetTemplateArgumentStatus_NullTemplSpecInfo; - } +const FunctionTemplateSpecializationInfo *SpecInfo = +FD->getTemplateSpecializationInfo(); +if (!SpecInfo) { + return CXGetTemplateArgumentStatus_NullTemplSpecInfo; +} - if (I >= SpecInfo->TemplateArguments->size()) { -return CXGetTemplateArgumentStatus_InvalidIndex; - } +if (I >= SpecInfo->TemplateArguments->size()) { + return CXGetTemplateArgumentStatus_InvalidIndex; +} - *TA = SpecInfo->TemplateArguments->get(I); - return 0; +*TA = SpecInfo->TemplateArguments->get(I); +return 0; + } else if (const ClassTemplateSpecializationDecl *SD = + llvm::dyn_cast_if_present< + clang::ClassTemplateSpecializationDecl>( + getCursorDecl(C))) { +if (I >= SD->getTemplateArgs().size()) { + printf("INVALID INDEX\n"); + return CXGetTemplateArgumentStatus_InvalidIndex; +} + +*TA = SD->getTemplateArgs()[I]; +return 0; + } else { +printf("CAST FAILED\n"); +return CXGetTemplateArgumentStatus_BadDeclCast; + } } enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C, Index: clang/docs/ReleaseNotes.rst === ---
[PATCH] D134416: Allow getting template args for ClassTemplateSpecializations
anderslanglands added reviewers: tbaeder, aaron.ballman. anderslanglands added a comment. Hello again, this generalizes the template argument functionality to operate on cursor kinds other than functions. I could use some help creating a test for this. On my previous path I was able to just copy/paste and modify an existing test, but from a quick scan of the current tests I can't see how I'd modify one of them to test this functionality. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D134416/new/ https://reviews.llvm.org/D134416 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D134416: Allow getting template args for ClassTemplateSpecializations
anderslanglands updated this revision to Diff 462103. anderslanglands added a comment. Herald added a subscriber: arphaman. Updating doc comments to reflect new functionality Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D134416/new/ https://reviews.llvm.org/D134416 Files: clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/tools/libclang/CXCursor.cpp Index: clang/tools/libclang/CXCursor.cpp === --- clang/tools/libclang/CXCursor.cpp +++ clang/tools/libclang/CXCursor.cpp @@ -1353,34 +1353,42 @@ } int clang_Cursor_getNumTemplateArguments(CXCursor C) { - if (clang_getCursorKind(C) != CXCursor_FunctionDecl) { + CXCursorKind kind = clang_getCursorKind(C); + if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl && + kind != CXCursor_ClassDecl && + kind != CXCursor_ClassTemplatePartialSpecialization) { return -1; } - const FunctionDecl *FD = - llvm::dyn_cast_or_null(getCursorDecl(C)); - if (!FD) { -return -1; - } - - const FunctionTemplateSpecializationInfo *SpecInfo = - FD->getTemplateSpecializationInfo(); - if (!SpecInfo) { + if (const FunctionDecl *FD = + llvm::dyn_cast_if_present(getCursorDecl(C))) { +const FunctionTemplateSpecializationInfo *SpecInfo = +FD->getTemplateSpecializationInfo(); +if (!SpecInfo) { + return -1; +} +return SpecInfo->TemplateArguments->size(); + } else if (const ClassTemplateSpecializationDecl *SD = + llvm::dyn_cast_if_present< + clang::ClassTemplateSpecializationDecl>( + getCursorDecl(C))) { +return SD->getTemplateArgs().size(); + } else { return -1; } - - return SpecInfo->TemplateArguments->size(); } enum CXGetTemplateArgumentStatus { /** The operation completed successfully */ CXGetTemplateArgumentStatus_Success = 0, - /** The specified cursor did not represent a FunctionDecl. */ - CXGetTemplateArgumentStatus_CursorNotFunctionDecl = -1, + /** The specified cursor did not represent a FunctionDecl or + ClassTemplateSpecializationDecl. */ + CXGetTemplateArgumentStatus_CursorNotCompatibleDecl = -1, - /** The specified cursor was not castable to a FunctionDecl. */ - CXGetTemplateArgumentStatus_BadFunctionDeclCast = -2, + /** The specified cursor was not castable to a FunctionDecl or + ClassTemplateSpecializationDecl. */ + CXGetTemplateArgumentStatus_BadDeclCast = -2, /** A NULL FunctionTemplateSpecializationInfo was retrieved. */ CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3, @@ -1391,28 +1399,43 @@ static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I, TemplateArgument *TA) { - if (clang_getCursorKind(C) != CXCursor_FunctionDecl) { -return CXGetTemplateArgumentStatus_CursorNotFunctionDecl; + CXCursorKind kind = clang_getCursorKind(C); + if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl && + kind != CXCursor_ClassDecl && + kind != CXCursor_ClassTemplatePartialSpecialization) { +return -1; } - const FunctionDecl *FD = - llvm::dyn_cast_or_null(getCursorDecl(C)); - if (!FD) { -return CXGetTemplateArgumentStatus_BadFunctionDeclCast; - } + if (const FunctionDecl *FD = + llvm::dyn_cast_if_present(getCursorDecl(C))) { - const FunctionTemplateSpecializationInfo *SpecInfo = - FD->getTemplateSpecializationInfo(); - if (!SpecInfo) { -return CXGetTemplateArgumentStatus_NullTemplSpecInfo; - } +const FunctionTemplateSpecializationInfo *SpecInfo = +FD->getTemplateSpecializationInfo(); +if (!SpecInfo) { + return CXGetTemplateArgumentStatus_NullTemplSpecInfo; +} - if (I >= SpecInfo->TemplateArguments->size()) { -return CXGetTemplateArgumentStatus_InvalidIndex; - } +if (I >= SpecInfo->TemplateArguments->size()) { + return CXGetTemplateArgumentStatus_InvalidIndex; +} - *TA = SpecInfo->TemplateArguments->get(I); - return 0; +*TA = SpecInfo->TemplateArguments->get(I); +return 0; + } else if (const ClassTemplateSpecializationDecl *SD = + llvm::dyn_cast_if_present< + clang::ClassTemplateSpecializationDecl>( + getCursorDecl(C))) { +if (I >= SD->getTemplateArgs().size()) { + printf("INVALID INDEX\n"); + return CXGetTemplateArgumentStatus_InvalidIndex; +} + +*TA = SD->getTemplateArgs()[I]; +return 0; + } else { +printf("CAST FAILED\n"); +return CXGetTemplateArgumentStatus_BadDeclCast; + } } enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C, Index: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@
[PATCH] D134416: Allow getting template args for ClassTemplateSpecializations
anderslanglands updated this revision to Diff 462392. anderslanglands marked 7 inline comments as done. anderslanglands added a comment. Add testing, address style notes Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D134416/new/ https://reviews.llvm.org/D134416 Files: clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/get-cursor.cpp clang/test/Index/index-templates.cpp clang/test/Index/print-display-names.cpp clang/test/Index/print-type.cpp clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CXCursor.cpp Index: clang/tools/libclang/CXCursor.cpp === --- clang/tools/libclang/CXCursor.cpp +++ clang/tools/libclang/CXCursor.cpp @@ -1353,34 +1353,43 @@ } int clang_Cursor_getNumTemplateArguments(CXCursor C) { - if (clang_getCursorKind(C) != CXCursor_FunctionDecl) { + CXCursorKind kind = clang_getCursorKind(C); + if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl && + kind != CXCursor_ClassDecl && + kind != CXCursor_ClassTemplatePartialSpecialization) { return -1; } - const FunctionDecl *FD = - llvm::dyn_cast_or_null(getCursorDecl(C)); - if (!FD) { -return -1; + if (const auto *FD = + llvm::dyn_cast_if_present(getCursorDecl(C))) { +const FunctionTemplateSpecializationInfo *SpecInfo = +FD->getTemplateSpecializationInfo(); +if (!SpecInfo) { + return -1; +} +return SpecInfo->TemplateArguments->size(); } - const FunctionTemplateSpecializationInfo *SpecInfo = - FD->getTemplateSpecializationInfo(); - if (!SpecInfo) { -return -1; + if (const auto *SD = + llvm::dyn_cast_if_present( + getCursorDecl(C))) { +return SD->getTemplateArgs().size(); } - return SpecInfo->TemplateArguments->size(); + return -1; } enum CXGetTemplateArgumentStatus { /** The operation completed successfully */ CXGetTemplateArgumentStatus_Success = 0, - /** The specified cursor did not represent a FunctionDecl. */ - CXGetTemplateArgumentStatus_CursorNotFunctionDecl = -1, + /** The specified cursor did not represent a FunctionDecl or + ClassTemplateSpecializationDecl. */ + CXGetTemplateArgumentStatus_CursorNotCompatibleDecl = -1, - /** The specified cursor was not castable to a FunctionDecl. */ - CXGetTemplateArgumentStatus_BadFunctionDeclCast = -2, + /** The specified cursor was not castable to a FunctionDecl or + ClassTemplateSpecializationDecl. */ + CXGetTemplateArgumentStatus_BadDeclCast = -2, /** A NULL FunctionTemplateSpecializationInfo was retrieved. */ CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3, @@ -1391,28 +1400,42 @@ static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I, TemplateArgument *TA) { - if (clang_getCursorKind(C) != CXCursor_FunctionDecl) { -return CXGetTemplateArgumentStatus_CursorNotFunctionDecl; + CXCursorKind kind = clang_getCursorKind(C); + if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl && + kind != CXCursor_ClassDecl && + kind != CXCursor_ClassTemplatePartialSpecialization) { +return -1; } - const FunctionDecl *FD = - llvm::dyn_cast_or_null(getCursorDecl(C)); - if (!FD) { -return CXGetTemplateArgumentStatus_BadFunctionDeclCast; - } + if (const auto *FD = + llvm::dyn_cast_if_present(getCursorDecl(C))) { + +const FunctionTemplateSpecializationInfo *SpecInfo = +FD->getTemplateSpecializationInfo(); +if (!SpecInfo) { + return CXGetTemplateArgumentStatus_NullTemplSpecInfo; +} - const FunctionTemplateSpecializationInfo *SpecInfo = - FD->getTemplateSpecializationInfo(); - if (!SpecInfo) { -return CXGetTemplateArgumentStatus_NullTemplSpecInfo; +if (I >= SpecInfo->TemplateArguments->size()) { + return CXGetTemplateArgumentStatus_InvalidIndex; +} + +*TA = SpecInfo->TemplateArguments->get(I); +return 0; } - if (I >= SpecInfo->TemplateArguments->size()) { -return CXGetTemplateArgumentStatus_InvalidIndex; + if (const auto *SD = + llvm::dyn_cast_if_present( + getCursorDecl(C))) { +if (I >= SD->getTemplateArgs().size()) { + return CXGetTemplateArgumentStatus_InvalidIndex; +} + +*TA = SD->getTemplateArgs()[I]; +return 0; } - *TA = SpecInfo->TemplateArguments->get(I); - return 0; + return CXGetTemplateArgumentStatus_BadDeclCast; } enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C, Index: clang/tools/c-index-test/c-index-test.c === --- clang/tools/c-index-test/c-index-test.c +++ clang/tools/c-index-test/c-index-test.c @@ -1002,7 +1002,10 @@ clang_getCString(Name), line, column); clang_disposeStri
[PATCH] D134416: Allow getting template args for ClassTemplateSpecializations
anderslanglands added a comment. I ended up modifying c-index-test to print out the template arguments in the same way it does for FunctionDecl, which ends up working all cases in the existing test suite. The only other thing I added was a specific case in index-templates.cpp to check whether it catches StructDecl too (it does). Comment at: clang/tools/libclang/CXCursor.cpp:1357 + CXCursorKind kind = clang_getCursorKind(C); + if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl && + kind != CXCursor_ClassDecl && aaron.ballman wrote: > `CXCursor_StructDecl` is interesting -- does that only get used in C or will > it also show up in C++? If it's C-only, we can drop that bit. It does. I added a case to index-templates.cpp that tests for this. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D134416/new/ https://reviews.llvm.org/D134416 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D135557: Add needsImplicitDefaultConstructor and friends
anderslanglands created this revision. Herald added a subscriber: arphaman. Herald added a project: All. anderslanglands requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Wraps CXXRecord::needsImplicitDefaultConstructor, needsImplicitCopyConstructor, etc. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D135557 Files: clang/bindings/python/clang/cindex.py clang/include/clang-c/Index.h clang/test/Index/annotate-attribute.cpp clang/test/Index/availability.cpp clang/test/Index/deletion.cpp clang/test/Index/file-refs.cpp clang/test/Index/get-cursor.cpp clang/test/Index/index-templates.cpp clang/test/Index/keep-going.cpp clang/test/Index/load-stmts.cpp clang/test/Index/print-display-names.cpp clang/test/Index/print-type-size.cpp clang/test/Index/print-type.cpp clang/test/Index/recursive-cxx-member-calls.cpp clang/test/Index/redeclarations.cpp clang/test/Parser/skip-function-bodies.mm clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CIndex.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -410,6 +410,15 @@ clang_getUnqualifiedType; clang_getNonReferenceType; clang_CXXMethod_isDeleted; +clang_CXXRecord_defaultedCopyConstructorIsDeleted; +clang_CXXRecord_defaultedMoveConstructorIsDeleted; +clang_CXXRecord_defaultedDestructorIsDeleted; +clang_CXXRecord_needsImplicitDefaultConstructor; +clang_CXXRecord_needsImplicitCopyConstructor; +clang_CXXRecord_needsImplicitCopyAssignment; +clang_CXXRecord_needsImplicitMoveConstructor; +clang_CXXRecord_needsImplicitMoveAssignment; +clang_CXXRecord_needsImplicitDestructor; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CIndex.cpp === --- clang/tools/libclang/CIndex.cpp +++ clang/tools/libclang/CIndex.cpp @@ -8903,6 +8903,105 @@ return (RD && RD->isAbstract()) ? 1 : 0; } +unsigned clang_CXXRecord_defaultedCopyConstructorIsDeleted(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD && !RD->isUnion()) +RD = RD->getDefinition(); + return (RD && RD->defaultedCopyConstructorIsDeleted()) ? 1 : 0; +} + +unsigned clang_CXXRecord_defaultedMoveConstructorIsDeleted(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->defaultedMoveConstructorIsDeleted()) ? 1 : 0; +} + +unsigned clang_CXXRecord_defaultedDestructorIsDeleted(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->defaultedDestructorIsDeleted()) ? 1 : 0; +} + +unsigned clang_CXXRecord_needsImplicitDefaultConstructor(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->needsImplicitDefaultConstructor()) ? 1 : 0; +} + +unsigned clang_CXXRecord_needsImplicitCopyConstructor(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->needsImplicitDefaultConstructor()) ? 1 : 0; +} + +unsigned clang_CXXRecord_needsImplicitCopyAssignment(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->needsImplicitCopyAssignment()) ? 1 : 0; +} + +unsigned clang_CXXRecord_needsImplicitMoveConstructor(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->needsImplicitDefaultConstructor()) ? 1 : 0; +} + +unsigned clang_CXXRecord_needsImplicitMoveAssignment(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->needsImplicitMoveAssignment()) ? 1 : 0; +} + +unsigned clang_CXXRecord
[PATCH] D135557: Add needsImplicitDefaultConstructor and friends
anderslanglands updated this revision to Diff 48. anderslanglands added a comment. Fixed clang-format error Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D135557/new/ https://reviews.llvm.org/D135557 Files: clang/bindings/python/clang/cindex.py clang/include/clang-c/Index.h clang/test/Index/annotate-attribute.cpp clang/test/Index/availability.cpp clang/test/Index/deletion.cpp clang/test/Index/file-refs.cpp clang/test/Index/get-cursor.cpp clang/test/Index/index-templates.cpp clang/test/Index/keep-going.cpp clang/test/Index/load-stmts.cpp clang/test/Index/print-display-names.cpp clang/test/Index/print-type-size.cpp clang/test/Index/print-type.cpp clang/test/Index/recursive-cxx-member-calls.cpp clang/test/Index/redeclarations.cpp clang/test/Parser/skip-function-bodies.mm clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CIndex.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -410,6 +410,15 @@ clang_getUnqualifiedType; clang_getNonReferenceType; clang_CXXMethod_isDeleted; +clang_CXXRecord_defaultedCopyConstructorIsDeleted; +clang_CXXRecord_defaultedMoveConstructorIsDeleted; +clang_CXXRecord_defaultedDestructorIsDeleted; +clang_CXXRecord_needsImplicitDefaultConstructor; +clang_CXXRecord_needsImplicitCopyConstructor; +clang_CXXRecord_needsImplicitCopyAssignment; +clang_CXXRecord_needsImplicitMoveConstructor; +clang_CXXRecord_needsImplicitMoveAssignment; +clang_CXXRecord_needsImplicitDestructor; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CIndex.cpp === --- clang/tools/libclang/CIndex.cpp +++ clang/tools/libclang/CIndex.cpp @@ -2181,8 +2181,8 @@ void VisitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective *D); void VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D); - void VisitOMPMaskedTaskLoopSimdDirective( - const OMPMaskedTaskLoopSimdDirective *D); + void + VisitOMPMaskedTaskLoopSimdDirective(const OMPMaskedTaskLoopSimdDirective *D); void VisitOMPParallelMasterTaskLoopDirective( const OMPParallelMasterTaskLoopDirective *D); void VisitOMPParallelMaskedTaskLoopDirective( @@ -4767,7 +4767,7 @@ int reserved; enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor, CXCursor); -} * CXCursorVisitorBlock; +} *CXCursorVisitorBlock; static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent, CXClientData client_data) { @@ -8903,6 +8903,109 @@ return (RD && RD->isAbstract()) ? 1 : 0; } +unsigned clang_CXXRecord_defaultedCopyConstructorIsDeleted(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD && !RD->isUnion()) +RD = RD->getDefinition(); + return (RD && RD->defaultedCopyConstructorIsDeleted()) ? 1 : 0; +} + +unsigned clang_CXXRecord_defaultedMoveConstructorIsDeleted(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->defaultedMoveConstructorIsDeleted()) ? 1 + : 0; +} + +unsigned clang_CXXRecord_defaultedDestructorIsDeleted(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->defaultedDestructorIsDeleted()) ? 1 : 0; +} + +unsigned clang_CXXRecord_needsImplicitDefaultConstructor(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->needsImplicitDefaultConstructor()) ? 1 + : 0; +} + +unsigned clang_CXXRecord_needsImplicitCopyConstructor(CXCursor C) { + if (!clang_isDeclaration(C.kind)) +return 0; + + const auto *D = cxcursor::getCursorDecl(C); + const auto *RD = dyn_cast_if_present(D); + if (RD) +RD = RD->getDefinition(); + return (RD && !RD->isUnion() && RD->needsImplicitDefaultConstructor()) ? 1 + : 0; +} + +unsigned clang_CXXRecord_needsImplicitCopyAssignment(CXCur
[PATCH] D135557: Add needsImplicitDefaultConstructor and friends
anderslanglands added inline comments. Comment at: clang/bindings/python/clang/cindex.py:1530 + +def record_needs_implicit_default_constructor(self): +"""Returns True if the cursor refers to a C++ record declaration royjacobson wrote: > aaron.ballman wrote: > > aaron.ballman wrote: > > > I don't think we should expose any of the "needs" functions like this -- > > > those are internal implementation details of the class and I don't think > > > we want to calcify that into something we have to support forever. As we > > > add members to a class, we recalculate whether the added member causes us > > > to delete defaulted special members (among other things), and the "needs" > > > functions are basically used when the class is completed to handle lazily > > > created special members. I'm pretty sure that lazy creation is not > > > mandated by the standard, which is why I think the "needs" functions are > > > more of an implementation detail. > > CC @erichkeane and @royjacobson as folks who have been in this same area of > > the compiler to see if they agree or disagree with my assessment there. > I think so. The 'needs_*' functions query `DeclaredSpecialMembers` and I'm > pretty sure it's modified when we add the implicit definitions in the class > completion code. So this looks a bit suspicious. Is this API //meant// to be > used with incomplete classes? > For complete classes I think looking up the default/move/copy constructor and > calling `isImplicit()` is the way to do it. > > About the 'is deleted' API - can't the same be done for those functions as > well so we have a smaller API? > > If this //is// meant to be used with incomplete classes for efficiency that > would be another thing, I guess. > So the intended use case here is I'm using libclang to parse an existing C++ libray's headers and generate a C interface to it. To do that I need to know if I need to generate default constructors etc, which the needs* methods do for me (I believe). The alternative is I have to check manually whether all the constructors/assignment operators exist, then implement the implicit declaration rules myself correctly for each version of the standard, which I'd rather avoid. Would putting a note in the doc comment about the behaviour differing when the class is being constructed as originally suggested work for everyone? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D135557/new/ https://reviews.llvm.org/D135557 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D135557: Add needsImplicitDefaultConstructor and friends
anderslanglands added inline comments. Comment at: clang/bindings/python/clang/cindex.py:1530 + +def record_needs_implicit_default_constructor(self): +"""Returns True if the cursor refers to a C++ record declaration royjacobson wrote: > anderslanglands wrote: > > royjacobson wrote: > > > aaron.ballman wrote: > > > > aaron.ballman wrote: > > > > > I don't think we should expose any of the "needs" functions like this > > > > > -- those are internal implementation details of the class and I don't > > > > > think we want to calcify that into something we have to support > > > > > forever. As we add members to a class, we recalculate whether the > > > > > added member causes us to delete defaulted special members (among > > > > > other things), and the "needs" functions are basically used when the > > > > > class is completed to handle lazily created special members. I'm > > > > > pretty sure that lazy creation is not mandated by the standard, which > > > > > is why I think the "needs" functions are more of an implementation > > > > > detail. > > > > CC @erichkeane and @royjacobson as folks who have been in this same > > > > area of the compiler to see if they agree or disagree with my > > > > assessment there. > > > I think so. The 'needs_*' functions query `DeclaredSpecialMembers` and > > > I'm pretty sure it's modified when we add the implicit definitions in the > > > class completion code. So this looks a bit suspicious. Is this API > > > //meant// to be used with incomplete classes? > > > For complete classes I think looking up the default/move/copy constructor > > > and calling `isImplicit()` is the way to do it. > > > > > > About the 'is deleted' API - can't the same be done for those functions > > > as well so we have a smaller API? > > > > > > If this //is// meant to be used with incomplete classes for efficiency > > > that would be another thing, I guess. > > > > > So the intended use case here is I'm using libclang to parse an existing > > C++ libray's headers and generate a C interface to it. To do that I need to > > know if I need to generate default constructors etc, which the needs* > > methods do for me (I believe). The alternative is I have to check manually > > whether all the constructors/assignment operators exist, then implement the > > implicit declaration rules myself correctly for each version of the > > standard, which I'd rather avoid. > > > > Would putting a note in the doc comment about the behaviour differing when > > the class is being constructed as originally suggested work for everyone? > Why is the `__is_default_constructible` builtin type trait not enough? Do you > have different behavior for user provided and implicit default constructors? > Can I evaluate that from libclang somewhow? I can't modify the C++ libraries I'm wrapping. Basically, given: ``` struct Foo { /* ... */ }; ``` I want to generate: ``` typedef struct Foo_t; Foo_t* Foo_ctor(); Foo_t* Foo_copy_ctor(Foo_t*); /* etc... */ Foo_dtor(Foo_t*); ``` In order to know which ones to generate for an arbitrary struct that may or may not have any combination of ctor/assignments defined, I need to know which ones exist and follow the implicit generation rules for the ones that don't. I can do this myself with a whole bunch of version-dependent logic, but I'd rather just rely on libclang since it already knows all this much better than I do. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D135557/new/ https://reviews.llvm.org/D135557 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D135557: Add needsImplicitDefaultConstructor and friends
anderslanglands added inline comments. Comment at: clang/bindings/python/clang/cindex.py:1530 + +def record_needs_implicit_default_constructor(self): +"""Returns True if the cursor refers to a C++ record declaration dblaikie wrote: > aaron.ballman wrote: > > royjacobson wrote: > > > anderslanglands wrote: > > > > royjacobson wrote: > > > > > anderslanglands wrote: > > > > > > royjacobson wrote: > > > > > > > aaron.ballman wrote: > > > > > > > > aaron.ballman wrote: > > > > > > > > > I don't think we should expose any of the "needs" functions > > > > > > > > > like this -- those are internal implementation details of the > > > > > > > > > class and I don't think we want to calcify that into > > > > > > > > > something we have to support forever. As we add members to a > > > > > > > > > class, we recalculate whether the added member causes us to > > > > > > > > > delete defaulted special members (among other things), and > > > > > > > > > the "needs" functions are basically used when the class is > > > > > > > > > completed to handle lazily created special members. I'm > > > > > > > > > pretty sure that lazy creation is not mandated by the > > > > > > > > > standard, which is why I think the "needs" functions are more > > > > > > > > > of an implementation detail. > > > > > > > > CC @erichkeane and @royjacobson as folks who have been in this > > > > > > > > same area of the compiler to see if they agree or disagree with > > > > > > > > my assessment there. > > > > > > > I think so. The 'needs_*' functions query > > > > > > > `DeclaredSpecialMembers` and I'm pretty sure it's modified when > > > > > > > we add the implicit definitions in the class completion code. So > > > > > > > this looks a bit suspicious. Is this API //meant// to be used > > > > > > > with incomplete classes? > > > > > > > For complete classes I think looking up the default/move/copy > > > > > > > constructor and calling `isImplicit()` is the way to do it. > > > > > > > > > > > > > > About the 'is deleted' API - can't the same be done for those > > > > > > > functions as well so we have a smaller API? > > > > > > > > > > > > > > If this //is// meant to be used with incomplete classes for > > > > > > > efficiency that would be another thing, I guess. > > > > > > > > > > > > > So the intended use case here is I'm using libclang to parse an > > > > > > existing C++ libray's headers and generate a C interface to it. To > > > > > > do that I need to know if I need to generate default constructors > > > > > > etc, which the needs* methods do for me (I believe). The > > > > > > alternative is I have to check manually whether all the > > > > > > constructors/assignment operators exist, then implement the > > > > > > implicit declaration rules myself correctly for each version of the > > > > > > standard, which I'd rather avoid. > > > > > > > > > > > > Would putting a note in the doc comment about the behaviour > > > > > > differing when the class is being constructed as originally > > > > > > suggested work for everyone? > > > > > Why is the `__is_default_constructible` builtin type trait not > > > > > enough? Do you have different behavior for user provided and implicit > > > > > default constructors? > > > > > > > > > Can I evaluate that from libclang somewhow? I can't modify the C++ > > > > libraries I'm wrapping. > > > > > > > > Basically, given: > > > > ``` > > > > struct Foo { /* ... */ }; > > > > ``` > > > > > > > > I want to generate: > > > > > > > > ``` > > > > typedef struct Foo_t; > > > > > > > > Foo_t* Foo_ctor(); > > > > Foo_t* Foo_copy_ctor(Foo_t*); > > > > /* etc... */ > > > > Foo_dtor(Foo_t*); > > > > ``` > > > > > > > > In order to know which ones to generate for an arbitrary struct that > > > > may or may not have any combination of ctor/assignments defined, I need > > > > to know which ones exist and follow the implicit generation rules for > > > > the ones that don't. I can do this myself with a whole bunch of > > > > version-dependent logic, but I'd rather just rely on libclang since it > > > > already knows all this much better than I do. > > > I looked a bit, and it seems they aren't, and that generally libclang > > > doesn't really know about Sema, so exporting the type traits is not that > > > easy :/ > > > > > > I'm not sure what's the best way forward here, but I don't like the idea > > > of exporting those half baked internal API calls when there are actual > > > standardized and implemented type traits that perform the same goal. > > CCing folks who may have more historical memory of the C APIs and whether > > they're expected to operate on a completed AST or are expected to work on > > an AST as it is under construction. My unverified belief is that these APIs > > are expected to work on a completed AST. > > > > @echristo @dblaikie @rjmccall @rsmith > > > > I'm also not certain of what the best path forward is he
[PATCH] D137818: Add support for querying SubstTemplateTypeParm types
anderslanglands created this revision. anderslanglands added reviewers: tbaeder, aaron.ballman. Herald added subscribers: arphaman, kristof.beyls. Herald added a project: All. anderslanglands requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Adds CXType_SubstTemplateTypeParm and clang_Type_getReplacementType() Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D137818 Files: clang/include/clang-c/Index.h clang/test/Index/print-type.cpp clang/tools/libclang/CXType.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -167,6 +167,7 @@ clang_Type_getSizeOf; clang_Type_getTemplateArgumentAsType; clang_Type_getValueType; +clang_Type_getReplacementType; clang_Type_isTransparentTagTypedef; clang_Type_visitFields; clang_VerbatimBlockLineComment_getText; Index: clang/tools/libclang/CXType.cpp === --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -118,12 +118,17 @@ TKCASE(Attributed); TKCASE(BTFTagAttributed); TKCASE(Atomic); +TKCASE(SubstTemplateTypeParm); default: return CXType_Unexposed; } #undef TKCASE } +static CXTypeKind GetSubstTemplateTypeParmTypeKind(const SubstTemplateTypeParmType* TP) { + const QualType RT = TP->getReplacementType(); + return GetTypeKind(RT); +} CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { CXTypeKind TK = CXType_Invalid; @@ -635,6 +640,7 @@ TKIND(OCLQueue); TKIND(OCLReserveID); TKIND(Atomic); +TKIND(SubstTemplateTypeParm); } #undef TKIND return cxstring::createRef(s); @@ -1355,3 +1361,13 @@ const auto *AT = T->castAs(); return MakeCXType(AT->getValueType(), GetTU(CT)); } + +CXType clang_Type_getReplacementType(CXType CT) { + QualType T = GetQualType(CT); + + if (T.isNull() || T->getTypeClass() != Type::SubstTemplateTypeParm) +return MakeCXType(QualType(), GetTU(CT)); + + const auto *ST = T->castAs(); + return MakeCXType(ST->getReplacementType(), GetTU(CT)); +} \ No newline at end of file Index: clang/test/Index/print-type.cpp === --- clang/test/Index/print-type.cpp +++ clang/test/Index/print-type.cpp @@ -171,7 +171,7 @@ // CHECK: VarDecl=autoI:54:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] // CHECK: VarDecl=autoTbar:55:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] -// CHECK: CallExpr=tbar:36:3 [type=int] [typekind=Unexposed] [canonicaltype=int] [canonicaltypekind=Int] [args= [int] [Int]] [isPOD=1] +// CHECK: CallExpr=tbar:36:3 [type=int] [typekind=SubstTemplateTypeParm] [canonicaltype=int] [canonicaltypekind=Int] [args= [int] [Int]] [isPOD=1] // CHECK: UnexposedExpr=tbar:36:3 [type=int (*)(int)] [typekind=Pointer] [canonicaltype=int (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=int (int)] [pointeekind=FunctionProto] // CHECK: DeclRefExpr=tbar:36:3 RefName=[55:17 - 55:21] RefName=[55:21 - 55:26] [type=int (int)] [typekind=FunctionProto] [canonicaltype=int (int)] [canonicaltypekind=FunctionProto] [isPOD=0] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] Index: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -2789,7 +2789,9 @@ CXType_ExtVector = 176, CXType_Atomic = 177, - CXType_BTFTagAttributed = 178 + CXType_BTFTagAttributed = 178, + /* Represents a type that as been substituted for a template type parameter */ + CXType_SubstTemplateTypeParm = 179 }; /** @@ -3447,6 +3449,13 @@ */ CINDEX_LINKAGE CXType clang_Type_getValueType(CXType CT); +/** + * Gets the replacement type for a SubstTemplateTypeParm type. + * + * If any other type kind is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getReplacementType(CXType CT); + /** * Return the offset of the field represented by the Cursor. * Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -167,6 +167,7 @@ clang_Type_getSizeOf; clang_Type_getTemplateArgumentAsType; clang_Type_getValueType; +clang_Type_getReplacementType; clang_Type_isTransparentTagTypedef; clang_Type_visitFields; clang_VerbatimBlockLineComment_getText; Index: clang/tools/libclang/CXType.cpp === --- clang/tools/libclang/CXType.cpp ++
[PATCH] D137818: Add support for querying SubstTemplateTypeParm types
anderslanglands updated this revision to Diff 476261. anderslanglands added a comment. Added release note, incorporated other review notes Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D137818/new/ https://reviews.llvm.org/D137818 Files: clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/print-type.cpp clang/tools/libclang/CXType.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -164,6 +164,7 @@ clang_Type_getObjCProtocolDecl; clang_Type_getObjCTypeArg; clang_Type_getOffsetOf; +clang_Type_getReplacementType; clang_Type_getSizeOf; clang_Type_getTemplateArgumentAsType; clang_Type_getValueType; Index: clang/tools/libclang/CXType.cpp === --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -118,13 +118,13 @@ TKCASE(Attributed); TKCASE(BTFTagAttributed); TKCASE(Atomic); +TKCASE(SubstTemplateTypeParm); default: return CXType_Unexposed; } #undef TKCASE } - CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { CXTypeKind TK = CXType_Invalid; @@ -635,6 +635,7 @@ TKIND(OCLQueue); TKIND(OCLReserveID); TKIND(Atomic); +TKIND(SubstTemplateTypeParm); } #undef TKIND return cxstring::createRef(s); @@ -1355,3 +1356,11 @@ const auto *AT = T->castAs(); return MakeCXType(AT->getValueType(), GetTU(CT)); } + +CXType clang_Type_getReplacementType(CXType CT) { + QualType T = GetQualType(CT); + + const auto *ST = + !T.isNull() ? T->getAs() : nullptr; + return MakeCXType(ST ? ST->getReplacementType() : QualType(), GetTU(CT)); +} Index: clang/test/Index/print-type.cpp === --- clang/test/Index/print-type.cpp +++ clang/test/Index/print-type.cpp @@ -171,7 +171,7 @@ // CHECK: VarDecl=autoI:54:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] // CHECK: VarDecl=autoTbar:55:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] -// CHECK: CallExpr=tbar:36:3 [type=int] [typekind=Unexposed] [canonicaltype=int] [canonicaltypekind=Int] [args= [int] [Int]] [isPOD=1] +// CHECK: CallExpr=tbar:36:3 [type=int] [typekind=SubstTemplateTypeParm] [canonicaltype=int] [canonicaltypekind=Int] [args= [int] [Int]] [isPOD=1] // CHECK: UnexposedExpr=tbar:36:3 [type=int (*)(int)] [typekind=Pointer] [canonicaltype=int (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=int (int)] [pointeekind=FunctionProto] // CHECK: DeclRefExpr=tbar:36:3 RefName=[55:17 - 55:21] RefName=[55:21 - 55:26] [type=int (int)] [typekind=FunctionProto] [canonicaltype=int (int)] [canonicaltypekind=FunctionProto] [isPOD=0] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] Index: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -2789,7 +2789,9 @@ CXType_ExtVector = 176, CXType_Atomic = 177, - CXType_BTFTagAttributed = 178 + CXType_BTFTagAttributed = 178, + /* Represents a type that has been substituted for a template type parameter. */ + CXType_SubstTemplateTypeParm = 179 }; /** @@ -3447,6 +3449,13 @@ */ CINDEX_LINKAGE CXType clang_Type_getValueType(CXType CT); +/** + * Gets the replacement type for a SubstTemplateTypeParm type. + * + * If any other type kind is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getReplacementType(CXType CT); + /** * Return the offset of the field represented by the Cursor. * Index: clang/docs/ReleaseNotes.rst === --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -795,6 +795,10 @@ ``clang_Cursor_getTemplateArgumentType``, ``clang_Cursor_getTemplateArgumentValue`` and ``clang_Cursor_getTemplateArgumentUnsignedValue`` now work on struct, class, and partial template specialization cursors in addition to function cursors. +- Added ``CXType_SubstTemplateTypeParm`` to ``CXTypeKind``, which identifies a type that + is a replacement for a template type parameter (previously reported a ``CXType_Unexposed``). +- Introduced the new function ``clang_Type_getReplacementType`` which gets the type replacing + the template type parameter when type kind is ``CXType_SubstTemplateTypeParm``. Static Analyzer --- ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D137818: Add support for querying SubstTemplateTypeParm types
anderslanglands added a comment. Great, thanks! I've got a couple more things to land once this is merged and I've cleaned them up. Do you wanna show me how to do the merge myself? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D137818/new/ https://reviews.llvm.org/D137818 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D137818: Add support for querying SubstTemplateTypeParm types
anderslanglands added a comment. Arg just noticed an issue: clang_Type_getReplacementType should be in the LLVM_16 block in libclang.map not in the LLVM_13 block. I've blown away my local branch so don't know how to fix the patch. Shall I just make a new patch once this is merged? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D137818/new/ https://reviews.llvm.org/D137818 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D138377: add clang_Type_getFullyQualifiedName
anderslanglands created this revision. anderslanglands added a reviewer: aaron.ballman. Herald added a subscriber: arphaman. Herald added a project: All. anderslanglands requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Not sure how to test this - adding it to c-index-test's PrintType will change *everything*, which doesn't seem like a great idea. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D138377 Files: clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/tools/libclang/CXType.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -413,6 +413,7 @@ clang_CXXMethod_isDeleted; clang_CXXMethod_isCopyAssignmentOperator; clang_CXXMethod_isMoveAssignmentOperator; +clang_Type_getFullyQualifiedName; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CXType.cpp === --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -20,6 +20,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/Type.h" +#include "clang/AST/QualTypeNames.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Frontend/ASTUnit.h" @@ -309,6 +310,22 @@ return cxstring::createDup(OS.str()); } +CXString clang_Type_getFullyQualifiedName(CXType CT) { + QualType T = GetQualType(CT); + if (T.isNull()) +return cxstring::createEmpty(); + + CXTranslationUnit TU = GetTU(CT); + SmallString<64> Str; + llvm::raw_svector_ostream OS(Str); + PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts()); + + std::string qname = clang::TypeName::getFullyQualifiedName( + T, cxtu::getASTUnit(TU)->getASTContext(), PP); + + return cxstring::createDup(qname); +} + CXType clang_getTypedefDeclUnderlyingType(CXCursor C) { using namespace cxcursor; CXTranslationUnit TU = cxcursor::getCursorTU(C); Index: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -2846,6 +2846,13 @@ */ CINDEX_LINKAGE CXString clang_getTypeSpelling(CXType CT); +/** + * Get the fully qualified name for a type. + * + * This includes full qualification of all template parameters. +*/ +CINDEX_LINKAGE CXString clang_Type_getFullyQualifiedName(CXType CT); + /** * Retrieve the underlying type of a typedef declaration. * Index: clang/docs/ReleaseNotes.rst === --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -810,6 +810,8 @@ is a replacement for a template type parameter (previously reported a ``CXType_Unexposed``). - Introduced the new function ``clang_Type_getReplacementType`` which gets the type replacing the template type parameter when type kind is ``CXType_SubstTemplateTypeParm``. +- Introduced the new function ``clang_Type_getFullyQualifiedName``, which gets the fully + qualified name of the given type, including qualification of all template parameters. Static Analyzer --- Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -413,6 +413,7 @@ clang_CXXMethod_isDeleted; clang_CXXMethod_isCopyAssignmentOperator; clang_CXXMethod_isMoveAssignmentOperator; +clang_Type_getFullyQualifiedName; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CXType.cpp === --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -20,6 +20,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/Type.h" +#include "clang/AST/QualTypeNames.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Frontend/ASTUnit.h" @@ -309,6 +310,22 @@ return cxstring::createDup(OS.str()); } +CXString clang_Type_getFullyQualifiedName(CXType CT) { + QualType T = GetQualType(CT); + if (T.isNull()) +return cxstring::createEmpty(); + + CXTranslationUnit TU = GetTU(CT); + SmallString<64> Str; + llvm::raw_svector_ostream OS(Str); + PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts()); + + std::string qname = clang::TypeName::getFullyQualifiedName( + T, cxtu::getASTUnit(TU)->getASTContext(), PP); + + return cxstring::createDup(qname); +} + CXType clang_getTypedefDeclUnderlyingType(CXCursor C) { using namespace cxcursor; CXTranslationUnit TU = cxcursor::getCursorTU(C); Index: clang/include/clang-c/Index.h ==
[PATCH] D137818: Add support for querying SubstTemplateTypeParm types
anderslanglands updated this revision to Diff 476935. anderslanglands added a comment. Move getReplacementType to LLVM_16 block Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D137818/new/ https://reviews.llvm.org/D137818 Files: clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/print-type.cpp clang/tools/libclang/CXType.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -412,6 +412,7 @@ clang_CXXMethod_isDeleted; clang_CXXMethod_isCopyAssignmentOperator; clang_CXXMethod_isMoveAssignmentOperator; +clang_Type_getReplacementType; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CXType.cpp === --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -118,13 +118,13 @@ TKCASE(Attributed); TKCASE(BTFTagAttributed); TKCASE(Atomic); +TKCASE(SubstTemplateTypeParm); default: return CXType_Unexposed; } #undef TKCASE } - CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) { CXTypeKind TK = CXType_Invalid; @@ -635,6 +635,7 @@ TKIND(OCLQueue); TKIND(OCLReserveID); TKIND(Atomic); +TKIND(SubstTemplateTypeParm); } #undef TKIND return cxstring::createRef(s); @@ -1355,3 +1356,11 @@ const auto *AT = T->castAs(); return MakeCXType(AT->getValueType(), GetTU(CT)); } + +CXType clang_Type_getReplacementType(CXType CT) { + QualType T = GetQualType(CT); + + const auto *ST = + !T.isNull() ? T->getAs() : nullptr; + return MakeCXType(ST ? ST->getReplacementType() : QualType(), GetTU(CT)); +} Index: clang/test/Index/print-type.cpp === --- clang/test/Index/print-type.cpp +++ clang/test/Index/print-type.cpp @@ -171,7 +171,7 @@ // CHECK: VarDecl=autoI:54:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] // CHECK: VarDecl=autoTbar:55:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1] -// CHECK: CallExpr=tbar:36:3 [type=int] [typekind=Unexposed] [canonicaltype=int] [canonicaltypekind=Int] [args= [int] [Int]] [isPOD=1] +// CHECK: CallExpr=tbar:36:3 [type=int] [typekind=SubstTemplateTypeParm] [canonicaltype=int] [canonicaltypekind=Int] [args= [int] [Int]] [isPOD=1] // CHECK: UnexposedExpr=tbar:36:3 [type=int (*)(int)] [typekind=Pointer] [canonicaltype=int (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=int (int)] [pointeekind=FunctionProto] // CHECK: DeclRefExpr=tbar:36:3 RefName=[55:17 - 55:21] RefName=[55:21 - 55:26] [type=int (int)] [typekind=FunctionProto] [canonicaltype=int (int)] [canonicaltypekind=FunctionProto] [isPOD=0] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] Index: clang/include/clang-c/Index.h === --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -2789,7 +2789,9 @@ CXType_ExtVector = 176, CXType_Atomic = 177, - CXType_BTFTagAttributed = 178 + CXType_BTFTagAttributed = 178, + /* Represents a type that has been substituted for a template type parameter. */ + CXType_SubstTemplateTypeParm = 179 }; /** @@ -3447,6 +3449,13 @@ */ CINDEX_LINKAGE CXType clang_Type_getValueType(CXType CT); +/** + * Gets the replacement type for a SubstTemplateTypeParm type. + * + * If any other type kind is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getReplacementType(CXType CT); + /** * Return the offset of the field represented by the Cursor. * Index: clang/docs/ReleaseNotes.rst === --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -806,6 +806,10 @@ ``clang_Cursor_getTemplateArgumentType``, ``clang_Cursor_getTemplateArgumentValue`` and ``clang_Cursor_getTemplateArgumentUnsignedValue`` now work on struct, class, and partial template specialization cursors in addition to function cursors. +- Added ``CXType_SubstTemplateTypeParm`` to ``CXTypeKind``, which identifies a type that + is a replacement for a template type parameter (previously reported a ``CXType_Unexposed``). +- Introduced the new function ``clang_Type_getReplacementType`` which gets the type replacing + the template type parameter when type kind is ``CXType_SubstTemplateTypeParm``. Static Analyzer --- ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D138377: add clang_Type_getFullyQualifiedName
anderslanglands updated this revision to Diff 477085. anderslanglands added a comment. Now tested by adding a -print-qualified-type-names flag to c-index-test and creating a (small) dedicated test in print-qualified-type.cpp Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138377/new/ https://reviews.llvm.org/D138377 Files: clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/print-qualified-type.cpp clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CXType.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -413,6 +413,7 @@ clang_CXXMethod_isDeleted; clang_CXXMethod_isCopyAssignmentOperator; clang_CXXMethod_isMoveAssignmentOperator; +clang_Type_getFullyQualifiedName; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CXType.cpp === --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -20,6 +20,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/Type.h" +#include "clang/AST/QualTypeNames.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Frontend/ASTUnit.h" @@ -309,6 +310,22 @@ return cxstring::createDup(OS.str()); } +CXString clang_Type_getFullyQualifiedName(CXType CT) { + QualType T = GetQualType(CT); + if (T.isNull()) +return cxstring::createEmpty(); + + CXTranslationUnit TU = GetTU(CT); + SmallString<64> Str; + llvm::raw_svector_ostream OS(Str); + PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts()); + + std::string qname = clang::TypeName::getFullyQualifiedName( + T, cxtu::getASTUnit(TU)->getASTContext(), PP); + + return cxstring::createDup(qname); +} + CXType clang_getTypedefDeclUnderlyingType(CXCursor C) { using namespace cxcursor; CXTranslationUnit TU = cxcursor::getCursorTU(C); Index: clang/tools/c-index-test/c-index-test.c === --- clang/tools/c-index-test/c-index-test.c +++ clang/tools/c-index-test/c-index-test.c @@ -373,6 +373,19 @@ return CommentSchemaFile; } +static int parse_print_qualified_type_names(int argc, const char **argv) { + const char *PrintQualifiedTypeNamesArg = "-print-qualified-type-names"; + const char *PrintQualifiedTypeNames = 0; + + if (argc == 0) +return PrintQualifiedTypeNames; + + if (!strncmp(argv[0], PrintQualifiedTypeNamesArg, strlen(PrintQualifiedTypeNamesArg))) +PrintQualifiedTypeNames = 1; + + return PrintQualifiedTypeNames; +} + /**/ /* Pretty-printing. */ /**/ @@ -1300,6 +1313,7 @@ CXTranslationUnit TU; enum CXCursorKind *Filter; const char *CommentSchemaFile; + int PrintQualifiedTypeNames; } VisitorData; @@ -1507,13 +1521,17 @@ /* Typekind testing. */ /**/ -static void PrintTypeAndTypeKind(CXType T, const char *Format) { +static void PrintTypeAndTypeKind(CXType T, const char *Format, + int PrintQualifiedName) { CXString TypeSpelling, TypeKindSpelling; - TypeSpelling = clang_getTypeSpelling(T); + if (PrintQualifiedName != 0) { +TypeSpelling = clang_Type_getFullyQualifiedName(T); + } else { +TypeSpelling = clang_getTypeSpelling(T); + } TypeKindSpelling = clang_getTypeKindSpelling(T.kind); - printf(Format, - clang_getCString(TypeSpelling), + printf(Format, clang_getCString(TypeSpelling), clang_getCString(TypeKindSpelling)); clang_disposeString(TypeSpelling); clang_disposeString(TypeKindSpelling); @@ -1525,7 +1543,8 @@ return CXVisit_Continue; } -static void PrintTypeTemplateArgs(CXType T, const char *Format) { +static void PrintTypeTemplateArgs(CXType T, const char *Format, + int PrintQualifiedName) { int NumTArgs = clang_Type_getNumTemplateArguments(T); if (NumTArgs != -1 && NumTArgs != 0) { int i; @@ -1534,7 +1553,8 @@ for (i = 0; i < NumTArgs; ++i) { TArg = clang_Type_getTemplateArgumentAsType(T, i); if (TArg.kind != CXType_Invalid) { -PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]"); +PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]", + PrintQualifiedName); } } /* Ensure that the returned type is invalid when indexing off-by-one. */ @@ -1577,7 +1597,9 @@ CXType PT = clang_get
[PATCH] D138377: add clang_Type_getFullyQualifiedName
anderslanglands added a comment. Re the whitespace - yeah that's me running clang-format on the whole function rather than just the lines I changed. I'll see if I can split those out. Comment at: clang/tools/c-index-test/c-index-test.c:1787 PrintCursor(cursor, NULL); + VisitorData *Data = (VisitorData *)d; PrintSingleTypeSize(T, " [type=%s] [typekind=%s]", " [sizeof=%lld]", aaron.ballman wrote: > I'm not super familiar with c-index-test -- how certain are you that the > client data will 1) be non-null, and 2) actually be a `VisitorData` pointer? This was just copy-pasted from another function. I'm as certain as I can be given that all the tests pass :\ Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138377/new/ https://reviews.llvm.org/D138377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D138377: add clang_Type_getFullyQualifiedName
anderslanglands added inline comments. Comment at: clang/tools/c-index-test/c-index-test.c:1787 PrintCursor(cursor, NULL); + VisitorData *Data = (VisitorData *)d; PrintSingleTypeSize(T, " [type=%s] [typekind=%s]", " [sizeof=%lld]", anderslanglands wrote: > aaron.ballman wrote: > > I'm not super familiar with c-index-test -- how certain are you that the > > client data will 1) be non-null, and 2) actually be a `VisitorData` pointer? > This was just copy-pasted from another function. I'm as certain as I can be > given that all the tests pass :\ From a quick scan, VisitorData is the only CXClientData struct used in the visitor callbacks, so I think we're safe. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138377/new/ https://reviews.llvm.org/D138377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D138377: add clang_Type_getFullyQualifiedName
anderslanglands updated this revision to Diff 477398. anderslanglands added a comment. Remove whitespace changes on unaffected lines Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138377/new/ https://reviews.llvm.org/D138377 Files: clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/print-qualified-type.cpp clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CXType.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -413,6 +413,7 @@ clang_CXXMethod_isDeleted; clang_CXXMethod_isCopyAssignmentOperator; clang_CXXMethod_isMoveAssignmentOperator; +clang_Type_getFullyQualifiedName; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CXType.cpp === --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -20,6 +20,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/Type.h" +#include "clang/AST/QualTypeNames.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Frontend/ASTUnit.h" @@ -309,6 +310,18 @@ return cxstring::createDup(OS.str()); } +CXString clang_Type_getFullyQualifiedName(CXType CT) { + QualType T = GetQualType(CT); + if (T.isNull()) +return cxstring::createEmpty(); + + const ASTContext &Ctx = cxtu::getASTUnit(GetTU(CT))->getASTContext(); + std::string QualName = clang::TypeName::getFullyQualifiedName( + T, Ctx, Ctx.getLangOpts()); + + return cxstring::createDup(QualName); +} + CXType clang_getTypedefDeclUnderlyingType(CXCursor C) { using namespace cxcursor; CXTranslationUnit TU = cxcursor::getCursorTU(C); Index: clang/tools/c-index-test/c-index-test.c === --- clang/tools/c-index-test/c-index-test.c +++ clang/tools/c-index-test/c-index-test.c @@ -373,6 +373,19 @@ return CommentSchemaFile; } +static int parse_print_qualified_type_names(int argc, const char **argv) { + const char *PrintQualifiedTypeNamesArg = "-print-qualified-type-names"; + int PrintQualifiedTypeNames = 0; + + if (argc == 0) +return PrintQualifiedTypeNames; + + if (!strncmp(argv[0], PrintQualifiedTypeNamesArg, strlen(PrintQualifiedTypeNamesArg))) +PrintQualifiedTypeNames = 1; + + return PrintQualifiedTypeNames; +} + /**/ /* Pretty-printing. */ /**/ @@ -1300,6 +1313,7 @@ CXTranslationUnit TU; enum CXCursorKind *Filter; const char *CommentSchemaFile; + int PrintQualifiedTypeNames; } VisitorData; @@ -1507,10 +1521,15 @@ /* Typekind testing. */ /**/ -static void PrintTypeAndTypeKind(CXType T, const char *Format) { +static void PrintTypeAndTypeKind(CXType T, const char *Format, + int PrintQualifiedName) { CXString TypeSpelling, TypeKindSpelling; - TypeSpelling = clang_getTypeSpelling(T); + if (PrintQualifiedName != 0) { +TypeSpelling = clang_Type_getFullyQualifiedName(T); + } else { +TypeSpelling = clang_getTypeSpelling(T); + } TypeKindSpelling = clang_getTypeKindSpelling(T.kind); printf(Format, clang_getCString(TypeSpelling), @@ -1525,7 +1544,8 @@ return CXVisit_Continue; } -static void PrintTypeTemplateArgs(CXType T, const char *Format) { +static void PrintTypeTemplateArgs(CXType T, const char *Format, + int PrintQualifiedName) { int NumTArgs = clang_Type_getNumTemplateArguments(T); if (NumTArgs != -1 && NumTArgs != 0) { int i; @@ -1534,7 +1554,8 @@ for (i = 0; i < NumTArgs; ++i) { TArg = clang_Type_getTemplateArgumentAsType(T, i); if (TArg.kind != CXType_Invalid) { -PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]"); +PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]", + PrintQualifiedName); } } /* Ensure that the returned type is invalid when indexing off-by-one. */ @@ -1577,7 +1598,9 @@ CXType PT = clang_getPointeeType(T); enum CXRefQualifierKind RQ = clang_Type_getCXXRefQualifier(T); PrintCursor(cursor, NULL); -PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]"); +VisitorData *Data = (VisitorData *)d; +PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]", + Data->PrintQualifiedTypeNames); PrintNullabilityKind(T, " [nullability=%s]"); if (cl
[PATCH] D138377: add clang_Type_getFullyQualifiedName
anderslanglands updated this revision to Diff 477399. anderslanglands added a comment. couple of little spaces I missed... Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D138377/new/ https://reviews.llvm.org/D138377 Files: clang/docs/ReleaseNotes.rst clang/include/clang-c/Index.h clang/test/Index/print-qualified-type.cpp clang/tools/c-index-test/c-index-test.c clang/tools/libclang/CXType.cpp clang/tools/libclang/libclang.map Index: clang/tools/libclang/libclang.map === --- clang/tools/libclang/libclang.map +++ clang/tools/libclang/libclang.map @@ -413,6 +413,7 @@ clang_CXXMethod_isDeleted; clang_CXXMethod_isCopyAssignmentOperator; clang_CXXMethod_isMoveAssignmentOperator; +clang_Type_getFullyQualifiedName; }; # Example of how to add a new symbol version entry. If you do add a new symbol Index: clang/tools/libclang/CXType.cpp === --- clang/tools/libclang/CXType.cpp +++ clang/tools/libclang/CXType.cpp @@ -20,6 +20,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/Type.h" +#include "clang/AST/QualTypeNames.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Frontend/ASTUnit.h" @@ -309,6 +310,18 @@ return cxstring::createDup(OS.str()); } +CXString clang_Type_getFullyQualifiedName(CXType CT) { + QualType T = GetQualType(CT); + if (T.isNull()) +return cxstring::createEmpty(); + + const ASTContext &Ctx = cxtu::getASTUnit(GetTU(CT))->getASTContext(); + std::string QualName = clang::TypeName::getFullyQualifiedName( + T, Ctx, Ctx.getLangOpts()); + + return cxstring::createDup(QualName); +} + CXType clang_getTypedefDeclUnderlyingType(CXCursor C) { using namespace cxcursor; CXTranslationUnit TU = cxcursor::getCursorTU(C); Index: clang/tools/c-index-test/c-index-test.c === --- clang/tools/c-index-test/c-index-test.c +++ clang/tools/c-index-test/c-index-test.c @@ -373,6 +373,19 @@ return CommentSchemaFile; } +static int parse_print_qualified_type_names(int argc, const char **argv) { + const char *PrintQualifiedTypeNamesArg = "-print-qualified-type-names"; + int PrintQualifiedTypeNames = 0; + + if (argc == 0) +return PrintQualifiedTypeNames; + + if (!strncmp(argv[0], PrintQualifiedTypeNamesArg, strlen(PrintQualifiedTypeNamesArg))) +PrintQualifiedTypeNames = 1; + + return PrintQualifiedTypeNames; +} + /**/ /* Pretty-printing. */ /**/ @@ -1300,6 +1313,7 @@ CXTranslationUnit TU; enum CXCursorKind *Filter; const char *CommentSchemaFile; + int PrintQualifiedTypeNames; } VisitorData; @@ -1507,10 +1521,15 @@ /* Typekind testing. */ /**/ -static void PrintTypeAndTypeKind(CXType T, const char *Format) { +static void PrintTypeAndTypeKind(CXType T, const char *Format, + int PrintQualifiedName) { CXString TypeSpelling, TypeKindSpelling; - TypeSpelling = clang_getTypeSpelling(T); + if (PrintQualifiedName != 0) { +TypeSpelling = clang_Type_getFullyQualifiedName(T); + } else { +TypeSpelling = clang_getTypeSpelling(T); + } TypeKindSpelling = clang_getTypeKindSpelling(T.kind); printf(Format, clang_getCString(TypeSpelling), @@ -1525,7 +1544,8 @@ return CXVisit_Continue; } -static void PrintTypeTemplateArgs(CXType T, const char *Format) { +static void PrintTypeTemplateArgs(CXType T, const char *Format, + int PrintQualifiedName) { int NumTArgs = clang_Type_getNumTemplateArguments(T); if (NumTArgs != -1 && NumTArgs != 0) { int i; @@ -1534,7 +1554,8 @@ for (i = 0; i < NumTArgs; ++i) { TArg = clang_Type_getTemplateArgumentAsType(T, i); if (TArg.kind != CXType_Invalid) { -PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]"); +PrintTypeAndTypeKind(TArg, " [type=%s] [typekind=%s]", + PrintQualifiedName); } } /* Ensure that the returned type is invalid when indexing off-by-one. */ @@ -1577,7 +1598,9 @@ CXType PT = clang_getPointeeType(T); enum CXRefQualifierKind RQ = clang_Type_getCXXRefQualifier(T); PrintCursor(cursor, NULL); -PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]"); +VisitorData *Data = (VisitorData *)d; +PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]", + Data->PrintQualifiedTypeNames); PrintNullabilityKind(T, " [nullability=%s]"); if (clang_isCons