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 | |