diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/CMakeLists.txt | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp | 108 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp | 59 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp | 41 |
5 files changed, 211 insertions, 3 deletions
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index 2658584639c..37eca01f81c 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -44,6 +44,8 @@ add_pdb_impl_folder(Native Native/NativeBuiltinSymbol.cpp Native/NativeCompilandSymbol.cpp Native/NativeEnumModules.cpp + Native/NativeEnumSymbol.cpp + Native/NativeEnumTypes.cpp Native/NativeExeSymbol.cpp Native/NativeRawSymbol.cpp Native/NamedStreamMap.cpp diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp new file mode 100644 index 00000000000..38d65917306 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp @@ -0,0 +1,108 @@ +//===- NativeEnumSymbol.cpp - info about enum type --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h" + +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" + +#include <cassert> + +using namespace llvm; +using namespace llvm::pdb; + +NativeEnumSymbol::NativeEnumSymbol(NativeSession &Session, SymIndexId Id, + const codeview::CVType &CVT) + : NativeRawSymbol(Session, Id), CV(CVT), + Record(codeview::TypeRecordKind::Enum) { + assert(CV.kind() == codeview::TypeLeafKind::LF_ENUM); + cantFail(visitTypeRecord(CV, *this)); +} + +NativeEnumSymbol::~NativeEnumSymbol() {} + +std::unique_ptr<NativeRawSymbol> NativeEnumSymbol::clone() const { + return llvm::make_unique<NativeEnumSymbol>(Session, SymbolId, CV); +} + +std::unique_ptr<IPDBEnumSymbols> +NativeEnumSymbol::findChildren(PDB_SymType Type) const { + switch (Type) { + case PDB_SymType::Data: { + // TODO(amccarth): Provide an actual implementation. + return nullptr; + } + default: + return nullptr; + } +} + +Error NativeEnumSymbol::visitKnownRecord(codeview::CVType &CVR, + codeview::EnumRecord &ER) { + Record = ER; + return Error::success(); +} + +Error NativeEnumSymbol::visitKnownMember(codeview::CVMemberRecord &CVM, + codeview::EnumeratorRecord &R) { + return Error::success(); +} + +PDB_SymType NativeEnumSymbol::getSymTag() const { return PDB_SymType::Enum; } + +uint32_t NativeEnumSymbol::getClassParentId() const { return 0xFFFFFFFF; } + +uint32_t NativeEnumSymbol::getUnmodifiedTypeId() const { return 0; } + +bool NativeEnumSymbol::hasConstructor() const { + return bool(Record.getOptions() & + codeview::ClassOptions::HasConstructorOrDestructor); +} + +bool NativeEnumSymbol::hasAssignmentOperator() const { + return bool(Record.getOptions() & + codeview::ClassOptions::HasOverloadedAssignmentOperator); +} + +bool NativeEnumSymbol::hasCastOperator() const { + return bool(Record.getOptions() & + codeview::ClassOptions::HasConversionOperator); +} + +uint64_t NativeEnumSymbol::getLength() const { + const auto Id = Session.findSymbolByTypeIndex(Record.getUnderlyingType()); + const auto UnderlyingType = + Session.getConcreteSymbolById<PDBSymbolTypeBuiltin>(Id); + return UnderlyingType ? UnderlyingType->getLength() : 0; +} + +std::string NativeEnumSymbol::getName() const { return Record.getName(); } + +bool NativeEnumSymbol::isNested() const { + return bool(Record.getOptions() & codeview::ClassOptions::Nested); +} + +bool NativeEnumSymbol::hasOverloadedOperator() const { + return bool(Record.getOptions() & + codeview::ClassOptions::HasOverloadedOperator); +} + +bool NativeEnumSymbol::isPacked() const { + return bool(Record.getOptions() & codeview::ClassOptions::Packed); +} + +bool NativeEnumSymbol::isScoped() const { + return bool(Record.getOptions() & codeview::ClassOptions::Scoped); +} + +uint32_t NativeEnumSymbol::getTypeId() const { + return Session.findSymbolByTypeIndex(Record.getUnderlyingType()); +} diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp new file mode 100644 index 00000000000..36a68a1c62d --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp @@ -0,0 +1,59 @@ +//==- NativeEnumTypes.cpp - Native Type Enumerator impl ----------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" + +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" +#include "llvm/DebugInfo/PDB/PDBSymbol.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" + +namespace llvm { +namespace pdb { + +NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession, + codeview::LazyRandomTypeCollection &Types, + codeview::TypeLeafKind Kind) + : Matches(), Index(0), Session(PDBSession), Kind(Kind) { + for (auto Index = Types.getFirst(); Index; + Index = Types.getNext(Index.getValue())) { + if (Types.getType(Index.getValue()).kind() == Kind) + Matches.push_back(Index.getValue()); + } +} + +NativeEnumTypes::NativeEnumTypes( + NativeSession &PDBSession, const std::vector<codeview::TypeIndex> &Matches, + codeview::TypeLeafKind Kind) + : Matches(Matches), Index(0), Session(PDBSession), Kind(Kind) {} + +uint32_t NativeEnumTypes::getChildCount() const { + return static_cast<uint32_t>(Matches.size()); +} + +std::unique_ptr<PDBSymbol> +NativeEnumTypes::getChildAtIndex(uint32_t Index) const { + if (Index < Matches.size()) + return Session.createEnumSymbol(Matches[Index]); + return nullptr; +} + +std::unique_ptr<PDBSymbol> NativeEnumTypes::getNext() { + return getChildAtIndex(Index++); +} + +void NativeEnumTypes::reset() { Index = 0; } + +NativeEnumTypes *NativeEnumTypes::clone() const { + return new NativeEnumTypes(Session, Matches, Kind); +} + +} // namespace pdb +} // namespace llvm diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp index 3241000b06d..b29d589eaa9 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp @@ -13,7 +13,9 @@ #include "llvm/DebugInfo/PDB/Native/DbiStream.h" #include "llvm/DebugInfo/PDB/Native/InfoStream.h" #include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h" +#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" namespace llvm { namespace pdb { @@ -38,6 +40,8 @@ NativeExeSymbol::findChildren(PDB_SymType Type) const { consumeError(Dbi.takeError()); break; } + case PDB_SymType::Enum: + return Session.createTypeEnumerator(codeview::LF_ENUM); default: break; } diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp index 76de0d8f9e7..d7be2d576c2 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp @@ -16,11 +16,15 @@ #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" #include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h" #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/Error.h" @@ -28,6 +32,7 @@ #include "llvm/Support/MemoryBuffer.h" #include <algorithm> +#include <cassert> #include <memory> #include <utility> @@ -102,6 +107,25 @@ NativeSession::createCompilandSymbol(DbiModuleDescriptor MI) { *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone())); } +std::unique_ptr<PDBSymbolTypeEnum> +NativeSession::createEnumSymbol(codeview::TypeIndex Index) { + const auto Id = findSymbolByTypeIndex(Index); + return llvm::make_unique<PDBSymbolTypeEnum>( + *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone())); +} + +std::unique_ptr<IPDBEnumSymbols> +NativeSession::createTypeEnumerator(codeview::TypeLeafKind Kind) { + auto Tpi = Pdb->getPDBTpiStream(); + if (!Tpi) { + consumeError(Tpi.takeError()); + return nullptr; + } + auto &Types = Tpi->typeCollection(); + return std::unique_ptr<IPDBEnumSymbols>( + new NativeEnumTypes(*this, Types, codeview::LF_ENUM)); +} + SymIndexId NativeSession::findSymbolByTypeIndex(codeview::TypeIndex Index) { // First see if it's already in our cache. const auto Entry = TypeIndexToSymbolId.find(Index); @@ -129,9 +153,20 @@ SymIndexId NativeSession::findSymbolByTypeIndex(codeview::TypeIndex Index) { return Id; } - // TODO: Look up PDB type by type index - - return 0; + // We need to instantiate and cache the desired type symbol. + auto Tpi = Pdb->getPDBTpiStream(); + if (!Tpi) { + consumeError(Tpi.takeError()); + return 0; + } + auto &Types = Tpi->typeCollection(); + const auto &I = Types.getType(Index); + const auto Id = static_cast<SymIndexId>(SymbolCache.size()); + // TODO(amccarth): Make this handle all types, not just LF_ENUMs. + assert(I.kind() == codeview::LF_ENUM); + SymbolCache.emplace_back(llvm::make_unique<NativeEnumSymbol>(*this, Id, I)); + TypeIndexToSymbolId[Index] = Id; + return Id; } uint64_t NativeSession::getLoadAddress() const { return 0; } |