1343171Sdim//===- NativeTypeUDT.cpp - info about class/struct type ---------*- C++ -*-===// 2343171Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343171Sdim// 7343171Sdim//===----------------------------------------------------------------------===// 8343171Sdim 9343171Sdim#include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h" 10343171Sdim 11343171Sdim#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" 12343171Sdim 13343171Sdim#include <cassert> 14343171Sdim 15343171Sdimusing namespace llvm; 16343171Sdimusing namespace llvm::codeview; 17343171Sdimusing namespace llvm::pdb; 18343171Sdim 19343171SdimNativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id, 20343171Sdim codeview::TypeIndex TI, codeview::ClassRecord CR) 21343171Sdim : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI), 22343171Sdim Class(std::move(CR)), Tag(Class.getPointer()) {} 23343171Sdim 24343171SdimNativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id, 25343171Sdim codeview::TypeIndex TI, codeview::UnionRecord UR) 26343171Sdim : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI), 27343171Sdim Union(std::move(UR)), Tag(Union.getPointer()) {} 28343171Sdim 29343171SdimNativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id, 30343171Sdim NativeTypeUDT &UnmodifiedType, 31343171Sdim codeview::ModifierRecord Modifier) 32343171Sdim : NativeRawSymbol(Session, PDB_SymType::UDT, Id), 33343171Sdim UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {} 34343171Sdim 35343171SdimNativeTypeUDT::~NativeTypeUDT() {} 36343171Sdim 37343171Sdimvoid NativeTypeUDT::dump(raw_ostream &OS, int Indent, 38343171Sdim PdbSymbolIdField ShowIdFields, 39343171Sdim PdbSymbolIdField RecurseIdFields) const { 40343171Sdim 41343171Sdim NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields); 42343171Sdim 43343171Sdim dumpSymbolField(OS, "name", getName(), Indent); 44343171Sdim dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session, 45343171Sdim PdbSymbolIdField::LexicalParent, ShowIdFields, 46343171Sdim RecurseIdFields); 47343171Sdim if (Modifiers.hasValue()) 48343171Sdim dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent, 49343171Sdim Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields, 50343171Sdim RecurseIdFields); 51343171Sdim if (getUdtKind() != PDB_UdtType::Union) 52343171Sdim dumpSymbolField(OS, "virtualTableShapeId", getVirtualTableShapeId(), 53343171Sdim Indent); 54343171Sdim dumpSymbolField(OS, "length", getLength(), Indent); 55343171Sdim dumpSymbolField(OS, "udtKind", getUdtKind(), Indent); 56343171Sdim dumpSymbolField(OS, "constructor", hasConstructor(), Indent); 57343171Sdim dumpSymbolField(OS, "constType", isConstType(), Indent); 58343171Sdim dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent); 59343171Sdim dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent); 60343171Sdim dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent); 61343171Sdim dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent); 62343171Sdim dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent); 63343171Sdim dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent); 64343171Sdim dumpSymbolField(OS, "nested", isNested(), Indent); 65343171Sdim dumpSymbolField(OS, "packed", isPacked(), Indent); 66343171Sdim dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent); 67343171Sdim dumpSymbolField(OS, "scoped", isScoped(), Indent); 68343171Sdim dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent); 69343171Sdim dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent); 70343171Sdim dumpSymbolField(OS, "volatileType", isVolatileType(), Indent); 71343171Sdim} 72343171Sdim 73343171Sdimstd::string NativeTypeUDT::getName() const { 74343171Sdim if (UnmodifiedType) 75343171Sdim return UnmodifiedType->getName(); 76343171Sdim 77343171Sdim return Tag->getName(); 78343171Sdim} 79343171Sdim 80343171SdimSymIndexId NativeTypeUDT::getLexicalParentId() const { return 0; } 81343171Sdim 82343171SdimSymIndexId NativeTypeUDT::getUnmodifiedTypeId() const { 83343171Sdim if (UnmodifiedType) 84343171Sdim return UnmodifiedType->getSymIndexId(); 85343171Sdim 86343171Sdim return 0; 87343171Sdim} 88343171Sdim 89343171SdimSymIndexId NativeTypeUDT::getVirtualTableShapeId() const { 90343171Sdim if (UnmodifiedType) 91343171Sdim return UnmodifiedType->getVirtualTableShapeId(); 92343171Sdim 93343171Sdim if (Class) 94343171Sdim return Session.getSymbolCache().findSymbolByTypeIndex(Class->VTableShape); 95343171Sdim 96343171Sdim return 0; 97343171Sdim} 98343171Sdim 99343171Sdimuint64_t NativeTypeUDT::getLength() const { 100343171Sdim if (UnmodifiedType) 101343171Sdim return UnmodifiedType->getLength(); 102343171Sdim 103343171Sdim if (Class) 104343171Sdim return Class->getSize(); 105343171Sdim 106343171Sdim return Union->getSize(); 107343171Sdim} 108343171Sdim 109343171SdimPDB_UdtType NativeTypeUDT::getUdtKind() const { 110343171Sdim if (UnmodifiedType) 111343171Sdim return UnmodifiedType->getUdtKind(); 112343171Sdim 113343171Sdim switch (Tag->Kind) { 114343171Sdim case TypeRecordKind::Class: 115343171Sdim return PDB_UdtType::Class; 116343171Sdim case TypeRecordKind::Union: 117343171Sdim return PDB_UdtType::Union; 118343171Sdim case TypeRecordKind::Struct: 119343171Sdim return PDB_UdtType::Struct; 120343171Sdim case TypeRecordKind::Interface: 121343171Sdim return PDB_UdtType::Interface; 122343171Sdim default: 123343171Sdim llvm_unreachable("Unexected udt kind"); 124343171Sdim } 125343171Sdim} 126343171Sdim 127343171Sdimbool NativeTypeUDT::hasConstructor() const { 128343171Sdim if (UnmodifiedType) 129343171Sdim return UnmodifiedType->hasConstructor(); 130343171Sdim 131343171Sdim return (Tag->Options & ClassOptions::HasConstructorOrDestructor) != 132343171Sdim ClassOptions::None; 133343171Sdim} 134343171Sdim 135343171Sdimbool NativeTypeUDT::isConstType() const { 136343171Sdim if (!Modifiers) 137343171Sdim return false; 138343171Sdim return (Modifiers->Modifiers & ModifierOptions::Const) != 139343171Sdim ModifierOptions::None; 140343171Sdim} 141343171Sdim 142343171Sdimbool NativeTypeUDT::hasAssignmentOperator() const { 143343171Sdim if (UnmodifiedType) 144343171Sdim return UnmodifiedType->hasAssignmentOperator(); 145343171Sdim 146343171Sdim return (Tag->Options & ClassOptions::HasOverloadedAssignmentOperator) != 147343171Sdim ClassOptions::None; 148343171Sdim} 149343171Sdim 150343171Sdimbool NativeTypeUDT::hasCastOperator() const { 151343171Sdim if (UnmodifiedType) 152343171Sdim return UnmodifiedType->hasCastOperator(); 153343171Sdim 154343171Sdim return (Tag->Options & ClassOptions::HasConversionOperator) != 155343171Sdim ClassOptions::None; 156343171Sdim} 157343171Sdim 158343171Sdimbool NativeTypeUDT::hasNestedTypes() const { 159343171Sdim if (UnmodifiedType) 160343171Sdim return UnmodifiedType->hasNestedTypes(); 161343171Sdim 162343171Sdim return (Tag->Options & ClassOptions::ContainsNestedClass) != 163343171Sdim ClassOptions::None; 164343171Sdim} 165343171Sdim 166343171Sdimbool NativeTypeUDT::hasOverloadedOperator() const { 167343171Sdim if (UnmodifiedType) 168343171Sdim return UnmodifiedType->hasOverloadedOperator(); 169343171Sdim 170343171Sdim return (Tag->Options & ClassOptions::HasOverloadedOperator) != 171343171Sdim ClassOptions::None; 172343171Sdim} 173343171Sdim 174343171Sdimbool NativeTypeUDT::isInterfaceUdt() const { return false; } 175343171Sdim 176343171Sdimbool NativeTypeUDT::isIntrinsic() const { 177343171Sdim if (UnmodifiedType) 178343171Sdim return UnmodifiedType->isIntrinsic(); 179343171Sdim 180343171Sdim return (Tag->Options & ClassOptions::Intrinsic) != ClassOptions::None; 181343171Sdim} 182343171Sdim 183343171Sdimbool NativeTypeUDT::isNested() const { 184343171Sdim if (UnmodifiedType) 185343171Sdim return UnmodifiedType->isNested(); 186343171Sdim 187343171Sdim return (Tag->Options & ClassOptions::Nested) != ClassOptions::None; 188343171Sdim} 189343171Sdim 190343171Sdimbool NativeTypeUDT::isPacked() const { 191343171Sdim if (UnmodifiedType) 192343171Sdim return UnmodifiedType->isPacked(); 193343171Sdim 194343171Sdim return (Tag->Options & ClassOptions::Packed) != ClassOptions::None; 195343171Sdim} 196343171Sdim 197343171Sdimbool NativeTypeUDT::isRefUdt() const { return false; } 198343171Sdim 199343171Sdimbool NativeTypeUDT::isScoped() const { 200343171Sdim if (UnmodifiedType) 201343171Sdim return UnmodifiedType->isScoped(); 202343171Sdim 203343171Sdim return (Tag->Options & ClassOptions::Scoped) != ClassOptions::None; 204343171Sdim} 205343171Sdim 206343171Sdimbool NativeTypeUDT::isValueUdt() const { return false; } 207343171Sdim 208343171Sdimbool NativeTypeUDT::isUnalignedType() const { 209343171Sdim if (!Modifiers) 210343171Sdim return false; 211343171Sdim return (Modifiers->Modifiers & ModifierOptions::Unaligned) != 212343171Sdim ModifierOptions::None; 213343171Sdim} 214343171Sdim 215343171Sdimbool NativeTypeUDT::isVolatileType() const { 216343171Sdim if (!Modifiers) 217343171Sdim return false; 218343171Sdim return (Modifiers->Modifiers & ModifierOptions::Volatile) != 219343171Sdim ModifierOptions::None; 220343171Sdim} 221