forked from OSchip/llvm-project
[PDB] Add support for parsing VFTable Shape records.
This allows them to be returned from the native API. llvm-svn: 343506
This commit is contained in:
parent
7159daa68e
commit
5c1873b213
|
@ -0,0 +1,46 @@
|
|||
//===- NativeTypeVTShape.h - info about virtual table shape ------*- 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_NATIVETYPEVTSHAPE_H
|
||||
#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEVTSHAPE_H
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace pdb {
|
||||
|
||||
class NativeTypeVTShape : public NativeRawSymbol {
|
||||
public:
|
||||
// Create a pointer record for a non-simple type.
|
||||
NativeTypeVTShape(NativeSession &Session, SymIndexId Id,
|
||||
codeview::TypeIndex TI, codeview::VFTableShapeRecord SR);
|
||||
|
||||
~NativeTypeVTShape() override;
|
||||
|
||||
void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
|
||||
PdbSymbolIdField RecurseIdFields) const override;
|
||||
|
||||
bool isConstType() const override;
|
||||
bool isVolatileType() const override;
|
||||
bool isUnalignedType() const override;
|
||||
uint32_t getCount() const override;
|
||||
|
||||
protected:
|
||||
codeview::TypeIndex TI;
|
||||
codeview::VFTableShapeRecord Record;
|
||||
};
|
||||
|
||||
} // namespace pdb
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
|
|
@ -58,6 +58,7 @@ add_pdb_impl_folder(Native
|
|||
Native/NativeTypeFunctionSig.cpp
|
||||
Native/NativeTypePointer.cpp
|
||||
Native/NativeTypeUDT.cpp
|
||||
Native/NativeTypeVTShape.cpp
|
||||
Native/NamedStreamMap.cpp
|
||||
Native/NativeSession.cpp
|
||||
Native/PDBFile.cpp
|
||||
|
|
|
@ -51,6 +51,8 @@ NativeExeSymbol::findChildren(PDB_SymType Type) const {
|
|||
return Session.getSymbolCache().createTypeEnumerator(
|
||||
{codeview::LF_STRUCTURE, codeview::LF_CLASS, codeview::LF_UNION,
|
||||
codeview::LF_INTERFACE});
|
||||
case PDB_SymType::VTableShape:
|
||||
return Session.getSymbolCache().createTypeEnumerator(codeview::LF_VTSHAPE);
|
||||
case PDB_SymType::FunctionSig:
|
||||
return Session.getSymbolCache().createTypeEnumerator(
|
||||
{codeview::LF_PROCEDURE, codeview::LF_MFUNCTION});
|
||||
|
|
|
@ -162,7 +162,8 @@ SymIndexId NativeTypeFunctionSig::getTypeId() const {
|
|||
TypeIndex ReturnTI =
|
||||
IsMemberFunction ? MemberFunc.getReturnType() : Proc.getReturnType();
|
||||
|
||||
return Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI);
|
||||
SymIndexId Result = Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI);
|
||||
return Result;
|
||||
}
|
||||
|
||||
int32_t NativeTypeFunctionSig::getThisAdjust() const {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::pdb;
|
||||
|
||||
// Create a pointer record for a non-simple type.
|
||||
NativeTypeVTShape::NativeTypeVTShape(NativeSession &Session, SymIndexId Id,
|
||||
codeview::TypeIndex TI,
|
||||
codeview::VFTableShapeRecord SR)
|
||||
: NativeRawSymbol(Session, PDB_SymType::VTableShape, Id), TI(TI),
|
||||
Record(std::move(SR)) {}
|
||||
|
||||
NativeTypeVTShape::~NativeTypeVTShape() {}
|
||||
|
||||
void NativeTypeVTShape::dump(raw_ostream &OS, int Indent,
|
||||
PdbSymbolIdField ShowIdFields,
|
||||
PdbSymbolIdField RecurseIdFields) const {
|
||||
NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
|
||||
|
||||
dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
|
||||
PdbSymbolIdField::LexicalParent, ShowIdFields,
|
||||
RecurseIdFields);
|
||||
dumpSymbolField(OS, "count", getCount(), Indent);
|
||||
dumpSymbolField(OS, "constType", isConstType(), Indent);
|
||||
dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
|
||||
dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
|
||||
}
|
||||
|
||||
bool NativeTypeVTShape::isConstType() const { return false; }
|
||||
|
||||
bool NativeTypeVTShape::isVolatileType() const { return false; }
|
||||
|
||||
bool NativeTypeVTShape::isUnalignedType() const { return false; }
|
||||
|
||||
uint32_t NativeTypeVTShape::getCount() const { return Record.Slots.size(); }
|
|
@ -13,6 +13,7 @@
|
|||
#include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
|
||||
|
@ -32,6 +33,7 @@ static const struct BuiltinTypeEntry {
|
|||
} BuiltinTypes[] = {
|
||||
{codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0},
|
||||
{codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0},
|
||||
{codeview::SimpleTypeKind::HResult, PDB_BuiltinType::HResult, 4},
|
||||
{codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2},
|
||||
{codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
|
||||
{codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
|
||||
|
@ -41,9 +43,15 @@ static const struct BuiltinTypeEntry {
|
|||
{codeview::SimpleTypeKind::Int64Quad, PDB_BuiltinType::Int, 8},
|
||||
{codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
|
||||
{codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
|
||||
{codeview::SimpleTypeKind::WideCharacter, PDB_BuiltinType::WCharT, 2},
|
||||
{codeview::SimpleTypeKind::Character16, PDB_BuiltinType::Char16, 2},
|
||||
{codeview::SimpleTypeKind::Character32, PDB_BuiltinType::Char32, 4},
|
||||
{codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
|
||||
{codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
|
||||
{codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1}
|
||||
{codeview::SimpleTypeKind::Float32, PDB_BuiltinType::Float, 4},
|
||||
{codeview::SimpleTypeKind::Float64, PDB_BuiltinType::Float, 8},
|
||||
{codeview::SimpleTypeKind::Float80, PDB_BuiltinType::Float, 10},
|
||||
{codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1},
|
||||
// This table can be grown as necessary, but these are the only types we've
|
||||
// needed so far.
|
||||
};
|
||||
|
@ -196,6 +204,10 @@ SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) {
|
|||
Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>(
|
||||
Index, std::move(CVT));
|
||||
break;
|
||||
case codeview::LF_VTSHAPE:
|
||||
Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>(
|
||||
Index, std::move(CVT));
|
||||
break;
|
||||
default:
|
||||
Id = createSymbolPlaceholder();
|
||||
break;
|
||||
|
|
|
@ -53,7 +53,10 @@ FunctionDumper::FunctionDumper(LinePrinter &P)
|
|||
void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol,
|
||||
const char *Name, PointerType Pointer) {
|
||||
auto ReturnType = Symbol.getReturnType();
|
||||
ReturnType->dump(*this);
|
||||
if (!ReturnType)
|
||||
Printer << "<unknown-type>";
|
||||
else
|
||||
ReturnType->dump(*this);
|
||||
Printer << " ";
|
||||
uint32_t ClassParentId = Symbol.getClassParentId();
|
||||
auto ClassParent =
|
||||
|
@ -225,9 +228,10 @@ void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) {
|
|||
// through to the real thing and dump it.
|
||||
uint32_t TypeId = Symbol.getTypeId();
|
||||
auto Type = Symbol.getSession().getSymbolById(TypeId);
|
||||
if (!Type)
|
||||
return;
|
||||
Type->dump(*this);
|
||||
if (Type)
|
||||
Printer << "<unknown-type>";
|
||||
else
|
||||
Type->dump(*this);
|
||||
}
|
||||
|
||||
void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
|
||||
|
|
|
@ -208,6 +208,10 @@ void TypeDumper::start(const PDBSymbolExe &Exe) {
|
|||
if (opts::pretty::Pointers)
|
||||
dumpSymbolCategory<PDBSymbolTypePointer>(Printer, Exe, *this, "Pointers");
|
||||
|
||||
if (opts::pretty::VTShapes)
|
||||
dumpSymbolCategory<PDBSymbolTypeVTableShape>(Printer, Exe, *this,
|
||||
"VFTable Shapes");
|
||||
|
||||
if (opts::pretty::Classes) {
|
||||
if (auto Classes = Exe.findAllChildren<PDBSymbolTypeUDT>()) {
|
||||
uint32_t All = Classes->getChildCount();
|
||||
|
@ -281,6 +285,10 @@ void TypeDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
|
|||
BD.start(Symbol);
|
||||
}
|
||||
|
||||
void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol) {
|
||||
printClassDecl(Printer, Symbol);
|
||||
}
|
||||
|
||||
void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
|
||||
assert(opts::pretty::Typedefs);
|
||||
|
||||
|
@ -305,7 +313,7 @@ void TypeDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {
|
|||
void TypeDumper::dump(const PDBSymbolTypePointer &Symbol) {
|
||||
std::unique_ptr<PDBSymbol> P = Symbol.getPointeeType();
|
||||
|
||||
if (auto *FS = dyn_cast_or_null<PDBSymbolTypeFunctionSig>(P.get())) {
|
||||
if (auto *FS = dyn_cast<PDBSymbolTypeFunctionSig>(P.get())) {
|
||||
FunctionDumper Dumper(Printer);
|
||||
FunctionDumper::PointerType PT =
|
||||
Symbol.isReference() ? FunctionDumper::PointerType::Reference
|
||||
|
@ -314,7 +322,7 @@ void TypeDumper::dump(const PDBSymbolTypePointer &Symbol) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (auto *UDT = dyn_cast_or_null<PDBSymbolTypeUDT>(P.get())) {
|
||||
if (auto *UDT = dyn_cast<PDBSymbolTypeUDT>(P.get())) {
|
||||
printClassDecl(Printer, *UDT);
|
||||
} else if (P) {
|
||||
P->dump(*this);
|
||||
|
@ -334,6 +342,10 @@ void TypeDumper::dump(const PDBSymbolTypePointer &Symbol) {
|
|||
Printer << "*";
|
||||
}
|
||||
|
||||
void TypeDumper::dump(const PDBSymbolTypeVTableShape &Symbol) {
|
||||
Printer.format("<vtshape ({0} methods)>", Symbol.getCount());
|
||||
}
|
||||
|
||||
void TypeDumper::dumpClassLayout(const ClassLayout &Class) {
|
||||
assert(opts::pretty::Classes);
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@ public:
|
|||
void dump(const PDBSymbolTypeArray &Symbol) override;
|
||||
void dump(const PDBSymbolTypeBuiltin &Symbol) override;
|
||||
void dump(const PDBSymbolTypePointer &Symbol) override;
|
||||
void dump(const PDBSymbolTypeVTableShape &Symbol) override;
|
||||
void dump(const PDBSymbolTypeUDT &Symbol) override;
|
||||
|
||||
void dumpClassLayout(const ClassLayout &Class);
|
||||
|
||||
|
|
|
@ -195,6 +195,8 @@ static cl::opt<bool> Funcsigs("funcsigs",
|
|||
cl::sub(DiaDumpSubcommand));
|
||||
static cl::opt<bool> Arrays("arrays", cl::desc("Dump array types"),
|
||||
cl::sub(DiaDumpSubcommand));
|
||||
static cl::opt<bool> VTShapes("vtshapes", cl::desc("Dump virtual table shapes"),
|
||||
cl::sub(DiaDumpSubcommand));
|
||||
} // namespace diadump
|
||||
|
||||
namespace pretty {
|
||||
|
@ -249,6 +251,8 @@ cl::opt<bool> Pointers("pointers", cl::desc("Display pointer types"),
|
|||
cl::cat(TypeCategory), cl::sub(PrettySubcommand));
|
||||
cl::opt<bool> Arrays("arrays", cl::desc("Display arrays"),
|
||||
cl::cat(TypeCategory), cl::sub(PrettySubcommand));
|
||||
cl::opt<bool> VTShapes("vtshapes", cl::desc("Display vftable shapes"),
|
||||
cl::cat(TypeCategory), cl::sub(PrettySubcommand));
|
||||
|
||||
cl::opt<SymbolSortMode> SymbolOrder(
|
||||
"symbol-order", cl::desc("symbol sort order"),
|
||||
|
@ -1021,8 +1025,11 @@ static void dumpDia(StringRef Path) {
|
|||
SymTypes.push_back(PDB_SymType::FunctionSig);
|
||||
if (opts::diadump::Arrays)
|
||||
SymTypes.push_back(PDB_SymType::ArrayType);
|
||||
if (opts::diadump::VTShapes)
|
||||
SymTypes.push_back(PDB_SymType::VTableShape);
|
||||
PdbSymbolIdField Ids = opts::diadump::NoSymIndexIds ? PdbSymbolIdField::None
|
||||
: PdbSymbolIdField::All;
|
||||
|
||||
PdbSymbolIdField Recurse = PdbSymbolIdField::None;
|
||||
if (opts::diadump::Recurse)
|
||||
Recurse = PdbSymbolIdField::All;
|
||||
|
@ -1188,7 +1195,7 @@ static void dumpPretty(StringRef Path) {
|
|||
|
||||
if (opts::pretty::Classes || opts::pretty::Enums || opts::pretty::Typedefs ||
|
||||
opts::pretty::Funcsigs || opts::pretty::Pointers ||
|
||||
opts::pretty::Arrays) {
|
||||
opts::pretty::Arrays || opts::pretty::VTShapes) {
|
||||
Printer.NewLine();
|
||||
WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---";
|
||||
Printer.Indent();
|
||||
|
|
|
@ -86,6 +86,7 @@ extern llvm::cl::opt<bool> Funcsigs;
|
|||
extern llvm::cl::opt<bool> Arrays;
|
||||
extern llvm::cl::opt<bool> Typedefs;
|
||||
extern llvm::cl::opt<bool> Pointers;
|
||||
extern llvm::cl::opt<bool> VTShapes;
|
||||
extern llvm::cl::opt<bool> All;
|
||||
extern llvm::cl::opt<bool> ExcludeCompilerGenerated;
|
||||
|
||||
|
|
Loading…
Reference in New Issue