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