75 lines · c
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-exception6//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_FIELD18//19// This will generate20//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