[PATCH] D54996: [libclang] Fix clang_Cursor_isAnonymous

2019-04-27 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee added a comment.
Herald added a project: LLVM.

This seems to have changed the behaviour w.r.t inline struct or union decls in 
fields and global variables e.g.

  struct foo {
  struct {
  int x;
  } bar;
  };

For the StructDecl cursor of 'bar' isAnonymous now returns true, instead of 
false.

I guess this was intended? But we were relying on this behaviour to collect all 
nested elements that were accessible through the parent struct, e.g.

  struct foo {
  struct {
  int x;
  } bar;
  union {
  int y;
  int z;
  };
  };

'y' and 'z' are accessible directly through foo by doing `foo.y` and `foo.z.`, 
but 'x' is not, we have to do `foo.bar.x`. Since isAnonymous now returns true 
for both 'bar' and the 'inlined' anonymous union, there is no easy way to 
differentiate between whether it appears as part of a FieldDecl or not. The 
only alternative is to look up the semantic parent, create a set of all the 
FieldDecl cursors, and then filter by the field's type's declaration cursors. 
(which is kind of 'meh' for usability/performance).

Any alternative to get the old behaviour?


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54996/new/

https://reviews.llvm.org/D54996



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61232: [libclang] Restore old clang_Cursor_isAnonymous behaviour

2019-04-27 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee created this revision.
JornVernee added reviewers: yvvan, nik, rsmith.
JornVernee added a project: clang.
Herald added a subscriber: arphaman.

https://reviews.llvm.org/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).


Repository:
  rC Clang

https://reviews.llvm.org/D61232

Files:
  include/clang-c/Index.h
  tools/libclang/CXType.cpp


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -1253,6 +1253,16 @@

   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(D))
+return FD->isAnonymousStructOrUnion();
+  return 0;
+}
+
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();
Index: include/clang-c/Index.h
===
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -3920,11 +3920,17 @@
  */
 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: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -1253,6 +1253,16 @@

   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(D))
+return FD->isAnonymousStructOrUnion();
+  return 0;
+}
+
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();
Index: include/clang-c/Index.h
===
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -3920,11 +3920,17 @@
  */
 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. */
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61232: [libclang] Restore old clang_Cursor_isAnonymous behaviour

2019-04-27 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee added a comment.

Also, I don't have commit access, so I would need some help with that if this 
gets accepted :)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61232/new/

https://reviews.llvm.org/D61232



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61232: [libclang] Restore old clang_Cursor_isAnonymous behaviour

2019-04-27 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee updated this revision to Diff 196988.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61232/new/

https://reviews.llvm.org/D61232

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


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -1253,6 +1253,16 @@
 
   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(D))
+return FD->isAnonymousStructOrUnion();
+  return 0;
+}
+
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -1664,6 +1664,12 @@
 printf(" [isAnon=%d]", isAnon);
   }
 }
+   
+   /* Print if it is an anonymous record decl */
+{
+  unsigned isAnonRecDecl = clang_Cursor_isAnonymousRecordDecl(cursor);
+  printf(" [isAnonRecDecl=%d]", isAnonRecDecl);
+}
 
 printf("\n");
   }
Index: test/Index/print-type.c
===
--- test/Index/print-type.c
+++ test/Index/print-type.c
@@ -15,6 +15,20 @@
 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 @@
 // 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 
.\test\Index\print-type.c:18:1)] [typekind=Record] [isPOD=1] [nbFields=2] 
[isAnon=1] [isAnonRecDecl=0]
+// CHECK: StructDecl=:23:1 (Definition) [type=struct (anonymous at 
.\test\Index\print-type.c:23:1)] [typekind=Record] [isPOD=1] [nbFields=1] 
[isAnon=1] [isAnonRecDecl=0]
+// CHECK: StructDecl=:24:3 (Definition) [type=struct (anonymous at 
.\test\Index\print-type.c:24:3)] [typekind=Record] [isPOD=1] [nbFields=2] 
[isAnon=1] [isAnonRecDecl=1]
+// CHECK: StructDecl=:30:10 (Definition) [type=struct (anonymous at 
.\test\Index\print-type.c:30:10)] [typekind=Record] [isPOD=1] [nbFields=2] 
[isAnon=1] [isAnonRecDecl=0]
Index: include/clang-c/Index.h
===
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -3920,11 +3920,17 @@
  */
 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: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -1253,6 +1253,16 @@
 
   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(D))
+return FD->isAnonymousStructOrUnion();
+  return 0;
+}
+
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.

[PATCH] D61232: [libclang] Restore old clang_Cursor_isAnonymous behaviour

2019-04-27 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee added a comment.

@yvvan Hows that as a test?

I'm pretty new at this, and it took a while to figure out how to run the tests. 
I used something like: `build\Release\bin\c-index-test.exe -test-print-type 
.\test\Index\print-type.c | ..\llvm\build\Release\bin\FileCheck 
.\test\Index\print-type.c`, but there's probably an easier way?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61232/new/

https://reviews.llvm.org/D61232



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61232: [libclang] Restore old clang_Cursor_isAnonymous behaviour

2019-04-28 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee updated this revision to Diff 197018.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61232/new/

https://reviews.llvm.org/D61232

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


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -1253,6 +1253,16 @@
 
   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(D))
+return FD->isAnonymousStructOrUnion();
+  return 0;
+}
+
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -1665,6 +1665,12 @@
   }
 }
 
+/* Print if it is an anonymous record decl */
+{
+  unsigned isAnonRecDecl = clang_Cursor_isAnonymousRecordDecl(cursor);
+  printf(" [isAnonRecDecl=%d]", isAnonRecDecl);
+}
+
 printf("\n");
   }
   return CXChildVisit_Recurse;
Index: test/Index/print-type.c
===
--- test/Index/print-type.c
+++ test/Index/print-type.c
@@ -15,6 +15,20 @@
 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 @@
 // 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: include/clang-c/Index.h
===
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -3920,11 +3920,17 @@
  */
 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: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -1253,6 +1253,16 @@
 
   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(D))
+return FD->isAnonymousStructOrUnion();
+  return 0;
+}
+
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -1665,6 +1665,12 @@
   }
 }
 
+/* 

[PATCH] D61232: [libclang] Restore old clang_Cursor_isAnonymous behaviour

2019-04-28 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee updated this revision to Diff 197019.
JornVernee marked an inline comment as done.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61232/new/

https://reviews.llvm.org/D61232

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


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -1253,6 +1253,16 @@
 
   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(D))
+return FD->isAnonymousStructOrUnion();
+  return 0;
+}
+
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -1665,6 +1665,12 @@
   }
 }
 
+/* Print if it is an anonymous record decl */
+{
+  unsigned isAnonRecDecl = clang_Cursor_isAnonymousRecordDecl(cursor);
+  printf(" [isAnonRecDecl=%d]", isAnonRecDecl);
+}
+
 printf("\n");
   }
   return CXChildVisit_Recurse;
Index: test/Index/print-type.c
===
--- test/Index/print-type.c
+++ test/Index/print-type.c
@@ -15,6 +15,20 @@
 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 @@
 // 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: include/clang-c/Index.h
===
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -3920,11 +3920,17 @@
  */
 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: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -1253,6 +1253,16 @@
 
   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(D))
+return FD->isAnonymousStructOrUnion();
+  return 0;
+}
+
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c

[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-04-28 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee created this revision.
JornVernee added reviewers: akyrtzi, aaron.ballman, rsmith.
JornVernee added a project: clang.
Herald added subscribers: arphaman, dexonsmith.

Currently, looking up the offset of a field in a type with an incomplete array, 
using `clang_Type_getOffsetOf` always returns `CXTypeLayoutError_Incomplete`. 
e.g. for the following:

  struct Foo {
  int size;
  void* data[]; // incomplete array
  };

This returns `CXTypeLayoutError_Incomplete` when looking up the offset of 
either the 'size' or the 'data' field.

But, since an incomplete array always appears at the end of a record, looking 
up the field offsets should be fine. Note that this also works fine using the 
offsetof macro.

The fix for this is to ignore incomplete array fields when doing the recursive 
type validation.


https://reviews.llvm.org/D61239

Files:
  test/Index/print-type-size.c
  tools/libclang/CXType.cpp


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -953,7 +953,7 @@
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType()) // IAT is 
okay here
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,30 @@
+struct Foo {
+int size;
+void* data[]; // incomplete array
+};
+
+struct Bar {
+int size;
+struct {
+int dummy;
+void* data[]; // incomplete array
+};
+};
+
+struct Baz {
+int size;
+union {
+void* data1[]; // incomplete array
+void* data2[]; // incomplete array
+};
+};
+
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+// CHECK: FieldDecl=size:2:9 (Definition) [type=int] [typekind=Int] [sizeof=4] 
[alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data:3:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64]
+// CHECK: FieldDecl=size:7:9 (Definition) [type=int] [typekind=Int] [sizeof=4] 
[alignof=4] [offsetof=0]
+// CHECK: FieldDecl=dummy:9:13 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=64/0]
+// CHECK: FieldDecl=data:10:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=128/64]
+// CHECK: FieldDecl=size:15:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data1:17:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64/0]
+// CHECK: FieldDecl=data2:18:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64/0]
\ No newline at end of file


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -953,7 +953,7 @@
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType()) // IAT is okay here
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,30 @@
+struct Foo {
+int size;
+void* data[]; // incomplete array
+};
+
+struct Bar {
+int size;
+struct {
+int dummy;
+void* data[]; // incomplete array
+};
+};
+
+struct Baz {
+int size;
+union {
+void* data1[]; // incomplete array
+void* data2[]; // incomplete array
+};
+};
+
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+// CHECK: FieldDecl=size:2:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data:3:11 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64]
+// CHECK: FieldDecl=size:7:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=dummy:9:13 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64/0]
+// CHECK: FieldDecl=data:10:15 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=128/64]
+// CHECK: FieldDecl=size:15:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data1:17:15 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64/0]
+// CHECK: Fie

[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-04-28 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee updated this revision to Diff 197024.
JornVernee added a comment.

Fixed the similar problem with `clang_Type_getAlignOf` since the patch is 
pretty small any ways.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61239/new/

https://reviews.llvm.org/D61239

Files:
  test/Index/print-type-size.c
  tools/libclang/CXType.cpp


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -895,7 +895,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (QT->isIncompleteType() && !QT->isIncompleteArrayType()) // IAT is okay 
here
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -953,7 +953,7 @@
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType()) // IAT is 
okay here
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,30 @@
+struct Foo {
+int size;
+void* data[]; // incomplete array
+};
+
+struct Bar {
+int size;
+struct {
+int dummy;
+void* data[]; // incomplete array
+};
+};
+
+struct Baz {
+int size;
+union {
+void* data1[]; // incomplete array
+void* data2[]; // incomplete array
+};
+};
+
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+// CHECK: FieldDecl=size:2:9 (Definition) [type=int] [typekind=Int] [sizeof=4] 
[alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data:3:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64]
+// CHECK: FieldDecl=size:7:9 (Definition) [type=int] [typekind=Int] [sizeof=4] 
[alignof=4] [offsetof=0]
+// CHECK: FieldDecl=dummy:9:13 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=64/0]
+// CHECK: FieldDecl=data:10:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=128/64]
+// CHECK: FieldDecl=size:15:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data1:17:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+// CHECK: FieldDecl=data2:18:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
\ No newline at end of file


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -895,7 +895,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (QT->isIncompleteType() && !QT->isIncompleteArrayType()) // IAT is okay here
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -953,7 +953,7 @@
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType()) // IAT is okay here
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,30 @@
+struct Foo {
+int size;
+void* data[]; // incomplete array
+};
+
+struct Bar {
+int size;
+struct {
+int dummy;
+void* data[]; // incomplete array
+};
+};
+
+struct Baz {
+int size;
+union {
+void* data1[]; // incomplete array
+void* data2[]; // incomplete array
+};
+};
+
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+// CHECK: FieldDecl=size:2:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data:3:11 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64]
+// CHECK: FieldDecl=size:7:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=dummy:9:13 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64/0]
+// CHECK: FieldDecl=data:10:15 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=128/64]
+// CHECK: FieldDecl=size:15:9 (Definition) [type=int] [typekind

[PATCH] D61232: [libclang] Restore old clang_Cursor_isAnonymous behaviour

2019-04-28 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee marked an inline comment as done.
JornVernee added a comment.

No worries! I'm already glad there's someone who picked up the review for this 
so quickly ;)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61232/new/

https://reviews.llvm.org/D61232



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61232: [libclang] Restore old clang_Cursor_isAnonymous behaviour

2019-04-28 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee updated this revision to Diff 197038.
JornVernee added a comment.

Incremented minor version


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61232/new/

https://reviews.llvm.org/D61232

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

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -1253,6 +1253,16 @@
 
   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(D))
+return FD->isAnonymousStructOrUnion();
+  return 0;
+}
+
 CXType clang_Type_getNamedType(CXType CT){
   QualType T = GetQualType(CT);
   const Type *TP = T.getTypePtrOrNull();
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -1665,6 +1665,12 @@
   }
 }
 
+/* Print if it is an anonymous record decl */
+{
+  unsigned isAnonRecDecl = clang_Cursor_isAnonymousRecordDecl(cursor);
+  printf(" [isAnonRecDecl=%d]", isAnonRecDecl);
+}
+
 printf("\n");
   }
   return CXChildVisit_Recurse;
Index: test/Index/print-type.c
===
--- test/Index/print-type.c
+++ test/Index/print-type.c
@@ -15,6 +15,20 @@
 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 @@
 // 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: include/clang-c/Index.h
===
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -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) * 1)   \
@@ -3920,11 +3920,17 @@
  */
 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. */
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-04-29 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee added a comment.

@yvvan Mind taking a look here as well?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61239/new/

https://reviews.llvm.org/D61239



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-05-01 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee updated this revision to Diff 197532.
JornVernee marked 2 inline comments as done.
JornVernee added a comment.

- Restructured test source file to put CHECK comments inline
- Removed IAT comments.

- holding of on adding helper method until hearing back.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61239/new/

https://reviews.llvm.org/D61239

Files:
  test/Index/print-type-size.c
  tools/libclang/CXType.cpp


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -895,7 +895,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (QT->isIncompleteType() && !QT->isIncompleteArrayType())
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -953,7 +953,7 @@
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType())
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,30 @@
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+
+struct Foo {
+int size;
+// CHECK: FieldDecl=size:4:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+void* data[];
+// CHECK: FieldDecl=data:6:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64]
+};
+
+struct Bar {
+int size;
+// CHECK: FieldDecl=size:11:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+struct {
+int dummy;
+// CHECK: FieldDecl=dummy:14:13 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=64/0]
+void* data[];
+// CHECK: FieldDecl=data:16:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=128/64]
+};
+};
+
+struct Baz {
+int size;
+// CHECK: FieldDecl=size:22:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+union {
+void* data1[];
+// CHECK: FieldDecl=data1:25:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+void* data2[];
+// CHECK: FieldDecl=data2:27:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+};
+};


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -895,7 +895,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (QT->isIncompleteType() && !QT->isIncompleteArrayType())
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -953,7 +953,7 @@
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType())
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,30 @@
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+
+struct Foo {
+int size;
+// CHECK: FieldDecl=size:4:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+void* data[];
+// CHECK: FieldDecl=data:6:11 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64]
+};
+
+struct Bar {
+int size;
+// CHECK: FieldDecl=size:11:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+struct {
+int dummy;
+// CHECK: FieldDecl=dummy:14:13 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64/0]
+void* data[];
+// CHECK: FieldDecl=data:16:15 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=128/64]
+};
+};
+
+struct Baz {
+int size;
+// CHECK: FieldDecl=size:22:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+union {
+void* data1[];
+// CHECK: FieldDecl=data1:25:15 (Definition) [type=void *[]] [typekind=Incomplete

[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-05-01 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee updated this revision to Diff 197533.
JornVernee added a comment.

Add forgotten newline


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61239/new/

https://reviews.llvm.org/D61239

Files:
  test/Index/print-type-size.c
  tools/libclang/CXType.cpp


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -895,7 +895,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (QT->isIncompleteType() && !QT->isIncompleteArrayType())
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -953,7 +953,7 @@
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType())
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,31 @@
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+
+struct Foo {
+int size;
+// CHECK: FieldDecl=size:4:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+void* data[];
+// CHECK: FieldDecl=data:6:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64]
+};
+
+struct Bar {
+int size;
+// CHECK: FieldDecl=size:11:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+struct {
+int dummy;
+// CHECK: FieldDecl=dummy:14:13 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=64/0]
+void* data[];
+// CHECK: FieldDecl=data:16:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=128/64]
+};
+};
+
+struct Baz {
+int size;
+// CHECK: FieldDecl=size:22:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+union {
+void* data1[];
+// CHECK: FieldDecl=data1:25:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+void* data2[];
+// CHECK: FieldDecl=data2:27:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+};
+};
+


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -895,7 +895,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (QT->isIncompleteType() && !QT->isIncompleteArrayType())
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -953,7 +953,7 @@
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType())
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,31 @@
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+
+struct Foo {
+int size;
+// CHECK: FieldDecl=size:4:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+void* data[];
+// CHECK: FieldDecl=data:6:11 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64]
+};
+
+struct Bar {
+int size;
+// CHECK: FieldDecl=size:11:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+struct {
+int dummy;
+// CHECK: FieldDecl=dummy:14:13 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64/0]
+void* data[];
+// CHECK: FieldDecl=data:16:15 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=128/64]
+};
+};
+
+struct Baz {
+int size;
+// CHECK: FieldDecl=size:22:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+union {
+void* data1[];
+// CHECK: FieldDecl=data1:25:15 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+void* data2[];
+// CHECK: FieldDecl=data2:27:15 (Definition) [type=void *[]] [typekind=IncompleteArr

[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-05-01 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee marked 4 inline comments as done.
JornVernee added a comment.

In D61239#1486005 , @aaron.ballman 
wrote:

> In D61239#1485994 , @JornVernee 
> wrote:
>
> > - holding of on adding helper method until hearing back.
>
>
> My rationale for wanting a helper method is because we already have two 
> places were incompleteness is important but has special cases. It's easier to 
> maintain that with something that's a named function to explain what the 
> predicate is actually doing. My concern is that we add another 
> `isIncompleteType()` and not think about this issue.
>
> Do we need this in `validateFieldParentType()`?


Thanks for the response, I misunderstood.

I usually go with naming my predicates in that way as well, but I misunderstood 
where you wanted to use it. I think adding the helper method for 
`validateFieldParentType()` is good. But, the check in 
`clang_Cursor_getAlignOf` is semantically different, since we basically want to 
check if the type has an alignment. (I actually realized we also need to check 
the element type for completeness in the case of incomplete arrays. Figuring 
that out now).




Comment at: test/Index/print-type-size.c:22
+
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+// CHECK: FieldDecl=size:2:9 (Definition) [type=int] [typekind=Int] [sizeof=4] 
[alignof=4] [offsetof=0]

aaron.ballman wrote:
> This should be the first line of the file. I don't have strong opinions on 
> where the CHECK lines go, but I usually prefer seeing them near the construct 
> being checked.
This style was taken from `print-type-size.cpp`, which also puts everything at 
the end. I'll put it at the front/inline instead (makes sense to me as well). I 
guess it's a legacy thing we're trying to move away from?



Comment at: tools/libclang/CXType.cpp:956
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType()) // IAT is 
okay here
   return CXTypeLayoutError_Incomplete;

aaron.ballman wrote:
> aaron.ballman wrote:
> > Same here.
> I sort of wonder whether we want a helper function like 
> `isTypeIncompleteForLayout()` or something, and then using that helper 
> directly.
Note that `clang_Type_getSizeOf` will (and AFAIK should) still return 
`CXTypeLayoutError_Incomplete` for incomplete arrays. I'd expect a potential 
`isTypeIncompleteForLayout()` to be used by all three functions (OffsetOf, 
SizeOf, AlignOf). So, I'm in favour of doing without such a helper method for 
the special OffsetOf and AlignOf cases.

It's a pretty unique case (but it appears a bunch of times in Windows API 
headers so we'd like to have support for it :) ).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61239/new/

https://reviews.llvm.org/D61239



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-05-01 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee updated this revision to Diff 197543.
JornVernee marked an inline comment as done.
JornVernee added a comment.

- Replaced plane predicates with helper methods describing their function.
- Fixed test file indentation

Changing the logic for `clang_Type_getAlignOf` was not needed after all, since 
the use of incomplete type as array element type was already causing an error 
earlier on (so I think we can assume at that point it's safe?)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61239/new/

https://reviews.llvm.org/D61239

Files:
  test/Index/print-type-size.c
  tools/libclang/CXType.cpp


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -885,6 +885,10 @@
   return result;
 }
 
+static bool isIncompleteTypeWithAlignment(const QualType &QT) {
+  return QT->isIncompleteArrayType() || !QT->isIncompleteType();
+}
+
 long long clang_Type_getAlignOf(CXType T) {
   if (T.kind == CXType_Invalid)
 return CXTypeLayoutError_Invalid;
@@ -895,7 +899,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (!isIncompleteTypeWithAlignment(QT))
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -950,10 +954,14 @@
   return Ctx.getTypeSizeInChars(QT).getQuantity();
 }
 
+static bool isTypeIncompleteForLayout(const QualType &QT) {
+  return QT->isIncompleteType() && !QT->isIncompleteArrayType();
+}
+
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (isTypeIncompleteForLayout(FQT))
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,31 @@
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+
+struct Foo {
+  int size;
+  // CHECK: FieldDecl=size:4:7 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+  void* data[];
+  // CHECK: FieldDecl=data:6:9 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64]
+};
+
+struct Bar {
+  int size;
+  // CHECK: FieldDecl=size:11:7 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+  struct {
+int dummy;
+// CHECK: FieldDecl=dummy:14:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=64/0]
+void* data[];
+// CHECK: FieldDecl=data:16:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=128/64]
+  };
+};
+
+struct Baz {
+  int size;
+  // CHECK: FieldDecl=size:22:7 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+  union {
+void* data1[];
+// CHECK: FieldDecl=data1:25:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+void* data2[];
+// CHECK: FieldDecl=data2:27:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+  };
+};
+


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -885,6 +885,10 @@
   return result;
 }
 
+static bool isIncompleteTypeWithAlignment(const QualType &QT) {
+  return QT->isIncompleteArrayType() || !QT->isIncompleteType();
+}
+
 long long clang_Type_getAlignOf(CXType T) {
   if (T.kind == CXType_Invalid)
 return CXTypeLayoutError_Invalid;
@@ -895,7 +899,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (!isIncompleteTypeWithAlignment(QT))
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -950,10 +954,14 @@
   return Ctx.getTypeSizeInChars(QT).getQuantity();
 }
 
+static bool isTypeIncompleteForLayout(const QualType &QT) {
+  return QT->isIncompleteType() && !QT->isIncompleteArrayType();
+}
+
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (isTypeIncompleteForLayout(FQT))
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,31 @@
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+
+struct Foo 

[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-05-01 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee updated this revision to Diff 197557.
JornVernee marked an inline comment as done.
JornVernee added a comment.

- Removed const& QualType and passing by-value instead
- Ran print-type-size.c through clang-format

FWIW, clang-format was removing the newline at the end of the file, so I added 
it back manually.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61239/new/

https://reviews.llvm.org/D61239

Files:
  test/Index/print-type-size.c
  tools/libclang/CXType.cpp


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -885,6 +885,10 @@
   return result;
 }
 
+static bool isIncompleteTypeWithAlignment(QualType QT) {
+  return QT->isIncompleteArrayType() || !QT->isIncompleteType();
+}
+
 long long clang_Type_getAlignOf(CXType T) {
   if (T.kind == CXType_Invalid)
 return CXTypeLayoutError_Invalid;
@@ -895,7 +899,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (!isIncompleteTypeWithAlignment(QT))
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -950,10 +954,14 @@
   return Ctx.getTypeSizeInChars(QT).getQuantity();
 }
 
+static bool isTypeIncompleteForLayout(QualType QT) {
+  return QT->isIncompleteType() && !QT->isIncompleteArrayType();
+}
+
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (isTypeIncompleteForLayout(FQT))
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,31 @@
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+
+struct Foo {
+  int size;
+  // CHECK: FieldDecl=size:4:7 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+  void *data[];
+  // CHECK: FieldDecl=data:6:9 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64]
+};
+
+struct Bar {
+  int size;
+  // CHECK: FieldDecl=size:11:7 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+  struct {
+int dummy;
+// CHECK: FieldDecl=dummy:14:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=64/0]
+void *data[];
+// CHECK: FieldDecl=data:16:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=128/64]
+  };
+};
+
+struct Baz {
+  int size;
+  // CHECK: FieldDecl=size:22:7 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+  union {
+void *data1[];
+// CHECK: FieldDecl=data1:25:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+void *data2[];
+// CHECK: FieldDecl=data2:27:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+  };
+};
+


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -885,6 +885,10 @@
   return result;
 }
 
+static bool isIncompleteTypeWithAlignment(QualType QT) {
+  return QT->isIncompleteArrayType() || !QT->isIncompleteType();
+}
+
 long long clang_Type_getAlignOf(CXType T) {
   if (T.kind == CXType_Invalid)
 return CXTypeLayoutError_Invalid;
@@ -895,7 +899,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (!isIncompleteTypeWithAlignment(QT))
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -950,10 +954,14 @@
   return Ctx.getTypeSizeInChars(QT).getQuantity();
 }
 
+static bool isTypeIncompleteForLayout(QualType QT) {
+  return QT->isIncompleteType() && !QT->isIncompleteArrayType();
+}
+
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (isTypeIncompleteForLayout(FQT))
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,31 @@
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+
+struct Foo {
+  int size;
+  // CHECK: FieldDecl=size:4:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+  void *data[];
+  // CHECK: Field

[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-05-01 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee updated this revision to Diff 197583.
JornVernee marked 3 inline comments as done.
JornVernee added a comment.

Removed spurious newline


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61239/new/

https://reviews.llvm.org/D61239

Files:
  test/Index/print-type-size.c
  tools/libclang/CXType.cpp


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -885,6 +885,10 @@
   return result;
 }
 
+static bool isIncompleteTypeWithAlignment(QualType QT) {
+  return QT->isIncompleteArrayType() || !QT->isIncompleteType();
+}
+
 long long clang_Type_getAlignOf(CXType T) {
   if (T.kind == CXType_Invalid)
 return CXTypeLayoutError_Invalid;
@@ -895,7 +899,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (!isIncompleteTypeWithAlignment(QT))
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -950,10 +954,14 @@
   return Ctx.getTypeSizeInChars(QT).getQuantity();
 }
 
+static bool isTypeIncompleteForLayout(QualType QT) {
+  return QT->isIncompleteType() && !QT->isIncompleteArrayType();
+}
+
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (isTypeIncompleteForLayout(FQT))
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,31 @@
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+
+struct Foo {
+  int size;
+  // CHECK: FieldDecl=size:4:7 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+  void *data[];
+  // CHECK: FieldDecl=data:6:9 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64]
+};
+
+struct Bar {
+  int size;
+  // CHECK: FieldDecl=size:11:7 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+  struct {
+int dummy;
+// CHECK: FieldDecl=dummy:14:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=64/0]
+void *data[];
+// CHECK: FieldDecl=data:16:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=128/64]
+  };
+};
+
+struct Baz {
+  int size;
+  // CHECK: FieldDecl=size:22:7 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+  union {
+void *data1[];
+// CHECK: FieldDecl=data1:25:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+void *data2[];
+// CHECK: FieldDecl=data2:27:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64/0]
+  };
+};
+


Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -885,6 +885,10 @@
   return result;
 }
 
+static bool isIncompleteTypeWithAlignment(QualType QT) {
+  return QT->isIncompleteArrayType() || !QT->isIncompleteType();
+}
+
 long long clang_Type_getAlignOf(CXType T) {
   if (T.kind == CXType_Invalid)
 return CXTypeLayoutError_Invalid;
@@ -895,7 +899,7 @@
   // [expr.alignof] p3: if reference type, return size of referenced type
   if (QT->isReferenceType())
 QT = QT.getNonReferenceType();
-  if (QT->isIncompleteType())
+  if (!isIncompleteTypeWithAlignment(QT))
 return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
 return CXTypeLayoutError_Dependent;
@@ -950,10 +954,14 @@
   return Ctx.getTypeSizeInChars(QT).getQuantity();
 }
 
+static bool isTypeIncompleteForLayout(QualType QT) {
+  return QT->isIncompleteType() && !QT->isIncompleteArrayType();
+}
+
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
 QualType FQT = I->getType();
-if (FQT->isIncompleteType())
+if (isTypeIncompleteForLayout(FQT))
   return CXTypeLayoutError_Incomplete;
 if (FQT->isDependentType())
   return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,31 @@
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+
+struct Foo {
+  int size;
+  // CHECK: FieldDecl=size:4:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+  void *data[];
+  // CHECK: FieldDecl=data:6:9 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=8] [offsetof=64]
+};
+
+struct Bar {
+  int size;
+  // CHECK: FieldDecl=size:11:7 

[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-05-01 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee added a comment.

In D61239#1486634 , @aaron.ballman 
wrote:

> LGTM, thank you! That's strange that clang-format would remove the newline 
> from the end of the file. I don't get that behavior when I try it, so it 
> makes me wonder what's different.


Yeah, my mistake. It was there after all. The output from clang-format looked 
the same as what I had before, but I think I just didn't catch the newline when 
copy-pasting the diff the first time :)

Also, I don't have committer access. Would you mind committing this?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61239/new/

https://reviews.llvm.org/D61239



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61239: [libclang] Allow field offset lookups in types with incomplete arrays.

2019-05-02 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee added a comment.

In D61239#1487406 , @aaron.ballman 
wrote:

> In D61239#1486692 , @JornVernee 
> wrote:
>
> > Also, I don't have committer access. Would you mind committing this?
>
>
> Happy to do so -- I'll try to get it in this week if I have the time, but it 
> may not happen until early next week.


Take your time. Thanks for al the help!


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61239/new/

https://reviews.llvm.org/D61239



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61716: [libclang] Expose AtomicType

2020-04-09 Thread Jorn Vernee via Phabricator via cfe-commits
JornVernee added a comment.

Would like to try to draw attention to this patch again, since it seems to have 
gone under the radar. Can someone review this/help get it integrated? We are 
still having to work around _Atomic types because we can't get to the 
underlying value type. Thanks


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61716/new/

https://reviews.llvm.org/D61716



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits