1 //==- NativeEnumTypes.cpp - Native Type Enumerator impl ----------*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
11 
12 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
13 #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
14 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
15 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
16 #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
17 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
18 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
19 
20 using namespace llvm;
21 using namespace llvm::codeview;
22 using namespace llvm::pdb;
23 
NativeEnumTypes(NativeSession & PDBSession,LazyRandomTypeCollection & Types,std::vector<codeview::TypeLeafKind> Kinds)24 NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
25                                  LazyRandomTypeCollection &Types,
26                                  std::vector<codeview::TypeLeafKind> Kinds)
27     : Matches(), Index(0), Session(PDBSession) {
28   Optional<TypeIndex> TI = Types.getFirst();
29   while (TI) {
30     CVType CVT = Types.getType(*TI);
31     TypeLeafKind K = CVT.kind();
32     if (llvm::is_contained(Kinds, K)) {
33       // Don't add forward refs, we'll find those later while enumerating.
34       if (!isUdtForwardRef(CVT))
35         Matches.push_back(*TI);
36     } else if (K == TypeLeafKind::LF_MODIFIER) {
37       TypeIndex ModifiedTI = getModifiedType(CVT);
38       if (!ModifiedTI.isSimple()) {
39         CVType UnmodifiedCVT = Types.getType(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(Kinds, UnmodifiedCVT.kind()))
44           Matches.push_back(*TI);
45       }
46     }
47     TI = Types.getNext(*TI);
48   }
49 }
50 
NativeEnumTypes(NativeSession & PDBSession,std::vector<codeview::TypeIndex> Indices)51 NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
52                                  std::vector<codeview::TypeIndex> Indices)
53     : Matches(std::move(Indices)), Index(0), Session(PDBSession) {}
54 
getChildCount() const55 uint32_t NativeEnumTypes::getChildCount() const {
56   return static_cast<uint32_t>(Matches.size());
57 }
58 
getChildAtIndex(uint32_t N) const59 std::unique_ptr<PDBSymbol> NativeEnumTypes::getChildAtIndex(uint32_t N) const {
60   if (N < Matches.size()) {
61     SymIndexId Id = Session.getSymbolCache().findSymbolByTypeIndex(Matches[N]);
62     return Session.getSymbolCache().getSymbolById(Id);
63   }
64   return nullptr;
65 }
66 
getNext()67 std::unique_ptr<PDBSymbol> NativeEnumTypes::getNext() {
68   return getChildAtIndex(Index++);
69 }
70 
reset()71 void NativeEnumTypes::reset() { Index = 0; }
72