10b57cec5SDimitry Andric //==- NativeEnumTypes.cpp - Native Type Enumerator impl ----------*- C++ -*-==//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
100b57cec5SDimitry Andric 
1181ad6265SDimitry Andric #include "llvm/ADT/STLExtras.h"
1281ad6265SDimitry Andric #include "llvm/DebugInfo/CodeView/CVRecord.h"
1381ad6265SDimitry Andric #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
140b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
150b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
160b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
1781ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
180b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbol.h"
1981ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/PDBTypes.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric using namespace llvm;
220b57cec5SDimitry Andric using namespace llvm::codeview;
230b57cec5SDimitry Andric using namespace llvm::pdb;
240b57cec5SDimitry Andric 
NativeEnumTypes(NativeSession & PDBSession,LazyRandomTypeCollection & Types,std::vector<codeview::TypeLeafKind> Kinds)250b57cec5SDimitry Andric NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
260b57cec5SDimitry Andric                                  LazyRandomTypeCollection &Types,
270b57cec5SDimitry Andric                                  std::vector<codeview::TypeLeafKind> Kinds)
2804eeddc0SDimitry Andric     : Index(0), Session(PDBSession) {
29bdd1243dSDimitry Andric   std::optional<TypeIndex> TI = Types.getFirst();
300b57cec5SDimitry Andric   while (TI) {
310b57cec5SDimitry Andric     CVType CVT = Types.getType(*TI);
320b57cec5SDimitry Andric     TypeLeafKind K = CVT.kind();
330b57cec5SDimitry Andric     if (llvm::is_contained(Kinds, K)) {
340b57cec5SDimitry Andric       // Don't add forward refs, we'll find those later while enumerating.
350b57cec5SDimitry Andric       if (!isUdtForwardRef(CVT))
360b57cec5SDimitry Andric         Matches.push_back(*TI);
370b57cec5SDimitry Andric     } else if (K == TypeLeafKind::LF_MODIFIER) {
380b57cec5SDimitry Andric       TypeIndex ModifiedTI = getModifiedType(CVT);
390b57cec5SDimitry Andric       if (!ModifiedTI.isSimple()) {
400b57cec5SDimitry Andric         CVType UnmodifiedCVT = Types.getType(ModifiedTI);
410b57cec5SDimitry Andric         // LF_MODIFIERs point to forward refs, but don't worry about that
420b57cec5SDimitry Andric         // here.  We're pushing the TypeIndex of the LF_MODIFIER itself,
430b57cec5SDimitry Andric         // so we'll worry about resolving forward refs later.
440b57cec5SDimitry Andric         if (llvm::is_contained(Kinds, UnmodifiedCVT.kind()))
450b57cec5SDimitry Andric           Matches.push_back(*TI);
460b57cec5SDimitry Andric       }
470b57cec5SDimitry Andric     }
480b57cec5SDimitry Andric     TI = Types.getNext(*TI);
490b57cec5SDimitry Andric   }
500b57cec5SDimitry Andric }
510b57cec5SDimitry Andric 
NativeEnumTypes(NativeSession & PDBSession,std::vector<codeview::TypeIndex> Indices)520b57cec5SDimitry Andric NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
530b57cec5SDimitry Andric                                  std::vector<codeview::TypeIndex> Indices)
540b57cec5SDimitry Andric     : Matches(std::move(Indices)), Index(0), Session(PDBSession) {}
550b57cec5SDimitry Andric 
getChildCount() const560b57cec5SDimitry Andric uint32_t NativeEnumTypes::getChildCount() const {
570b57cec5SDimitry Andric   return static_cast<uint32_t>(Matches.size());
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric 
getChildAtIndex(uint32_t N) const600b57cec5SDimitry Andric std::unique_ptr<PDBSymbol> NativeEnumTypes::getChildAtIndex(uint32_t N) const {
610b57cec5SDimitry Andric   if (N < Matches.size()) {
620b57cec5SDimitry Andric     SymIndexId Id = Session.getSymbolCache().findSymbolByTypeIndex(Matches[N]);
630b57cec5SDimitry Andric     return Session.getSymbolCache().getSymbolById(Id);
640b57cec5SDimitry Andric   }
650b57cec5SDimitry Andric   return nullptr;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
getNext()680b57cec5SDimitry Andric std::unique_ptr<PDBSymbol> NativeEnumTypes::getNext() {
690b57cec5SDimitry Andric   return getChildAtIndex(Index++);
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric 
reset()720b57cec5SDimitry Andric void NativeEnumTypes::reset() { Index = 0; }
73