1 | //==- NativeEnumTypes.cpp - Native Type Enumerator impl ----------*- 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/NativeEnumTypes.h" |
10 | |
11 | #include "llvm/ADT/STLExtras.h" |
12 | #include "llvm/DebugInfo/CodeView/CVRecord.h" |
13 | #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" |
14 | #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h" |
15 | #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" |
16 | #include "llvm/DebugInfo/PDB/Native/NativeSession.h" |
17 | #include "llvm/DebugInfo/PDB/Native/SymbolCache.h" |
18 | #include "llvm/DebugInfo/PDB/PDBSymbol.h" |
19 | #include "llvm/DebugInfo/PDB/PDBTypes.h" |
20 | |
21 | using namespace llvm; |
22 | using namespace llvm::codeview; |
23 | using namespace llvm::pdb; |
24 | |
25 | NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession, |
26 | LazyRandomTypeCollection &Types, |
27 | std::vector<codeview::TypeLeafKind> Kinds) |
28 | : Index(0), Session(PDBSession) { |
29 | std::optional<TypeIndex> TI = Types.getFirst(); |
30 | while (TI) { |
31 | CVType CVT = Types.getType(Index: *TI); |
32 | TypeLeafKind K = CVT.kind(); |
33 | if (llvm::is_contained(Range&: Kinds, Element: K)) { |
34 | // Don't add forward refs, we'll find those later while enumerating. |
35 | if (!isUdtForwardRef(CVT)) |
36 | Matches.push_back(x: *TI); |
37 | } else if (K == TypeLeafKind::LF_MODIFIER) { |
38 | TypeIndex ModifiedTI = getModifiedType(CVT); |
39 | if (!ModifiedTI.isSimple()) { |
40 | CVType UnmodifiedCVT = Types.getType(Index: ModifiedTI); |
41 | // LF_MODIFIERs point to forward refs, but don't worry about that |
42 | // here. We're pushing the TypeIndex of the LF_MODIFIER itself, |
43 | // so we'll worry about resolving forward refs later. |
44 | if (llvm::is_contained(Range&: Kinds, Element: UnmodifiedCVT.kind())) |
45 | Matches.push_back(x: *TI); |
46 | } |
47 | } |
48 | TI = Types.getNext(Prev: *TI); |
49 | } |
50 | } |
51 | |
52 | NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession, |
53 | std::vector<codeview::TypeIndex> Indices) |
54 | : Matches(std::move(Indices)), Index(0), Session(PDBSession) {} |
55 | |
56 | uint32_t NativeEnumTypes::getChildCount() const { |
57 | return static_cast<uint32_t>(Matches.size()); |
58 | } |
59 | |
60 | std::unique_ptr<PDBSymbol> NativeEnumTypes::getChildAtIndex(uint32_t N) const { |
61 | if (N < Matches.size()) { |
62 | SymIndexId Id = Session.getSymbolCache().findSymbolByTypeIndex(TI: Matches[N]); |
63 | return Session.getSymbolCache().getSymbolById(SymbolId: Id); |
64 | } |
65 | return nullptr; |
66 | } |
67 | |
68 | std::unique_ptr<PDBSymbol> NativeEnumTypes::getNext() { |
69 | return getChildAtIndex(N: Index++); |
70 | } |
71 | |
72 | void NativeEnumTypes::reset() { Index = 0; } |
73 | |