Thanks to visit codestin.com
Credit goes to llvm.org

LLVM 22.0.0git
NativeTypeEnum.cpp
Go to the documentation of this file.
1//===- NativeTypeEnum.cpp - info about enum 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
10
21
22#include <cassert>
23#include <optional>
24
25using namespace llvm;
26using namespace llvm::codeview;
27using namespace llvm::pdb;
28
29namespace {
30// Yea, this is a pretty terrible class name. But if we have an enum:
31//
32// enum Foo {
33// A,
34// B
35// };
36//
37// then A and B are the "enumerators" of the "enum" Foo. And we need
38// to enumerate them.
39class NativeEnumEnumEnumerators : public IPDBEnumSymbols, TypeVisitorCallbacks {
40public:
41 NativeEnumEnumEnumerators(NativeSession &Session,
42 const NativeTypeEnum &ClassParent);
43
44 uint32_t getChildCount() const override;
45 std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
46 std::unique_ptr<PDBSymbol> getNext() override;
47 void reset() override;
48
49private:
50 Error visitKnownMember(CVMemberRecord &CVM,
51 EnumeratorRecord &Record) override;
52 Error visitKnownMember(CVMemberRecord &CVM,
53 ListContinuationRecord &Record) override;
54
55 NativeSession &Session;
56 const NativeTypeEnum &ClassParent;
57 std::vector<EnumeratorRecord> Enumerators;
58 std::optional<TypeIndex> ContinuationIndex;
59 uint32_t Index = 0;
60};
61} // namespace
62
63NativeEnumEnumEnumerators::NativeEnumEnumEnumerators(
65 : Session(Session), ClassParent(ClassParent) {
66 TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
68
69 ContinuationIndex = ClassParent.getEnumRecord().FieldList;
70 while (ContinuationIndex) {
71 CVType FieldListCVT = Types.getType(*ContinuationIndex);
72 assert(FieldListCVT.kind() == LF_FIELDLIST);
73 ContinuationIndex.reset();
76 FieldList));
78 }
79}
80
81Error NativeEnumEnumEnumerators::visitKnownMember(CVMemberRecord &CVM,
83 Enumerators.push_back(Record);
84 return Error::success();
85}
86
87Error NativeEnumEnumEnumerators::visitKnownMember(
88 CVMemberRecord &CVM, ListContinuationRecord &Record) {
89 ContinuationIndex = Record.ContinuationIndex;
90 return Error::success();
91}
92
93uint32_t NativeEnumEnumEnumerators::getChildCount() const {
94 return Enumerators.size();
95}
96
97std::unique_ptr<PDBSymbol>
98NativeEnumEnumEnumerators::getChildAtIndex(uint32_t Index) const {
99 if (Index >= getChildCount())
100 return nullptr;
101
102 SymIndexId Id = Session.getSymbolCache()
103 .getOrCreateFieldListMember<NativeSymbolEnumerator>(
104 ClassParent.getEnumRecord().FieldList, Index,
105 ClassParent, Enumerators[Index]);
106 return Session.getSymbolCache().getSymbolById(Id);
107}
108
109std::unique_ptr<PDBSymbol> NativeEnumEnumEnumerators::getNext() {
110 if (Index >= getChildCount())
111 return nullptr;
112
113 return getChildAtIndex(Index++);
114}
115
116void NativeEnumEnumEnumerators::reset() { Index = 0; }
117
122
128
130
132 PdbSymbolIdField ShowIdFields,
133 PdbSymbolIdField RecurseIdFields) const {
134 NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
135
136 dumpSymbolField(OS, "baseType", static_cast<uint32_t>(getBuiltinType()),
137 Indent);
138 dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
140 RecurseIdFields);
141 dumpSymbolField(OS, "name", getName(), Indent);
142 dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
143 PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
144 if (Modifiers)
145 dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
147 RecurseIdFields);
148 dumpSymbolField(OS, "length", getLength(), Indent);
149 dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
150 dumpSymbolField(OS, "constType", isConstType(), Indent);
151 dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
152 dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
153 dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
154 dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
155 dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
156 dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
157 dumpSymbolField(OS, "nested", isNested(), Indent);
158 dumpSymbolField(OS, "packed", isPacked(), Indent);
159 dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
160 dumpSymbolField(OS, "scoped", isScoped(), Indent);
161 dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
162 dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
163 dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
164}
165
166std::unique_ptr<IPDBEnumSymbols>
168 if (Type != PDB_SymType::Data)
169 return std::make_unique<NullEnumerator<PDBSymbol>>();
170
171 const NativeTypeEnum *ClassParent = nullptr;
172 if (!Modifiers)
173 ClassParent = this;
174 else
176 return std::make_unique<NativeEnumEnumEnumerators>(Session, *ClassParent);
177}
178
180
182 if (UnmodifiedType)
183 return UnmodifiedType->getBuiltinType();
184
185 Session.getSymbolCache().findSymbolByTypeIndex(Record->getUnderlyingType());
186
187 codeview::TypeIndex Underlying = Record->getUnderlyingType();
188
189 // This indicates a corrupt record.
190 if (!Underlying.isSimple() ||
191 Underlying.getSimpleMode() != SimpleTypeMode::Direct) {
193 }
194
195 switch (Underlying.getSimpleKind()) {
249 default:
251 }
252 llvm_unreachable("Unreachable");
253}
254
256 return UnmodifiedType ? UnmodifiedType->getSymIndexId() : 0;
257}
258
260 if (UnmodifiedType)
261 return UnmodifiedType->hasConstructor();
262
263 return bool(Record->getOptions() &
265}
266
268 if (UnmodifiedType)
269 return UnmodifiedType->hasAssignmentOperator();
270
271 return bool(Record->getOptions() &
273}
274
276 if (UnmodifiedType)
277 return UnmodifiedType->hasNestedTypes();
278
279 return bool(Record->getOptions() &
281}
282
284 if (UnmodifiedType)
285 return UnmodifiedType->isIntrinsic();
286
287 return bool(Record->getOptions() & codeview::ClassOptions::Intrinsic);
288}
289
291 if (UnmodifiedType)
292 return UnmodifiedType->hasCastOperator();
293
294 return bool(Record->getOptions() &
296}
297
299 if (UnmodifiedType)
300 return UnmodifiedType->getLength();
301
302 const auto Id = Session.getSymbolCache().findSymbolByTypeIndex(
303 Record->getUnderlyingType());
304 const auto UnderlyingType =
305 Session.getConcreteSymbolById<PDBSymbolTypeBuiltin>(Id);
306 return UnderlyingType ? UnderlyingType->getLength() : 0;
307}
308
309std::string NativeTypeEnum::getName() const {
310 if (UnmodifiedType)
311 return UnmodifiedType->getName();
312
313 return std::string(Record->getName());
314}
315
317 if (UnmodifiedType)
318 return UnmodifiedType->isNested();
319
320 return bool(Record->getOptions() & codeview::ClassOptions::Nested);
321}
322
324 if (UnmodifiedType)
325 return UnmodifiedType->hasOverloadedOperator();
326
327 return bool(Record->getOptions() &
329}
330
332 if (UnmodifiedType)
333 return UnmodifiedType->isPacked();
334
335 return bool(Record->getOptions() & codeview::ClassOptions::Packed);
336}
337
339 if (UnmodifiedType)
340 return UnmodifiedType->isScoped();
341
342 return bool(Record->getOptions() & codeview::ClassOptions::Scoped);
343}
344
346 if (UnmodifiedType)
347 return UnmodifiedType->getTypeId();
348
349 return Session.getSymbolCache().findSymbolByTypeIndex(
350 Record->getUnderlyingType());
351}
352
353bool NativeTypeEnum::isRefUdt() const { return false; }
354
355bool NativeTypeEnum::isValueUdt() const { return false; }
356
357bool NativeTypeEnum::isInterfaceUdt() const { return false; }
358
360 if (!Modifiers)
361 return false;
362 return ((Modifiers->getModifiers() & ModifierOptions::Const) !=
364}
365
367 if (!Modifiers)
368 return false;
369 return ((Modifiers->getModifiers() & ModifierOptions::Volatile) !=
371}
372
374 if (!Modifiers)
375 return false;
376 return ((Modifiers->getModifiers() & ModifierOptions::Unaligned) !=
378}
379
381 if (UnmodifiedType)
382 return UnmodifiedType->getUnderlyingBuiltinType();
383
384 return Session.getSymbolCache().getNativeSymbolById<NativeTypeBuiltin>(
385 getTypeId());
386}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Error visitKnownMember(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks)
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Provides amortized O(1) random access to a CodeView type stream.
static Error deserializeAs(CVType &CVT, T &Record)
A 32-bit type reference.
Definition TypeIndex.h:97
NativeRawSymbol(NativeSession &PDBSession, PDB_SymType Tag, SymIndexId SymbolId)
void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, PdbSymbolIdField RecurseIdFields) const override
SymbolCache & getSymbolCache()
codeview::TypeIndex Index
bool isVolatileType() const override
bool isScoped() const override
bool hasOverloadedOperator() const override
bool isIntrinsic() const override
bool isPacked() const override
std::string getName() const override
void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, PdbSymbolIdField RecurseIdFields) const override
bool hasAssignmentOperator() const override
bool isNested() const override
bool isValueUdt() const override
bool isUnalignedType() const override
bool isInterfaceUdt() const override
std::unique_ptr< IPDBEnumSymbols > findChildren(PDB_SymType Type) const override
bool hasCastOperator() const override
PDB_BuiltinType getBuiltinType() const override
bool hasConstructor() const override
SymIndexId getTypeId() const override
bool isConstType() const override
const NativeTypeBuiltin & getUnderlyingBuiltinType() const
bool hasNestedTypes() const override
PDB_SymType getSymTag() const override
SymIndexId getUnmodifiedTypeId() const override
std::optional< codeview::ModifierRecord > Modifiers
NativeTypeEnum * UnmodifiedType
uint64_t getLength() const override
std::optional< codeview::EnumRecord > Record
bool isRefUdt() const override
NativeTypeEnum(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI, codeview::EnumRecord Record)
Expected< TpiStream & > getPDBTpiStream()
Definition PDBFile.cpp:300
SymIndexId getOrCreateFieldListMember(codeview::TypeIndex FieldListTI, uint32_t Index, Args &&... ConstructorArgs)
LLVM_ABI std::unique_ptr< PDBSymbol > getSymbolById(SymIndexId SymbolId) const
codeview::LazyRandomTypeCollection & typeCollection()
Definition TpiStream.h:62
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CVRecord< TypeLeafKind > CVType
Definition CVRecord.h:64
LLVM_ABI Error visitMemberRecordStream(ArrayRef< uint8_t > FieldList, TypeVisitorCallbacks &Callbacks)
uint32_t SymIndexId
Definition PDBTypes.h:26
void dumpSymbolField(raw_ostream &OS, StringRef Name, T Value, int Indent)
Definition PDBExtras.h:51
PDB_BuiltinType
These values correspond to the Basictype enumeration, and are documented here: https://msdn....
Definition PDBTypes.h:335
PDB_SymType
These values correspond to the SymTagEnum enumeration, and are documented here: https://msdn....
Definition PDBTypes.h:243
IPDBEnumChildren< PDBSymbol > IPDBEnumSymbols
Definition PDBTypes.h:69
LLVM_ABI void dumpSymbolIdField(raw_ostream &OS, StringRef Name, SymIndexId Value, int Indent, const IPDBSession &Session, PdbSymbolIdField FieldId, PdbSymbolIdField ShowFlags, PdbSymbolIdField RecurseFlags)
This is an optimization pass for GlobalISel generic memory operations.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1847
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:851