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 15 using namespace llvm; 16 using namespace llvm::codeview; 17 using namespace llvm::pdb; 18 19 NativeTypeUDT::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 24 NativeTypeUDT::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 29 NativeTypeUDT::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 35 NativeTypeUDT::~NativeTypeUDT() {} 36 37 void 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 73 std::string NativeTypeUDT::getName() const { 74 if (UnmodifiedType) 75 return UnmodifiedType->getName(); 76 77 return std::string(Tag->getName()); 78 } 79 80 SymIndexId NativeTypeUDT::getLexicalParentId() const { return 0; } 81 82 SymIndexId NativeTypeUDT::getUnmodifiedTypeId() const { 83 if (UnmodifiedType) 84 return UnmodifiedType->getSymIndexId(); 85 86 return 0; 87 } 88 89 SymIndexId 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 99 uint64_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 109 PDB_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("Unexpected udt kind"); 124 } 125 } 126 127 bool NativeTypeUDT::hasConstructor() const { 128 if (UnmodifiedType) 129 return UnmodifiedType->hasConstructor(); 130 131 return (Tag->Options & ClassOptions::HasConstructorOrDestructor) != 132 ClassOptions::None; 133 } 134 135 bool NativeTypeUDT::isConstType() const { 136 if (!Modifiers) 137 return false; 138 return (Modifiers->Modifiers & ModifierOptions::Const) != 139 ModifierOptions::None; 140 } 141 142 bool NativeTypeUDT::hasAssignmentOperator() const { 143 if (UnmodifiedType) 144 return UnmodifiedType->hasAssignmentOperator(); 145 146 return (Tag->Options & ClassOptions::HasOverloadedAssignmentOperator) != 147 ClassOptions::None; 148 } 149 150 bool NativeTypeUDT::hasCastOperator() const { 151 if (UnmodifiedType) 152 return UnmodifiedType->hasCastOperator(); 153 154 return (Tag->Options & ClassOptions::HasConversionOperator) != 155 ClassOptions::None; 156 } 157 158 bool NativeTypeUDT::hasNestedTypes() const { 159 if (UnmodifiedType) 160 return UnmodifiedType->hasNestedTypes(); 161 162 return (Tag->Options & ClassOptions::ContainsNestedClass) != 163 ClassOptions::None; 164 } 165 166 bool NativeTypeUDT::hasOverloadedOperator() const { 167 if (UnmodifiedType) 168 return UnmodifiedType->hasOverloadedOperator(); 169 170 return (Tag->Options & ClassOptions::HasOverloadedOperator) != 171 ClassOptions::None; 172 } 173 174 bool NativeTypeUDT::isInterfaceUdt() const { return false; } 175 176 bool NativeTypeUDT::isIntrinsic() const { 177 if (UnmodifiedType) 178 return UnmodifiedType->isIntrinsic(); 179 180 return (Tag->Options & ClassOptions::Intrinsic) != ClassOptions::None; 181 } 182 183 bool NativeTypeUDT::isNested() const { 184 if (UnmodifiedType) 185 return UnmodifiedType->isNested(); 186 187 return (Tag->Options & ClassOptions::Nested) != ClassOptions::None; 188 } 189 190 bool NativeTypeUDT::isPacked() const { 191 if (UnmodifiedType) 192 return UnmodifiedType->isPacked(); 193 194 return (Tag->Options & ClassOptions::Packed) != ClassOptions::None; 195 } 196 197 bool NativeTypeUDT::isRefUdt() const { return false; } 198 199 bool NativeTypeUDT::isScoped() const { 200 if (UnmodifiedType) 201 return UnmodifiedType->isScoped(); 202 203 return (Tag->Options & ClassOptions::Scoped) != ClassOptions::None; 204 } 205 206 bool NativeTypeUDT::isValueUdt() const { return false; } 207 208 bool NativeTypeUDT::isUnalignedType() const { 209 if (!Modifiers) 210 return false; 211 return (Modifiers->Modifiers & ModifierOptions::Unaligned) != 212 ModifierOptions::None; 213 } 214 215 bool NativeTypeUDT::isVolatileType() const { 216 if (!Modifiers) 217 return false; 218 return (Modifiers->Modifiers & ModifierOptions::Volatile) != 219 ModifierOptions::None; 220 } 221