summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/PDB
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/PDB')
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp108
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp59
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp41
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; }
OpenPOWER on IntegriCloud