[CodeView] Add function to get size in bytes for TypeIndex/CVType.
authorCarlos Alberto Enciso <carlos.alberto.enciso@gmail.com>
Mon, 8 Aug 2022 07:48:23 +0000 (08:48 +0100)
committerCarlos Alberto Enciso <carlos.alberto.enciso@gmail.com>
Mon, 8 Aug 2022 07:48:23 +0000 (08:48 +0100)
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

llvm/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h
llvm/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp

index 041f5214967c605f5cabbd564a42f05119080c01..aa183cd7d19d30a635b117607659faa64e9751d5 100644 (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
 
index 8e632f3be4609ad1b967eb58f7accabbda64f936..e44dec6d63966c0b415f0c5dc5f74bef1c775a54 100644 (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();
+  }
+}