r179251 - [libclang] Expose record layout info via new libclang functions:

Matt Beaumont-Gay matthewbg at google.com
Fri Jun 21 15:13:32 PDT 2013


Apologies for the necrothread...

On Wed, Apr 10, 2013 at 6:20 PM, Argyrios Kyrtzidis <akyrtzi at gmail.com> wrote:
> Author: akirtzidis
> Date: Wed Apr 10 20:20:11 2013
> New Revision: 179251
>
> URL: http://llvm.org/viewvc/llvm-project?rev=179251&view=rev
> Log:
> [libclang] Expose record layout info via new libclang functions:
>
> clang_Type_getAlignOf
> clang_Type_getSizeOf
> clang_Type_getOffsetOf
> clang_Cursor_isBitField
>
> Patch by Loïc Jaquemet!
>
> Added:
>     cfe/trunk/test/Index/print-type-size.cpp
> Modified:
>     cfe/trunk/bindings/python/clang/cindex.py
>     cfe/trunk/bindings/python/tests/cindex/test_type.py
>     cfe/trunk/bindings/python/tests/cindex/util.py
>     cfe/trunk/include/clang-c/Index.h
>     cfe/trunk/tools/c-index-test/c-index-test.c
>     cfe/trunk/tools/libclang/CXType.cpp
>     cfe/trunk/tools/libclang/libclang.exports
>
<snip>
> Added: cfe/trunk/test/Index/print-type-size.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-type-size.cpp?rev=179251&view=auto
> ==============================================================================
> --- cfe/trunk/test/Index/print-type-size.cpp (added)
> +++ cfe/trunk/test/Index/print-type-size.cpp Wed Apr 10 20:20:11 2013
> @@ -0,0 +1,428 @@
> +// from SemaCXX/class-layout.cpp
> +// RUN: c-index-test -test-print-type-size %s -target x86_64-pc-linux-gnu | FileCheck -check-prefix=CHECK64 %s
> +// RUN: c-index-test -test-print-type-size %s -target i386-apple-darwin9 | FileCheck -check-prefix=CHECK32 %s
> +
> +namespace basic {
> +
> +// CHECK64: VarDecl=v:[[@LINE+2]]:6 (Definition) [type=void] [typekind=Void]
> +// CHECK32: VarDecl=v:[[@LINE+1]]:6 (Definition) [type=void] [typekind=Void]
> +void v;
> +
> +// CHECK64: VarDecl=v1:[[@LINE+2]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=8] [alignof=8]
> +// CHECK32: VarDecl=v1:[[@LINE+1]]:7 (Definition) [type=void *] [typekind=Pointer] [sizeof=4] [alignof=4]
> +void *v1;
> +
> +// offsetof
> +// CHECK64: StructDecl=simple:[[@LINE+2]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=48] [alignof=8]
> +// CHECK32: StructDecl=simple:[[@LINE+1]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=36] [alignof=4]
> +struct simple {
> +  int a;
> +  char b;
> +// CHECK64: FieldDecl=c:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=40] [BitFieldSize=3]
> +  int c:3;
> +  long d;
> +  int e:5;
> +// CHECK64: FieldDecl=f:[[@LINE+1]]:7 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=133] [BitFieldSize=4]
> +  int f:4;
> +// CHECK64: FieldDecl=g:[[@LINE+2]]:13 (Definition) [type=long long] [typekind=LongLong] [sizeof=8] [alignof=8] [offsetof=192]
> +// CHECK32: FieldDecl=g:[[@LINE+1]]:13 (Definition) [type=long long] [typekind=LongLong] [sizeof=8] [alignof=4] [offsetof=128]
> +  long long g;
> +// CHECK64: FieldDecl=h:[[@LINE+1]]:8 (Definition) [type=char] [typekind=Char_S] [sizeof=1] [alignof=1] [offsetof=256] [BitFieldSize=3]
> +  char h:3;
> +  char i:3;
> +  float j;
> +// CHECK64: FieldDecl=k:[[@LINE+2]]:10 (Definition) [type=char *] [typekind=Pointer] [sizeof=8] [alignof=8] [offsetof=320]
> +// CHECK32: FieldDecl=k:[[@LINE+1]]:10 (Definition) [type=char *] [typekind=Pointer] [sizeof=4] [alignof=4] [offsetof=256]
> +  char * k;
> +};
> +
> +
> +// CHECK64: UnionDecl=u:[[@LINE+2]]:7 (Definition) [type=basic::u] [typekind=Record] [sizeof=48] [alignof=8]
> +// CHECK32: UnionDecl=u:[[@LINE+1]]:7 (Definition) [type=basic::u] [typekind=Record] [sizeof=36] [alignof=4]
> +union u {
> +  int u1;
> +  long long u2;
> +  struct simple s1;
> +};
> +
> +// CHECK64: VarDecl=s1:[[@LINE+2]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=48] [alignof=8]
> +// CHECK32: VarDecl=s1:[[@LINE+1]]:8 (Definition) [type=basic::simple] [typekind=Record] [sizeof=36] [alignof=4]
> +simple s1;
> +
> +struct Test {
> +  struct {
> +    union {
> +//CHECK64: FieldDecl=foo:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
> +      int foo;
> +    };
> +  };
> +};
> +
> +struct Test2 {
> +  struct {
> +    struct {
> +//CHECK64: FieldDecl=foo:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
> +      int foo;
> +    };
> +    struct {
> +//CHECK64: FieldDecl=bar:[[@LINE+1]]:11 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=32]
> +      int bar;
> +    };
> +    struct {
> +        struct {
> +//CHECK64: FieldDecl=foobar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64]
> +          int foobar;
> +        };
> +    };
> +    struct inner {
> +        struct {
> +//CHECK64: FieldDecl=mybar:[[@LINE+1]]:15 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
> +          int mybar;
> +        };
> +//CHECK64: FieldDecl=mole:[[@LINE+1]]:7 (Definition) [type=struct inner] [typekind=Unexposed] [sizeof=4] [alignof=4] [offsetof=96]
> +    } mole;
> +  };
> +};

This struct is invalid:
tools/clang/test/Index/print-type-size.cpp:77:12: error: types cannot
be declared in an anonymous struct
    struct inner {
           ^

I noticed because it trips an assert I added to
ASTContext::getASTRecordLayout (asserting that the decl is valid). How
deeply do you care about this particular part of the test case? Can I
remove it, or is there a particular fix I should apply?

I have a patch which adds some invalid-decl checks to
clang_Type_getOffsetOf, but it breaks all of the existing test cases
which explicitly exercise invalid structs (not to mention Test2
above). It's obviously important that we don't crash on those inputs,
but I'm not sure I see the value of checking for any particular
output.

Thoughts?

Thanks,
Matt




More information about the cfe-commits mailing list