Skip to content

Commit

Permalink
Enable llvm-pdbutil to list enumerations using native PDB reader
Browse files Browse the repository at this point in the history
This extends the native reader to enable llvm-pdbutil to list the enums in a
PDB and it includes a simple test. It does not yet list the values in the
enumerations, which requires an actual implementation of
NativeEnumSymbol::FindChildren.

To exercise this code, use a command like:

    llvm-pdbutil pretty -native -enums foo.pdb

Differential Revision: https://reviews.llvm.org/D35738

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310144 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
amccarth-google committed Aug 4, 2017
1 parent 09cd716 commit 2d30fac
Show file tree
Hide file tree
Showing 11 changed files with 354 additions and 19 deletions.
60 changes: 60 additions & 0 deletions include/llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//===- NativeEnumSymbol.h - 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.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMSYMBOL_H
#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMSYMBOL_H

#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"

namespace llvm {
namespace pdb {

class NativeEnumSymbol : public NativeRawSymbol,
public codeview::TypeVisitorCallbacks {
public:
NativeEnumSymbol(NativeSession &Session, SymIndexId Id,
const codeview::CVType &CV);
~NativeEnumSymbol() override;

std::unique_ptr<NativeRawSymbol> clone() const override;

std::unique_ptr<IPDBEnumSymbols>
findChildren(PDB_SymType Type) const override;

Error visitKnownRecord(codeview::CVType &CVR,
codeview::EnumRecord &Record) override;
Error visitKnownMember(codeview::CVMemberRecord &CVM,
codeview::EnumeratorRecord &Record) override;

PDB_SymType getSymTag() const override;
uint32_t getClassParentId() const override;
uint32_t getUnmodifiedTypeId() const override;
bool hasConstructor() const override;
bool hasAssignmentOperator() const override;
bool hasCastOperator() const override;
uint64_t getLength() const override;
std::string getName() const override;
bool isNested() const override;
bool hasOverloadedOperator() const override;
bool isPacked() const override;
bool isScoped() const override;
uint32_t getTypeId() const override;

protected:
codeview::CVType CV;
codeview::EnumRecord Record;
};

} // namespace pdb
} // namespace llvm

#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMSYMBOL_H
51 changes: 51 additions & 0 deletions include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//==- NativeEnumTypes.h - 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.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMTYPES_H
#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMTYPES_H

#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"

#include <vector>

namespace llvm {
namespace pdb {

class NativeSession;

class NativeEnumTypes : public IPDBEnumChildren<PDBSymbol> {
public:
NativeEnumTypes(NativeSession &Session,
codeview::LazyRandomTypeCollection &TypeCollection,
codeview::TypeLeafKind Kind);

uint32_t getChildCount() const override;
std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
std::unique_ptr<PDBSymbol> getNext() override;
void reset() override;
NativeEnumTypes *clone() const override;

private:
NativeEnumTypes(NativeSession &Session,
const std::vector<codeview::TypeIndex> &Matches,
codeview::TypeLeafKind Kind);

std::vector<codeview::TypeIndex> Matches;
uint32_t Index;
NativeSession &Session;
codeview::TypeLeafKind Kind;
};

} // namespace pdb
} // namespace llvm

#endif
6 changes: 6 additions & 0 deletions include/llvm/DebugInfo/PDB/Native/NativeSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ class NativeSession : public IPDBSession {
std::unique_ptr<PDBSymbolCompiland>
createCompilandSymbol(DbiModuleDescriptor MI);

std::unique_ptr<PDBSymbolTypeEnum>
createEnumSymbol(codeview::TypeIndex Index);

std::unique_ptr<IPDBEnumSymbols>
createTypeEnumerator(codeview::TypeLeafKind Kind);

SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI);

uint64_t getLoadAddress() const override;
Expand Down
4 changes: 2 additions & 2 deletions include/llvm/DebugInfo/PDB/PDBSymbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_PDB_IPDBSYMBOL_H
#define LLVM_DEBUGINFO_PDB_IPDBSYMBOL_H
#ifndef LLVM_DEBUGINFO_PDB_PDBSYMBOL_H
#define LLVM_DEBUGINFO_PDB_PDBSYMBOL_H

#include "ConcreteSymbolEnumerator.h"
#include "IPDBRawSymbol.h"
Expand Down
2 changes: 2 additions & 0 deletions lib/DebugInfo/PDB/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
108 changes: 108 additions & 0 deletions lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp
Original file line number Diff line number Diff line change
@@ -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());
}
59 changes: 59 additions & 0 deletions lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
}
Expand Down
Loading

0 comments on commit 2d30fac

Please sign in to comment.