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
16using namespace llvm;
17using namespace llvm::codeview;
18using namespace llvm::pdb;
19
20NativeTypeUDT::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) {}
24
25NativeTypeUDT::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) {}
29
30NativeTypeUDT::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
36NativeTypeUDT::~NativeTypeUDT() = default;
37
38void 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: "name", Value: getName(), Indent);
45 dumpSymbolIdField(OS, Name: "lexicalParentId", Value: 0, Indent, Session,
46 FieldId: PdbSymbolIdField::LexicalParent, ShowFlags: ShowIdFields,
47 RecurseFlags: RecurseIdFields);
48 if (Modifiers)
49 dumpSymbolIdField(OS, Name: "unmodifiedTypeId", Value: getUnmodifiedTypeId(), Indent,
50 Session, FieldId: PdbSymbolIdField::UnmodifiedType, ShowFlags: ShowIdFields,
51 RecurseFlags: RecurseIdFields);
52 if (getUdtKind() != PDB_UdtType::Union)
53 dumpSymbolField(OS, Name: "virtualTableShapeId", Value: getVirtualTableShapeId(),
54 Indent);
55 dumpSymbolField(OS, Name: "length", Value: getLength(), Indent);
56 dumpSymbolField(OS, Name: "udtKind", Value: getUdtKind(), Indent);
57 dumpSymbolField(OS, Name: "constructor", Value: hasConstructor(), Indent);
58 dumpSymbolField(OS, Name: "constType", Value: isConstType(), Indent);
59 dumpSymbolField(OS, Name: "hasAssignmentOperator", Value: hasAssignmentOperator(), Indent);
60 dumpSymbolField(OS, Name: "hasCastOperator", Value: hasCastOperator(), Indent);
61 dumpSymbolField(OS, Name: "hasNestedTypes", Value: hasNestedTypes(), Indent);
62 dumpSymbolField(OS, Name: "overloadedOperator", Value: hasOverloadedOperator(), Indent);
63 dumpSymbolField(OS, Name: "isInterfaceUdt", Value: isInterfaceUdt(), Indent);
64 dumpSymbolField(OS, Name: "intrinsic", Value: isIntrinsic(), Indent);
65 dumpSymbolField(OS, Name: "nested", Value: isNested(), Indent);
66 dumpSymbolField(OS, Name: "packed", Value: isPacked(), Indent);
67 dumpSymbolField(OS, Name: "isRefUdt", Value: isRefUdt(), Indent);
68 dumpSymbolField(OS, Name: "scoped", Value: isScoped(), Indent);
69 dumpSymbolField(OS, Name: "unalignedType", Value: isUnalignedType(), Indent);
70 dumpSymbolField(OS, Name: "isValueUdt", Value: isValueUdt(), Indent);
71 dumpSymbolField(OS, Name: "volatileType", Value: isVolatileType(), Indent);
72}
73
74std::string NativeTypeUDT::getName() const {
75 if (UnmodifiedType)
76 return UnmodifiedType->getName();
77
78 return std::string(Tag->getName());
79}
80
81SymIndexId NativeTypeUDT::getLexicalParentId() const { return 0; }
82
83SymIndexId NativeTypeUDT::getUnmodifiedTypeId() const {
84 if (UnmodifiedType)
85 return UnmodifiedType->getSymIndexId();
86
87 return 0;
88}
89
90SymIndexId NativeTypeUDT::getVirtualTableShapeId() const {
91 if (UnmodifiedType)
92 return UnmodifiedType->getVirtualTableShapeId();
93
94 if (Class)
95 return Session.getSymbolCache().findSymbolByTypeIndex(TI: Class->VTableShape);
96
97 return 0;
98}
99
100uint64_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
110PDB_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
128bool NativeTypeUDT::hasConstructor() const {
129 if (UnmodifiedType)
130 return UnmodifiedType->hasConstructor();
131
132 return (Tag->Options & ClassOptions::HasConstructorOrDestructor) !=
133 ClassOptions::None;
134}
135
136bool NativeTypeUDT::isConstType() const {
137 if (!Modifiers)
138 return false;
139 return (Modifiers->Modifiers & ModifierOptions::Const) !=
140 ModifierOptions::None;
141}
142
143bool NativeTypeUDT::hasAssignmentOperator() const {
144 if (UnmodifiedType)
145 return UnmodifiedType->hasAssignmentOperator();
146
147 return (Tag->Options & ClassOptions::HasOverloadedAssignmentOperator) !=
148 ClassOptions::None;
149}
150
151bool NativeTypeUDT::hasCastOperator() const {
152 if (UnmodifiedType)
153 return UnmodifiedType->hasCastOperator();
154
155 return (Tag->Options & ClassOptions::HasConversionOperator) !=
156 ClassOptions::None;
157}
158
159bool NativeTypeUDT::hasNestedTypes() const {
160 if (UnmodifiedType)
161 return UnmodifiedType->hasNestedTypes();
162
163 return (Tag->Options & ClassOptions::ContainsNestedClass) !=
164 ClassOptions::None;
165}
166
167bool NativeTypeUDT::hasOverloadedOperator() const {
168 if (UnmodifiedType)
169 return UnmodifiedType->hasOverloadedOperator();
170
171 return (Tag->Options & ClassOptions::HasOverloadedOperator) !=
172 ClassOptions::None;
173}
174
175bool NativeTypeUDT::isInterfaceUdt() const { return false; }
176
177bool NativeTypeUDT::isIntrinsic() const {
178 if (UnmodifiedType)
179 return UnmodifiedType->isIntrinsic();
180
181 return (Tag->Options & ClassOptions::Intrinsic) != ClassOptions::None;
182}
183
184bool NativeTypeUDT::isNested() const {
185 if (UnmodifiedType)
186 return UnmodifiedType->isNested();
187
188 return (Tag->Options & ClassOptions::Nested) != ClassOptions::None;
189}
190
191bool NativeTypeUDT::isPacked() const {
192 if (UnmodifiedType)
193 return UnmodifiedType->isPacked();
194
195 return (Tag->Options & ClassOptions::Packed) != ClassOptions::None;
196}
197
198bool NativeTypeUDT::isRefUdt() const { return false; }
199
200bool NativeTypeUDT::isScoped() const {
201 if (UnmodifiedType)
202 return UnmodifiedType->isScoped();
203
204 return (Tag->Options & ClassOptions::Scoped) != ClassOptions::None;
205}
206
207bool NativeTypeUDT::isValueUdt() const { return false; }
208
209bool NativeTypeUDT::isUnalignedType() const {
210 if (!Modifiers)
211 return false;
212 return (Modifiers->Modifiers & ModifierOptions::Unaligned) !=
213 ModifierOptions::None;
214}
215
216bool NativeTypeUDT::isVolatileType() const {
217 if (!Modifiers)
218 return false;
219 return (Modifiers->Modifiers & ModifierOptions::Volatile) !=
220 ModifierOptions::None;
221}
222

source code of llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp