1*453102a0SJez Ng //===- Layout.h -----------------------------------------------------------===// 2*453102a0SJez Ng // 3*453102a0SJez Ng // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*453102a0SJez Ng // See https://llvm.org/LICENSE.txt for license information. 5*453102a0SJez Ng // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*453102a0SJez Ng // 7*453102a0SJez Ng //===----------------------------------------------------------------------===// 8*453102a0SJez Ng 9*453102a0SJez Ng // Convenience macros for obtaining offsets of members in structs. 10*453102a0SJez Ng // 11*453102a0SJez Ng // Usage: 12*453102a0SJez Ng // 13*453102a0SJez Ng // #define FOR_EACH_FOO_FIELD(DO) \ 14*453102a0SJez Ng // DO(Ptr, bar) \ 15*453102a0SJez Ng // DO(uint32_t, baz) \ 16*453102a0SJez Ng // CREATE_LAYOUT_CLASS(Foo, FOR_EACH_FOO_FIELD) 17*453102a0SJez Ng // #undef FOR_EACH_FOO_FIELD 18*453102a0SJez Ng // 19*453102a0SJez Ng // This will generate 20*453102a0SJez Ng // 21*453102a0SJez Ng // struct FooLayout { 22*453102a0SJez Ng // uint32_t barOffset; 23*453102a0SJez Ng // uint32_t bazOffset; 24*453102a0SJez Ng // uint32_t totalSize; 25*453102a0SJez Ng // 26*453102a0SJez Ng // FooLayout(size_t wordSize) { 27*453102a0SJez Ng // if (wordSize == 8) 28*453102a0SJez Ng // init<uint64_t>(); 29*453102a0SJez Ng // else { 30*453102a0SJez Ng // assert(wordSize == 4); 31*453102a0SJez Ng // init<uint32_t>(); 32*453102a0SJez Ng // } 33*453102a0SJez Ng // } 34*453102a0SJez Ng // 35*453102a0SJez Ng // private: 36*453102a0SJez Ng // template <class Ptr> void init() { 37*453102a0SJez Ng // FOR_EACH_FIELD(_INIT_OFFSET); 38*453102a0SJez Ng // barOffset = offsetof(Layout<Ptr>, bar); 39*453102a0SJez Ng // bazOffset = offsetof(Layout<Ptr>, baz); 40*453102a0SJez Ng // totalSize = sizeof(Layout<Ptr>); 41*453102a0SJez Ng // } 42*453102a0SJez Ng // template <class Ptr> struct Layout { 43*453102a0SJez Ng // Ptr bar; 44*453102a0SJez Ng // uint32_t baz; 45*453102a0SJez Ng // }; 46*453102a0SJez Ng // }; 47*453102a0SJez Ng 48*453102a0SJez Ng #define _OFFSET_FOR_FIELD(_, name) uint32_t name##Offset; 49*453102a0SJez Ng #define _INIT_OFFSET(type, name) name##Offset = offsetof(Layout<Ptr>, name); 50*453102a0SJez Ng #define _LAYOUT_ENTRY(type, name) type name; 51*453102a0SJez Ng 52*453102a0SJez Ng #define CREATE_LAYOUT_CLASS(className, FOR_EACH_FIELD) \ 53*453102a0SJez Ng struct className##Layout { \ 54*453102a0SJez Ng FOR_EACH_FIELD(_OFFSET_FOR_FIELD) \ 55*453102a0SJez Ng uint32_t totalSize; \ 56*453102a0SJez Ng \ 57*453102a0SJez Ng className##Layout(size_t wordSize) { \ 58*453102a0SJez Ng if (wordSize == 8) \ 59*453102a0SJez Ng init<uint64_t>(); \ 60*453102a0SJez Ng else { \ 61*453102a0SJez Ng assert(wordSize == 4); \ 62*453102a0SJez Ng init<uint32_t>(); \ 63*453102a0SJez Ng } \ 64*453102a0SJez Ng } \ 65*453102a0SJez Ng \ 66*453102a0SJez Ng private: \ 67*453102a0SJez Ng template <class Ptr> void init() { \ 68*453102a0SJez Ng FOR_EACH_FIELD(_INIT_OFFSET); \ 69*453102a0SJez Ng totalSize = sizeof(Layout<Ptr>); \ 70*453102a0SJez Ng } \ 71*453102a0SJez Ng template <class Ptr> struct Layout { \ 72*453102a0SJez Ng FOR_EACH_FIELD(_LAYOUT_ENTRY) \ 73*453102a0SJez Ng }; \ 74*453102a0SJez Ng } 75