From: Ivan Donchevskii Date: Thu, 10 Jan 2019 09:34:44 +0000 (+0000) Subject: [libclang] Fix clang_Cursor_isAnonymous X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5a120398929f7bbbc3edac565fb785ebee888949;p=clang [libclang] Fix clang_Cursor_isAnonymous Use the same logic as in TypePrinter::printTag to determine that the tag is anonymous and the separate check for namespaces. Differential Revision: https://reviews.llvm.org/D54996 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350805 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Index/print-type.cpp b/test/Index/print-type.cpp index 654b456239..17bae2e9c3 100644 --- a/test/Index/print-type.cpp +++ b/test/Index/print-type.cpp @@ -79,6 +79,17 @@ auto autoTemplPointer = &autoTemplRefParam; outer::Foo parameter; outer::inner::Bar construct(¶meter); + +class X { + struct { int a; }; + class { public: int b; }; + union { int c; int d;}; + enum { Test }; +}; + +namespace { + int a; +} // RUN: c-index-test -test-print-type %s -std=c++14 | FileCheck %s // CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] // CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0] @@ -188,3 +199,8 @@ outer::inner::Bar construct(¶meter); // CHECK: TypeAliasDecl=baz:76:7 (Definition) [type=baz] [typekind=Typedef] [templateargs/1= [type=A] [typekind=Unexposed]] [canonicaltype=A] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=void] [typekind=Void]] [isPOD=0] // CHECK: VarDecl=autoTemplPointer:78:6 (Definition) [type=Specialization &> *] [typekind=Auto] [canonicaltype=Specialization &> *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=Specialization &>] [pointeekind=Record] // CHECK: CallExpr=Bar:17:3 [type=outer::inner::Bar] [typekind=Elaborated] [canonicaltype=outer::inner::Bar] [canonicaltypekind=Record] [args= [outer::Foo *] [Pointer]] [isPOD=0] [nbFields=3] +// CHECK: StructDecl=:84:3 (Definition) [type=X::(anonymous struct at {{.*}}print-type.cpp:84:3)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1] +// CHECK: ClassDecl=:85:3 (Definition) [type=X::(anonymous class at {{.*}}print-type.cpp:85:3)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1] +// CHECK: UnionDecl=:86:3 (Definition) [type=X::(anonymous union at {{.*}}print-type.cpp:86:3)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] +// CHECK: EnumDecl=:87:3 (Definition) [type=X::(anonymous enum at {{.*}}print-type.cpp:87:3)] [typekind=Enum] [isPOD=1] [isAnon=1] +// CHECK: Namespace=:90:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] [isAnon=1] diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 7c88811a74..fc6ba46fd6 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -1654,13 +1654,14 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p, if (numFields != 0) { printf(" [nbFields=%d]", numFields); } - /* Print if it is an anonymous record. */ - { - unsigned isAnon = clang_Cursor_isAnonymous(cursor); - if (isAnon != 0) { - printf(" [isAnon=%d]", isAnon); - } - } + } + } + + /* Print if it is an anonymous record or namespace. */ + { + unsigned isAnon = clang_Cursor_isAnonymous(cursor); + if (isAnon != 0) { + printf(" [isAnon=%d]", isAnon); } } diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp index b511046fe6..b8009ddc1c 100644 --- a/tools/libclang/CXType.cpp +++ b/tools/libclang/CXType.cpp @@ -1229,11 +1229,15 @@ unsigned clang_Cursor_isAnonymous(CXCursor C){ if (!clang_isDeclaration(C.kind)) return 0; const Decl *D = cxcursor::getCursorDecl(C); - if (const RecordDecl *FD = dyn_cast_or_null(D)) - return FD->isAnonymousStructOrUnion(); + if (const NamespaceDecl *ND = dyn_cast_or_null(D)) { + return ND->isAnonymousNamespace(); + } else if (const TagDecl *TD = dyn_cast_or_null(D)) { + return TD->getTypedefNameForAnonDecl() == nullptr && + TD->getIdentifier() == nullptr; + } + return 0; } - CXType clang_Type_getNamedType(CXType CT){ QualType T = GetQualType(CT); const Type *TP = T.getTypePtrOrNull();