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