Index: llvm/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h +++ llvm/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h @@ -41,6 +41,27 @@ } } +/// Given an arbitrary codeview type, determine if it is an LF_STRUCTURE, +/// LF_CLASS, LF_INTERFACE, LF_UNION. +inline bool isAggregate(CVType CVT) { + switch (CVT.kind()) { + case LF_STRUCTURE: + case LF_CLASS: + case LF_INTERFACE: + case LF_UNION: + return true; + default: + return false; + } +} + +/// Given an arbitrary codeview type index, determine its size. +uint64_t getSizeInBytesForTypeIndex(TypeIndex TI); + +/// Given an arbitrary codeview type, return the type's size in the case +/// of aggregate (LF_STRUCTURE, LF_CLASS, LF_INTERFACE, LF_UNION). +uint64_t getSizeInBytesForTypeRecord(CVType CVT); + } // namespace codeview } // namespace llvm Index: llvm/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp =================================================================== --- llvm/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp +++ llvm/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp @@ -9,8 +9,8 @@ #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" using namespace llvm; using namespace llvm::codeview; @@ -50,3 +50,133 @@ discoverTypeIndices(CVT, Refs); return Refs.front(); } + +uint64_t llvm::codeview::getSizeInBytesForTypeIndex(TypeIndex TI) { + if (!TI.isSimple()) + return 0; + if (TI.getSimpleMode() != SimpleTypeMode::Direct) { + // We have a native pointer. + switch (TI.getSimpleMode()) { + case SimpleTypeMode::NearPointer: + case SimpleTypeMode::FarPointer: + case SimpleTypeMode::HugePointer: + return 2; + case SimpleTypeMode::NearPointer32: + case SimpleTypeMode::FarPointer32: + return 4; + case SimpleTypeMode::NearPointer64: + return 8; + case SimpleTypeMode::NearPointer128: + return 16; + default: + assert(false && "invalid simple type mode!"); + } + } + switch (TI.getSimpleKind()) { + case SimpleTypeKind::None: + case SimpleTypeKind::Void: + return 0; + case SimpleTypeKind::HResult: + return 4; + case SimpleTypeKind::SByte: + case SimpleTypeKind::Byte: + return 1; + + // Signed/unsigned integer. + case SimpleTypeKind::Int16Short: + case SimpleTypeKind::UInt16Short: + case SimpleTypeKind::Int16: + case SimpleTypeKind::UInt16: + return 2; + case SimpleTypeKind::Int32Long: + case SimpleTypeKind::UInt32Long: + case SimpleTypeKind::Int32: + case SimpleTypeKind::UInt32: + return 4; + case SimpleTypeKind::Int64Quad: + case SimpleTypeKind::UInt64Quad: + case SimpleTypeKind::Int64: + case SimpleTypeKind::UInt64: + return 8; + case SimpleTypeKind::Int128Oct: + case SimpleTypeKind::UInt128Oct: + case SimpleTypeKind::Int128: + case SimpleTypeKind::UInt128: + return 16; + + // Signed/Unsigned character. + case SimpleTypeKind::Character8: + case SimpleTypeKind::SignedCharacter: + case SimpleTypeKind::UnsignedCharacter: + case SimpleTypeKind::NarrowCharacter: + return 1; + case SimpleTypeKind::WideCharacter: + case SimpleTypeKind::Character16: + return 2; + case SimpleTypeKind::Character32: + return 4; + + // Float. + case SimpleTypeKind::Float16: + return 2; + case SimpleTypeKind::Float32: + return 4; + case SimpleTypeKind::Float48: + return 6; + case SimpleTypeKind::Float64: + return 8; + case SimpleTypeKind::Float80: + return 10; + case SimpleTypeKind::Float128: + return 16; + + // Boolean. + case SimpleTypeKind::Boolean8: + return 1; + case SimpleTypeKind::Boolean16: + return 2; + case SimpleTypeKind::Boolean32: + return 4; + case SimpleTypeKind::Boolean64: + return 8; + case SimpleTypeKind::Boolean128: + return 16; + + // Complex float. + case SimpleTypeKind::Complex16: + return 2; + case SimpleTypeKind::Complex32: + return 4; + case SimpleTypeKind::Complex64: + return 8; + case SimpleTypeKind::Complex80: + return 10; + case SimpleTypeKind::Complex128: + return 16; + + default: + return 0; + } +} + +template static uint64_t getUdtSize(CVType CVT) { + RecordT Record; + if (auto EC = TypeDeserializer::deserializeAs(CVT, Record)) { + consumeError(std::move(EC)); + return 0; + } + return Record.getSize(); +} + +uint64_t llvm::codeview::getSizeInBytesForTypeRecord(CVType CVT) { + switch (CVT.kind()) { + case LF_STRUCTURE: + case LF_CLASS: + case LF_INTERFACE: + return getUdtSize(std::move(CVT)); + case LF_UNION: + return getUdtSize(std::move(CVT)); + default: + return CVT.length(); + } +}