]> granicus.if.org Git - clang/commitdiff
[libclang] Restore old clang_Cursor_isAnonymous behaviour
authorIvan Donchevskii <yv.ivan@gmail.com>
Mon, 29 Apr 2019 13:44:07 +0000 (13:44 +0000)
committerIvan Donchevskii <yv.ivan@gmail.com>
Mon, 29 Apr 2019 13:44:07 +0000 (13:44 +0000)
D54996 Changed the behaviour of clang_Cursor_isAnonymous, but there is no alternative available to get the old behaviour in some cases, which is essential for determining if a record is syntactically accessible, e.g.

struct {
  int x;
  int y;
} foo;

struct {
  struct {
    int x;
    int y;
  };
} bar;

void fun(struct { int x; int y; } *param);
The only 'anonymous' struct here is the one nested in bar, since there is
no way to reference the struct itself, only the fields within. Though the
anonymity applies to the instance itself, not the type.

To avoid confusion, I have added a new function called clang_Cursor_isAnonymousRecordDecl
which has the old behaviour of clang_Cursor_isAnonymous (and updated the doc
for the latter as well, which was seemingly forgotten).

Patch by Jorn Vernee.

Differential Revision: https://reviews.llvm.org/D61232

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359448 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang-c/Index.h
test/Index/print-type.c
tools/c-index-test/c-index-test.c
tools/libclang/CXType.cpp

index 4f2f521f92ff89fcccd9c61e1e43bb4b3e48f4e6..24b865cbaf3b1962b4c4e10f1a1497daf7c47562 100644 (file)
@@ -32,7 +32,7 @@
  * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
  */
 #define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 55
+#define CINDEX_VERSION_MINOR 56
 
 #define CINDEX_VERSION_ENCODE(major, minor) ( \
       ((major) * 10000)                       \
@@ -3920,11 +3920,17 @@ CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T);
  */
 CINDEX_LINKAGE long long clang_Cursor_getOffsetOfField(CXCursor C);
 
+/**
+ * Determine whether the given cursor represents an anonymous
+ * tag or namespace
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isAnonymous(CXCursor C);
+
 /**
  * Determine whether the given cursor represents an anonymous record
  * declaration.
  */
-CINDEX_LINKAGE unsigned clang_Cursor_isAnonymous(CXCursor C);
+CINDEX_LINKAGE unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C);
 
 enum CXRefQualifierKind {
   /** No ref-qualifier was provided. */
index 13c765543726cb8ae66595df5d39df4ddf92b97d..9bf05884082513eddd3be95de5845b9e8415cfd3 100644 (file)
@@ -15,6 +15,20 @@ int f2(int incompletearray[]);
 enum Enum{i}; enum Enum elaboratedEnumType();
 struct Struct{}; struct Struct elaboratedStructType();
 
+struct {
+  int x;
+  int y;
+} foo;
+
+struct {
+  struct {
+    int x;
+    int y;
+  };
+} bar;
+
+void fun(struct { int x; int y; } *param);
+
 // RUN: c-index-test -test-print-type %s | FileCheck %s
 // CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int [5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0]
 // CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
@@ -53,3 +67,7 @@ struct Struct{}; struct Struct elaboratedStructType();
 // CHECK: StructDecl=Struct:16:8 (Definition) [type=struct Struct] [typekind=Record] [isPOD=1]
 // CHECK: FunctionDecl=elaboratedStructType:16:32 [type=struct Struct ()] [typekind=FunctionNoProto] [canonicaltype=struct Struct ()] [canonicaltypekind=FunctionNoProto] [resulttype=struct Struct] [resulttypekind=Elaborated] [isPOD=0]
 // CHECK: TypeRef=struct Struct:16:8 [type=struct Struct] [typekind=Record] [isPOD=1]
+// CHECK: StructDecl=:18:1 (Definition) [type=struct (anonymous at {{.*}}print-type.c:18:1)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0]
+// CHECK: StructDecl=:23:1 (Definition) [type=struct (anonymous at {{.*}}print-type.c:23:1)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1] [isAnonRecDecl=0]
+// CHECK: StructDecl=:24:3 (Definition) [type=struct (anonymous at {{.*}}print-type.c:24:3)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=1]
+// CHECK: StructDecl=:30:10 (Definition) [type=struct (anonymous at {{.*}}print-type.c:30:10)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0]
index 2cf442ef0dc8794717193af63f4abf622ab62d43..17b773c63664897dae2c76dca7235c6adeebe29e 100644 (file)
@@ -1665,6 +1665,12 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
       }
     }
 
+    /* Print if it is an anonymous record decl */
+    {
+      unsigned isAnonRecDecl = clang_Cursor_isAnonymousRecordDecl(cursor);
+      printf(" [isAnonRecDecl=%d]", isAnonRecDecl);
+    }
+
     printf("\n");
   }
   return CXChildVisit_Recurse;
index 4d22a5e00b9e564affee79b46bd3c1632e975478..6cb680a64d8b576789693b30c29528cfb0984600 100644 (file)
@@ -1253,6 +1253,16 @@ unsigned clang_Cursor_isAnonymous(CXCursor C){
 
   return 0;
 }
+
+unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C){
+  if (!clang_isDeclaration(C.kind))
+    return 0;
+  const Decl *D = cxcursor::getCursorDecl(C);
+  if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
+    return FD->isAnonymousStructOrUnion();
+  return 0;
+}
+
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();