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 
NativeEnumTypes(NativeSession & PDBSession,LazyRandomTypeCollection & Types,std::vector<codeview::TypeLeafKind> Kinds)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(*TI);
32     TypeLeafKind K = CVT.kind();
33     if (llvm::is_contained(Kinds, K)) {
34       // Don't add forward refs, we'll find those later while enumerating.
35       if (!isUdtForwardRef(CVT))
36         Matches.push_back(*TI);
37     } else if (K == TypeLeafKind::LF_MODIFIER) {
38       TypeIndex ModifiedTI = getModifiedType(CVT);
39       if (!ModifiedTI.isSimple()) {
40         CVType UnmodifiedCVT = Types.getType(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(Kinds, UnmodifiedCVT.kind()))
45           Matches.push_back(*TI);
46       }
47     }
48     TI = Types.getNext(*TI);
49   }
50 }
51 
NativeEnumTypes(NativeSession & PDBSession,std::vector<codeview::TypeIndex> Indices)52 NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
53                                  std::vector<codeview::TypeIndex> Indices)
54     : Matches(std::move(Indices)), Index(0), Session(PDBSession) {}
55 
getChildCount() const56 uint32_t NativeEnumTypes::getChildCount() const {
57   return static_cast<uint32_t>(Matches.size());
58 }
59 
getChildAtIndex(uint32_t N) const60 std::unique_ptr<PDBSymbol> NativeEnumTypes::getChildAtIndex(uint32_t N) const {
61   if (N < Matches.size()) {
62     SymIndexId Id = Session.getSymbolCache().findSymbolByTypeIndex(Matches[N]);
63     return Session.getSymbolCache().getSymbolById(Id);
64   }
65   return nullptr;
66 }
67 
getNext()68 std::unique_ptr<PDBSymbol> NativeEnumTypes::getNext() {
69   return getChildAtIndex(Index++);
70 }
71 
reset()72 void NativeEnumTypes::reset() { Index = 0; }
73