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