brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 6a7653f Raw
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