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