File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -3052,6 +3052,24 @@ bool Converter::VisitTypeTraitExpr(clang::TypeTraitExpr *expr) {
30523052 return false ;
30533053}
30543054
3055+ bool Converter::VisitOffsetOfExpr (clang::OffsetOfExpr *expr) {
3056+ std::string member_path;
3057+ for (unsigned i = 0 ; i < expr->getNumComponents (); ++i) {
3058+ const clang::OffsetOfNode &node = expr->getComponent (i);
3059+ ENSURE (node.getKind () == clang::OffsetOfNode::Field);
3060+ if (!member_path.empty ()) {
3061+ member_path += ' .' ;
3062+ }
3063+ member_path += GetNamedDeclAsString (node.getField ());
3064+ }
3065+ StrCat (
3066+ std::format (" ::std::mem::offset_of!({}, {}) as u64" ,
3067+ GetUnsafeTypeAsString (expr->getTypeSourceInfo ()->getType ()),
3068+ member_path));
3069+ computed_expr_type_ = ComputedExprType::FreshValue;
3070+ return false ;
3071+ }
3072+
30553073bool Converter::VisitEnumDecl (clang::EnumDecl *decl) {
30563074 ENSURE (decl_ids_.insert (GetID (decl)).second );
30573075 if (Mapper::Contains (ctx_.getCanonicalTagType (decl))) {
Original file line number Diff line number Diff line change @@ -349,6 +349,8 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
349349
350350 virtual bool VisitTypeTraitExpr (clang::TypeTraitExpr *expr);
351351
352+ virtual bool VisitOffsetOfExpr (clang::OffsetOfExpr *expr);
353+
352354 virtual bool VisitEnumDecl (clang::EnumDecl *decl);
353355
354356 virtual void AddFromImpl (clang::EnumDecl *decl);
Original file line number Diff line number Diff line change 1+ // no-compile: refcount
2+ #include < assert.h>
3+ #include < stddef.h>
4+ #include < stdint.h>
5+
6+ struct Layout {
7+ uint8_t a;
8+ uint32_t b;
9+ uint16_t c;
10+ };
11+
12+ struct Inner {
13+ uint16_t x;
14+ uint32_t y;
15+ };
16+
17+ struct Outer {
18+ uint8_t pad;
19+ struct Inner inner;
20+ };
21+
22+ int main (void ) {
23+ assert (offsetof (struct Layout , a) == 0 );
24+ assert (offsetof (struct Layout , b) == 4 );
25+ assert (offsetof (struct Layout , c) == 8 );
26+
27+ assert (offsetof (struct Outer , inner.y) == 8 );
28+
29+ struct Layout v = {0 };
30+ v.b = 0xDEADBEEF ;
31+ unsigned char *base = (unsigned char *)&v;
32+ uint32_t *bp = (uint32_t *)(base + offsetof (struct Layout , b));
33+ assert (*bp == 0xDEADBEEF );
34+
35+ return 0 ;
36+ }
Original file line number Diff line number Diff line change 1+ extern crate libc;
2+ use libc:: * ;
3+ extern crate libcc2rs;
4+ use libcc2rs:: * ;
5+ use std:: collections:: BTreeMap ;
6+ use std:: io:: { Read , Seek , Write } ;
7+ use std:: os:: fd:: { AsFd , FromRawFd , IntoRawFd } ;
8+ use std:: rc:: Rc ;
9+ #[ repr( C ) ]
10+ #[ derive( Copy , Clone , Default ) ]
11+ pub struct Layout {
12+ pub a : u8 ,
13+ pub b : u32 ,
14+ pub c : u16 ,
15+ }
16+ #[ repr( C ) ]
17+ #[ derive( Copy , Clone , Default ) ]
18+ pub struct Inner {
19+ pub x : u16 ,
20+ pub y : u32 ,
21+ }
22+ #[ repr( C ) ]
23+ #[ derive( Copy , Clone , Default ) ]
24+ pub struct Outer {
25+ pub pad : u8 ,
26+ pub inner : Inner ,
27+ }
28+ pub fn main ( ) {
29+ unsafe {
30+ std:: process:: exit ( main_0 ( ) as i32 ) ;
31+ }
32+ }
33+ unsafe fn main_0 ( ) -> i32 {
34+ assert ! ( ( ( :: std:: mem:: offset_of!( Layout , a) as u64 ) == ( 0_u64 ) ) ) ;
35+ assert ! ( ( ( :: std:: mem:: offset_of!( Layout , b) as u64 ) == ( 4_u64 ) ) ) ;
36+ assert ! ( ( ( :: std:: mem:: offset_of!( Layout , c) as u64 ) == ( 8_u64 ) ) ) ;
37+ assert ! ( ( ( :: std:: mem:: offset_of!( Outer , inner. y) as u64 ) == ( 8_u64 ) ) ) ;
38+ let mut v: Layout = Layout {
39+ a : 0_u8 ,
40+ b : 0_u32 ,
41+ c : 0_u16 ,
42+ } ;
43+ v. b = 3735928559_u32 ;
44+ let mut base: * mut u8 = ( ( & mut v as * mut Layout ) as * mut u8 ) ;
45+ let mut bp: * mut u32 =
46+ ( ( base. offset ( ( :: std:: mem:: offset_of!( Layout , b) as u64 ) as isize ) ) as * mut u32 ) ;
47+ assert ! ( ( ( * bp) == ( 3735928559_u32 ) ) ) ;
48+ return 0 ;
49+ }
You can’t perform that action at this time.
0 commit comments