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 21using namespace llvm; 22using namespace llvm::codeview; 23using namespace llvm::pdb; 24 25NativeEnumTypes::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 52NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession, 53 std::vector<codeview::TypeIndex> Indices) 54 : Matches(std::move(Indices)), Index(0), Session(PDBSession) {} 55 56uint32_t NativeEnumTypes::getChildCount() const { 57 return static_cast<uint32_t>(Matches.size()); 58} 59 60std::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 68std::unique_ptr<PDBSymbol> NativeEnumTypes::getNext() { 69 return getChildAtIndex(Index++); 70} 71 72void NativeEnumTypes::reset() { Index = 0; } 73