forked from OSchip/llvm-project
[CodeView] Add function to get size in bytes for TypeIndex/CVType.
Given a TypeIndex or CVType return its size in bytes. Basically it is the inverse to 'CodeViewDebug::lowerTypeBasic', that returns a TypeIndex based in a size. Reviewed By: rnk, djtodoro Differential Revision: https://reviews.llvm.org/D129846
This commit is contained in:
parent
7042417ef1
commit
a3f7a2c183
|
@ -41,6 +41,27 @@ inline bool isIdRecord(TypeLeafKind K) {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
|
||||
|
|
|
@ -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 @@ TypeIndex llvm::codeview::getModifiedType(const CVType &CVT) {
|
|||
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 <typename RecordT> static uint64_t getUdtSize(CVType CVT) {
|
||||
RecordT Record;
|
||||
if (auto EC = TypeDeserializer::deserializeAs<RecordT>(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<ClassRecord>(std::move(CVT));
|
||||
case LF_UNION:
|
||||
return getUdtSize<UnionRecord>(std::move(CVT));
|
||||
default:
|
||||
return CVT.length();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue