1//===- NativeTypeUDT.cpp - info about class/struct type ---------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h" 10 11#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" 12 13#include <cassert> 14 15using namespace llvm; 16using namespace llvm::codeview; 17using namespace llvm::pdb; 18 19NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id, 20 codeview::TypeIndex TI, codeview::ClassRecord CR) 21 : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI), 22 Class(std::move(CR)), Tag(Class.getPointer()) {} 23 24NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id, 25 codeview::TypeIndex TI, codeview::UnionRecord UR) 26 : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI), 27 Union(std::move(UR)), Tag(Union.getPointer()) {} 28 29NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id, 30 NativeTypeUDT &UnmodifiedType, 31 codeview::ModifierRecord Modifier) 32 : NativeRawSymbol(Session, PDB_SymType::UDT, Id), 33 UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {} 34 35NativeTypeUDT::~NativeTypeUDT() {} 36 37void NativeTypeUDT::dump(raw_ostream &OS, int Indent, 38 PdbSymbolIdField ShowIdFields, 39 PdbSymbolIdField RecurseIdFields) const { 40 41 NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields); 42 43 dumpSymbolField(OS, "name", getName(), Indent); 44 dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session, 45 PdbSymbolIdField::LexicalParent, ShowIdFields, 46 RecurseIdFields); 47 if (Modifiers.hasValue()) 48 dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent, 49 Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields, 50 RecurseIdFields); 51 if (getUdtKind() != PDB_UdtType::Union) 52 dumpSymbolField(OS, "virtualTableShapeId", getVirtualTableShapeId(), 53 Indent); 54 dumpSymbolField(OS, "length", getLength(), Indent); 55 dumpSymbolField(OS, "udtKind", getUdtKind(), Indent); 56 dumpSymbolField(OS, "constructor", hasConstructor(), Indent); 57 dumpSymbolField(OS, "constType", isConstType(), Indent); 58 dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent); 59 dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent); 60 dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent); 61 dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent); 62 dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent); 63 dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent); 64 dumpSymbolField(OS, "nested", isNested(), Indent); 65 dumpSymbolField(OS, "packed", isPacked(), Indent); 66 dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent); 67 dumpSymbolField(OS, "scoped", isScoped(), Indent); 68 dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent); 69 dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent); 70 dumpSymbolField(OS, "volatileType", isVolatileType(), Indent); 71} 72 73std::string NativeTypeUDT::getName() const { 74 if (UnmodifiedType) 75 return UnmodifiedType->getName(); 76 77 return Tag->getName(); 78} 79 80SymIndexId NativeTypeUDT::getLexicalParentId() const { return 0; } 81 82SymIndexId NativeTypeUDT::getUnmodifiedTypeId() const { 83 if (UnmodifiedType) 84 return UnmodifiedType->getSymIndexId(); 85 86 return 0; 87} 88 89SymIndexId NativeTypeUDT::getVirtualTableShapeId() const { 90 if (UnmodifiedType) 91 return UnmodifiedType->getVirtualTableShapeId(); 92 93 if (Class) 94 return Session.getSymbolCache().findSymbolByTypeIndex(Class->VTableShape); 95 96 return 0; 97} 98 99uint64_t NativeTypeUDT::getLength() const { 100 if (UnmodifiedType) 101 return UnmodifiedType->getLength(); 102 103 if (Class) 104 return Class->getSize(); 105 106 return Union->getSize(); 107} 108 109PDB_UdtType NativeTypeUDT::getUdtKind() const { 110 if (UnmodifiedType) 111 return UnmodifiedType->getUdtKind(); 112 113 switch (Tag->Kind) { 114 case TypeRecordKind::Class: 115 return PDB_UdtType::Class; 116 case TypeRecordKind::Union: 117 return PDB_UdtType::Union; 118 case TypeRecordKind::Struct: 119 return PDB_UdtType::Struct; 120 case TypeRecordKind::Interface: 121 return PDB_UdtType::Interface; 122 default: 123 llvm_unreachable("Unexected udt kind"); 124 } 125} 126 127bool NativeTypeUDT::hasConstructor() const { 128 if (UnmodifiedType) 129 return UnmodifiedType->hasConstructor(); 130 131 return (Tag->Options & ClassOptions::HasConstructorOrDestructor) != 132 ClassOptions::None; 133} 134 135bool NativeTypeUDT::isConstType() const { 136 if (!Modifiers) 137 return false; 138 return (Modifiers->Modifiers & ModifierOptions::Const) != 139 ModifierOptions::None; 140} 141 142bool NativeTypeUDT::hasAssignmentOperator() const { 143 if (UnmodifiedType) 144 return UnmodifiedType->hasAssignmentOperator(); 145 146 return (Tag->Options & ClassOptions::HasOverloadedAssignmentOperator) != 147 ClassOptions::None; 148} 149 150bool NativeTypeUDT::hasCastOperator() const { 151 if (UnmodifiedType) 152 return UnmodifiedType->hasCastOperator(); 153 154 return (Tag->Options & ClassOptions::HasConversionOperator) != 155 ClassOptions::None; 156} 157 158bool NativeTypeUDT::hasNestedTypes() const { 159 if (UnmodifiedType) 160 return UnmodifiedType->hasNestedTypes(); 161 162 return (Tag->Options & ClassOptions::ContainsNestedClass) != 163 ClassOptions::None; 164} 165 166bool NativeTypeUDT::hasOverloadedOperator() const { 167 if (UnmodifiedType) 168 return UnmodifiedType->hasOverloadedOperator(); 169 170 return (Tag->Options & ClassOptions::HasOverloadedOperator) != 171 ClassOptions::None; 172} 173 174bool NativeTypeUDT::isInterfaceUdt() const { return false; } 175 176bool NativeTypeUDT::isIntrinsic() const { 177 if (UnmodifiedType) 178 return UnmodifiedType->isIntrinsic(); 179 180 return (Tag->Options & ClassOptions::Intrinsic) != ClassOptions::None; 181} 182 183bool NativeTypeUDT::isNested() const { 184 if (UnmodifiedType) 185 return UnmodifiedType->isNested(); 186 187 return (Tag->Options & ClassOptions::Nested) != ClassOptions::None; 188} 189 190bool NativeTypeUDT::isPacked() const { 191 if (UnmodifiedType) 192 return UnmodifiedType->isPacked(); 193 194 return (Tag->Options & ClassOptions::Packed) != ClassOptions::None; 195} 196 197bool NativeTypeUDT::isRefUdt() const { return false; } 198 199bool NativeTypeUDT::isScoped() const { 200 if (UnmodifiedType) 201 return UnmodifiedType->isScoped(); 202 203 return (Tag->Options & ClassOptions::Scoped) != ClassOptions::None; 204} 205 206bool NativeTypeUDT::isValueUdt() const { return false; } 207 208bool NativeTypeUDT::isUnalignedType() const { 209 if (!Modifiers) 210 return false; 211 return (Modifiers->Modifiers & ModifierOptions::Unaligned) != 212 ModifierOptions::None; 213} 214 215bool NativeTypeUDT::isVolatileType() const { 216 if (!Modifiers) 217 return false; 218 return (Modifiers->Modifiers & ModifierOptions::Volatile) != 219 ModifierOptions::None; 220} 221