<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">On Jun 21, 2013, at 3:13 PM, Matt Beaumont-Gay <<a href="mailto:matthewbg@google.com">matthewbg@google.com</a>> wrote:<br><div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Apologies for the necrothread...<br><br>On Wed, Apr 10, 2013 at 6:20 PM, Argyrios Kyrtzidis <<a href="mailto:akyrtzi@gmail.com">akyrtzi@gmail.com</a>> wrote:<br><blockquote type="cite">Author: akirtzidis<br>Date: Wed Apr 10 20:20:11 2013<br>New Revision: 179251<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=179251&view=rev">http://llvm.org/viewvc/llvm-project?rev=179251&view=rev</a><br>Log:<br>[libclang] Expose record layout info via new libclang functions:<br><br>clang_Type_getAlignOf<br>clang_Type_getSizeOf<br>clang_Type_getOffsetOf<br>clang_Cursor_isBitField<br><br>Patch by Loïc Jaquemet!<br><br>Added:<br>   cfe/trunk/test/Index/print-type-size.cpp<br>Modified:<br>   cfe/trunk/bindings/python/clang/cindex.py<br>   cfe/trunk/bindings/python/tests/cindex/test_type.py<br>   cfe/trunk/bindings/python/tests/cindex/util.py<br>   cfe/trunk/include/clang-c/Index.h<br>   cfe/trunk/tools/c-index-test/c-index-test.c<br>   cfe/trunk/tools/libclang/CXType.cpp<br>   cfe/trunk/tools/libclang/libclang.exports<br><br></blockquote><snip><br><blockquote type="cite">Added: cfe/trunk/test/Index/print-type-size.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-type-size.cpp?rev=179251&view=auto">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-type-size.cpp?rev=179251&view=auto</a><br>==============================================================================<br>--- cfe/trunk/test/Index/print-type-size.cpp (added)<br>+++ cfe/trunk/test/Index/print-type-size.cpp Wed Apr 10 20:20:11 2013<br>@@ -0,0 +1,428 @@<br>+// from SemaCXX/class-layout.cpp<br>+// RUN: c-index-test -test-print-type-size %s -target x86_64-pc-linux-gnu | FileCheck -check-prefix=CHECK64 %s<br>+// RUN: c-index-test -test-print-type-size %s -target i386-apple-darwin9 | FileCheck -check-prefix=CHECK32 %s<br>+<br>+namespace basic {<br>+<br>+// CHECK64: VarDecl=v:[[@LINE+2]]:6 (Definition) [type=void] [typekind=Void]<br>+// CHECK32: VarDecl=v:[[@LINE+1]]:6 (Definition) [type=void] [typekind=Void]<br>+void v;<br>+<br>+// CHECK64: VarDecl=v1:[[@LINE+2]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=8] [alignof=8]<br>+// CHECK32: VarDecl=v1:[[@LINE+1]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=4] [alignof=4]<br>+void *v1;<br>+<br>+// offsetof<br>+// CHECK64: StructDecl=simple:[[@LINE+2]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=48] [alignof=8]<br>+// CHECK32: StructDecl=simple:[[@LINE+1]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=36] [alignof=4]<br>+struct simple {<br>+  int a;<br>+  char b;<br>+// CHECK64: FieldDecl=c:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=40] [BitFieldSize=3]<br>+  int c:3;<br>+  long d;<br>+  int e:5;<br>+// CHECK64: FieldDecl=f:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=133] [BitFieldSize=4]<br>+  int f:4;<br>+// CHECK64: FieldDecl=g:[[@LINE+2]]:13 (Definition) [type=long long] [typekind=LongLong] [sizeof=8] [alignof=8] [offsetof=192]<br>+// CHECK32: FieldDecl=g:[[@LINE+1]]:13 (Definition) [type=long long] [typekind=LongLong] [sizeof=8] [alignof=4] [offsetof=128]<br>+  long long g;<br>+// CHECK64: FieldDecl=h:[[@LINE+1]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=256] [BitFieldSize=3]<br>+  char h:3;<br>+  char i:3;<br>+  float j;<br>+// CHECK64: FieldDecl=k:[[@LINE+2]]:10 (Definition) [type=char *] [typekind=Pointer] [sizeof=8] [alignof=8] [offsetof=320]<br>+// CHECK32: FieldDecl=k:[[@LINE+1]]:10 (Definition) [type=char *] [typekind=Pointer] [sizeof=4] [alignof=4] [offsetof=256]<br>+  char * k;<br>+};<br>+<br>+<br>+// CHECK64: UnionDecl=u:[[@LINE+2]]:7 (Definition) [type=basic::u] [typekind=Record] [sizeof=48] [alignof=8]<br>+// CHECK32: UnionDecl=u:[[@LINE+1]]:7 (Definition) [type=basic::u] [typekind=Record] [sizeof=36] [alignof=4]<br>+union u {<br>+  int u1;<br>+  long long u2;<br>+  struct simple s1;<br>+};<br>+<br>+// CHECK64: VarDecl=s1:[[@LINE+2]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=48] [alignof=8]<br>+// CHECK32: VarDecl=s1:[[@LINE+1]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=36] [alignof=4]<br>+simple s1;<br>+<br>+struct Test {<br>+  struct {<br>+    union {<br>+//CHECK64: FieldDecl=foo:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]<br>+      int foo;<br>+    };<br>+  };<br>+};<br>+<br>+struct Test2 {<br>+  struct {<br>+    struct {<br>+//CHECK64: FieldDecl=foo:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]<br>+      int foo;<br>+    };<br>+    struct {<br>+//CHECK64: FieldDecl=bar:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=32]<br>+      int bar;<br>+    };<br>+    struct {<br>+        struct {<br>+//CHECK64: FieldDecl=foobar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64]<br>+          int foobar;<br>+        };<br>+    };<br>+    struct inner {<br>+        struct {<br>+//CHECK64: FieldDecl=mybar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]<br>+          int mybar;<br>+        };<br>+//CHECK64: FieldDecl=mole:[[@LINE+1]]:7 (Definition) [type=struct inner] [typekind=Unexposed] [sizeof=4] [alignof=4] [offsetof=96]<br>+    } mole;<br>+  };<br>+};<br></blockquote><br>This struct is invalid:<br>tools/clang/test/Index/print-type-size.cpp:77:12: error: types cannot<br>be declared in an anonymous struct<br>   struct inner {<br>          ^<br><br>I noticed because it trips an assert I added to<br>ASTContext::getASTRecordLayout (asserting that the decl is valid). How<br>deeply do you care about this particular part of the test case? Can I<br>remove it, or is there a particular fix I should apply?<br><br>I have a patch which adds some invalid-decl checks to<br>clang_Type_getOffsetOf, but it breaks all of the existing test cases<br>which explicitly exercise invalid structs (not to mention Test2<br>above). It's obviously important that we don't crash on those inputs,<br>but I'm not sure I see the value of checking for any particular<br>output.<br><br>Thoughts?<br></div></blockquote><div dir="auto"><br></div><div dir="auto">I suggest adding the invalid-decl checks and leaving an invalid struct in the test to make sure libclang does not hit the assertion; the rest can be turned into valid decls so that the checks can work.</div><br><blockquote type="cite"><div style="font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>Thanks,<br>Matt</div></blockquote></div><br></body></html>