[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:
Carlos Alberto Enciso 2022-08-08 08:48:23 +01:00
parent 7042417ef1
commit a3f7a2c183
2 changed files with 152 additions and 1 deletions

View File

@ -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

View File

@ -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();
}
}