10b57cec5SDimitry Andric //===- TypeRecordHelpers.cpp ------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 120b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" 13bdd1243dSDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric using namespace llvm; 160b57cec5SDimitry Andric using namespace llvm::codeview; 170b57cec5SDimitry Andric getUdtOptions(CVType CVT)180b57cec5SDimitry Andrictemplate <typename RecordT> static ClassOptions getUdtOptions(CVType CVT) { 190b57cec5SDimitry Andric RecordT Record; 200b57cec5SDimitry Andric if (auto EC = TypeDeserializer::deserializeAs<RecordT>(CVT, Record)) { 210b57cec5SDimitry Andric consumeError(std::move(EC)); 220b57cec5SDimitry Andric return ClassOptions::None; 230b57cec5SDimitry Andric } 240b57cec5SDimitry Andric return Record.getOptions(); 250b57cec5SDimitry Andric } 260b57cec5SDimitry Andric isUdtForwardRef(CVType CVT)270b57cec5SDimitry Andricbool llvm::codeview::isUdtForwardRef(CVType CVT) { 280b57cec5SDimitry Andric ClassOptions UdtOptions = ClassOptions::None; 290b57cec5SDimitry Andric switch (CVT.kind()) { 300b57cec5SDimitry Andric case LF_STRUCTURE: 310b57cec5SDimitry Andric case LF_CLASS: 320b57cec5SDimitry Andric case LF_INTERFACE: 330b57cec5SDimitry Andric UdtOptions = getUdtOptions<ClassRecord>(std::move(CVT)); 340b57cec5SDimitry Andric break; 350b57cec5SDimitry Andric case LF_ENUM: 360b57cec5SDimitry Andric UdtOptions = getUdtOptions<EnumRecord>(std::move(CVT)); 370b57cec5SDimitry Andric break; 380b57cec5SDimitry Andric case LF_UNION: 390b57cec5SDimitry Andric UdtOptions = getUdtOptions<UnionRecord>(std::move(CVT)); 400b57cec5SDimitry Andric break; 410b57cec5SDimitry Andric default: 420b57cec5SDimitry Andric return false; 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric return (UdtOptions & ClassOptions::ForwardReference) != ClassOptions::None; 450b57cec5SDimitry Andric } 460b57cec5SDimitry Andric getModifiedType(const CVType & CVT)470b57cec5SDimitry AndricTypeIndex llvm::codeview::getModifiedType(const CVType &CVT) { 480b57cec5SDimitry Andric assert(CVT.kind() == LF_MODIFIER); 490b57cec5SDimitry Andric SmallVector<TypeIndex, 1> Refs; 500b57cec5SDimitry Andric discoverTypeIndices(CVT, Refs); 510b57cec5SDimitry Andric return Refs.front(); 520b57cec5SDimitry Andric } 53bdd1243dSDimitry Andric getSizeInBytesForTypeIndex(TypeIndex TI)54bdd1243dSDimitry Andricuint64_t llvm::codeview::getSizeInBytesForTypeIndex(TypeIndex TI) { 55bdd1243dSDimitry Andric if (!TI.isSimple()) 56bdd1243dSDimitry Andric return 0; 57bdd1243dSDimitry Andric if (TI.getSimpleMode() != SimpleTypeMode::Direct) { 58bdd1243dSDimitry Andric // We have a native pointer. 59bdd1243dSDimitry Andric switch (TI.getSimpleMode()) { 60bdd1243dSDimitry Andric case SimpleTypeMode::NearPointer: 61bdd1243dSDimitry Andric case SimpleTypeMode::FarPointer: 62bdd1243dSDimitry Andric case SimpleTypeMode::HugePointer: 63bdd1243dSDimitry Andric return 2; 64bdd1243dSDimitry Andric case SimpleTypeMode::NearPointer32: 65bdd1243dSDimitry Andric case SimpleTypeMode::FarPointer32: 66bdd1243dSDimitry Andric return 4; 67bdd1243dSDimitry Andric case SimpleTypeMode::NearPointer64: 68bdd1243dSDimitry Andric return 8; 69bdd1243dSDimitry Andric case SimpleTypeMode::NearPointer128: 70bdd1243dSDimitry Andric return 16; 71bdd1243dSDimitry Andric default: 72bdd1243dSDimitry Andric assert(false && "invalid simple type mode!"); 73bdd1243dSDimitry Andric } 74bdd1243dSDimitry Andric } 75bdd1243dSDimitry Andric switch (TI.getSimpleKind()) { 76bdd1243dSDimitry Andric case SimpleTypeKind::None: 77bdd1243dSDimitry Andric case SimpleTypeKind::Void: 78bdd1243dSDimitry Andric return 0; 79bdd1243dSDimitry Andric case SimpleTypeKind::HResult: 80bdd1243dSDimitry Andric return 4; 81bdd1243dSDimitry Andric case SimpleTypeKind::SByte: 82bdd1243dSDimitry Andric case SimpleTypeKind::Byte: 83bdd1243dSDimitry Andric return 1; 84bdd1243dSDimitry Andric 85bdd1243dSDimitry Andric // Signed/unsigned integer. 86bdd1243dSDimitry Andric case SimpleTypeKind::Int16Short: 87bdd1243dSDimitry Andric case SimpleTypeKind::UInt16Short: 88bdd1243dSDimitry Andric case SimpleTypeKind::Int16: 89bdd1243dSDimitry Andric case SimpleTypeKind::UInt16: 90bdd1243dSDimitry Andric return 2; 91bdd1243dSDimitry Andric case SimpleTypeKind::Int32Long: 92bdd1243dSDimitry Andric case SimpleTypeKind::UInt32Long: 93bdd1243dSDimitry Andric case SimpleTypeKind::Int32: 94bdd1243dSDimitry Andric case SimpleTypeKind::UInt32: 95bdd1243dSDimitry Andric return 4; 96bdd1243dSDimitry Andric case SimpleTypeKind::Int64Quad: 97bdd1243dSDimitry Andric case SimpleTypeKind::UInt64Quad: 98bdd1243dSDimitry Andric case SimpleTypeKind::Int64: 99bdd1243dSDimitry Andric case SimpleTypeKind::UInt64: 100bdd1243dSDimitry Andric return 8; 101bdd1243dSDimitry Andric case SimpleTypeKind::Int128Oct: 102bdd1243dSDimitry Andric case SimpleTypeKind::UInt128Oct: 103bdd1243dSDimitry Andric case SimpleTypeKind::Int128: 104bdd1243dSDimitry Andric case SimpleTypeKind::UInt128: 105bdd1243dSDimitry Andric return 16; 106bdd1243dSDimitry Andric 107bdd1243dSDimitry Andric // Signed/Unsigned character. 108bdd1243dSDimitry Andric case SimpleTypeKind::Character8: 109bdd1243dSDimitry Andric case SimpleTypeKind::SignedCharacter: 110bdd1243dSDimitry Andric case SimpleTypeKind::UnsignedCharacter: 111bdd1243dSDimitry Andric case SimpleTypeKind::NarrowCharacter: 112bdd1243dSDimitry Andric return 1; 113bdd1243dSDimitry Andric case SimpleTypeKind::WideCharacter: 114bdd1243dSDimitry Andric case SimpleTypeKind::Character16: 115bdd1243dSDimitry Andric return 2; 116bdd1243dSDimitry Andric case SimpleTypeKind::Character32: 117bdd1243dSDimitry Andric return 4; 118bdd1243dSDimitry Andric 119bdd1243dSDimitry Andric // Float. 120bdd1243dSDimitry Andric case SimpleTypeKind::Float16: 121bdd1243dSDimitry Andric return 2; 122bdd1243dSDimitry Andric case SimpleTypeKind::Float32: 123bdd1243dSDimitry Andric return 4; 124bdd1243dSDimitry Andric case SimpleTypeKind::Float48: 125bdd1243dSDimitry Andric return 6; 126bdd1243dSDimitry Andric case SimpleTypeKind::Float64: 127bdd1243dSDimitry Andric return 8; 128bdd1243dSDimitry Andric case SimpleTypeKind::Float80: 129bdd1243dSDimitry Andric return 10; 130bdd1243dSDimitry Andric case SimpleTypeKind::Float128: 131bdd1243dSDimitry Andric return 16; 132bdd1243dSDimitry Andric 133bdd1243dSDimitry Andric // Boolean. 134bdd1243dSDimitry Andric case SimpleTypeKind::Boolean8: 135bdd1243dSDimitry Andric return 1; 136bdd1243dSDimitry Andric case SimpleTypeKind::Boolean16: 137bdd1243dSDimitry Andric return 2; 138bdd1243dSDimitry Andric case SimpleTypeKind::Boolean32: 139bdd1243dSDimitry Andric return 4; 140bdd1243dSDimitry Andric case SimpleTypeKind::Boolean64: 141bdd1243dSDimitry Andric return 8; 142bdd1243dSDimitry Andric case SimpleTypeKind::Boolean128: 143bdd1243dSDimitry Andric return 16; 144bdd1243dSDimitry Andric 145bdd1243dSDimitry Andric // Complex float. 146bdd1243dSDimitry Andric case SimpleTypeKind::Complex16: 147bdd1243dSDimitry Andric return 4; 14806c3fb27SDimitry Andric case SimpleTypeKind::Complex32: 149bdd1243dSDimitry Andric return 8; 15006c3fb27SDimitry Andric case SimpleTypeKind::Complex64: 151bdd1243dSDimitry Andric return 16; 15206c3fb27SDimitry Andric case SimpleTypeKind::Complex80: 15306c3fb27SDimitry Andric return 20; 15406c3fb27SDimitry Andric case SimpleTypeKind::Complex128: 15506c3fb27SDimitry Andric return 32; 156bdd1243dSDimitry Andric 157bdd1243dSDimitry Andric default: 158bdd1243dSDimitry Andric return 0; 159bdd1243dSDimitry Andric } 160bdd1243dSDimitry Andric } 161bdd1243dSDimitry Andric getUdtSize(CVType CVT)162bdd1243dSDimitry Andrictemplate <typename RecordT> static uint64_t getUdtSize(CVType CVT) { 163bdd1243dSDimitry Andric RecordT Record; 164bdd1243dSDimitry Andric if (auto EC = TypeDeserializer::deserializeAs<RecordT>(CVT, Record)) { 165bdd1243dSDimitry Andric consumeError(std::move(EC)); 166bdd1243dSDimitry Andric return 0; 167bdd1243dSDimitry Andric } 168bdd1243dSDimitry Andric return Record.getSize(); 169bdd1243dSDimitry Andric } 170bdd1243dSDimitry Andric getSizeInBytesForTypeRecord(CVType CVT)171bdd1243dSDimitry Andricuint64_t llvm::codeview::getSizeInBytesForTypeRecord(CVType CVT) { 172bdd1243dSDimitry Andric switch (CVT.kind()) { 173bdd1243dSDimitry Andric case LF_STRUCTURE: 174bdd1243dSDimitry Andric case LF_CLASS: 175bdd1243dSDimitry Andric case LF_INTERFACE: 176bdd1243dSDimitry Andric return getUdtSize<ClassRecord>(std::move(CVT)); 177bdd1243dSDimitry Andric case LF_UNION: 178bdd1243dSDimitry Andric return getUdtSize<UnionRecord>(std::move(CVT)); 179bdd1243dSDimitry Andric default: 180bdd1243dSDimitry Andric return CVT.length(); 181bdd1243dSDimitry Andric } 182bdd1243dSDimitry Andric } 183