int DwarfDie::typeAlignment() const { switch (tag()) { case DW_TAG_base_type: case DW_TAG_enumeration_type: return std::min(typeSize(), 8); // TODO: 32bit support case DW_TAG_array_type: case DW_TAG_const_type: case DW_TAG_restrict_type: case DW_TAG_typedef: case DW_TAG_volatile_type: { const auto typeDie = attribute(DW_AT_type).value<DwarfDie*>(); assert(typeDie); return typeDie->typeAlignment(); } case DW_TAG_pointer_type: case DW_TAG_reference_type: case DW_TAG_rvalue_reference_type: return 8; // TODO: 32bit support case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: { int align = 1; foreach (const auto child, children()) { if (child->tag() != DW_TAG_member && child->tag() != DW_TAG_inheritance) continue; if (child->isStaticMember()) continue; const auto typeDie = child->attribute(DW_AT_type).value<DwarfDie*>(); assert(typeDie); align = std::max(align, typeDie->typeAlignment()); } return align; } } return 0; }
inline size_t alignedUpTo(size_t offset, TypePtr type) { return alignedUpTo(offset, typeAlignment(type)); }