2015-02-07 02:47:14 +01:00
|
|
|
//===- llvm/unittest/DebugInfo/PDB/PDBApiTest.cpp -------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
2015-02-11 00:46:48 +01:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2015-02-07 02:47:14 +01:00
|
|
|
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
|
2018-03-13 18:58:28 +01:00
|
|
|
#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h"
|
2018-03-07 01:33:09 +01:00
|
|
|
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
|
2015-02-07 02:47:14 +01:00
|
|
|
#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
|
2018-03-22 05:08:15 +01:00
|
|
|
#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"
|
2015-02-08 21:58:09 +01:00
|
|
|
#include "llvm/DebugInfo/PDB/IPDBSession.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
|
2017-11-16 15:33:09 +01:00
|
|
|
#include "llvm/DebugInfo/PDB/IPDBTable.h"
|
2015-02-08 21:58:09 +01:00
|
|
|
|
2015-02-07 02:47:14 +01:00
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
|
|
|
|
#include "llvm/DebugInfo/PDB/PDBTypes.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace llvm;
|
2016-05-04 23:06:12 +02:00
|
|
|
using namespace llvm::pdb;
|
2015-02-07 02:47:14 +01:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
#define MOCK_SYMBOL_ACCESSOR(Func) \
|
2015-02-07 03:02:23 +01:00
|
|
|
decltype(std::declval<IPDBRawSymbol>().Func()) Func() const override { \
|
2015-02-07 02:47:14 +01:00
|
|
|
typedef decltype(IPDBRawSymbol::Func()) ReturnType; \
|
|
|
|
return ReturnType(); \
|
|
|
|
}
|
|
|
|
|
2015-02-08 21:58:09 +01:00
|
|
|
class MockSession : public IPDBSession {
|
|
|
|
uint64_t getLoadAddress() const override { return 0; }
|
2018-02-23 01:02:27 +01:00
|
|
|
bool setLoadAddress(uint64_t Address) override { return false; }
|
2017-06-22 20:42:23 +02:00
|
|
|
std::unique_ptr<PDBSymbolExe> getGlobalScope() override { return nullptr; }
|
2018-09-10 23:30:59 +02:00
|
|
|
std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const override {
|
2015-02-10 22:40:29 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBSourceFile>
|
|
|
|
getSourceFileById(uint32_t SymbolId) const override {
|
2015-02-08 21:58:09 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
2018-03-27 00:10:02 +02:00
|
|
|
bool addressForVA(uint64_t VA, uint32_t &Section,
|
|
|
|
uint32_t &Offset) const override {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
bool addressForRVA(uint32_t RVA, uint32_t &Section,
|
|
|
|
uint32_t &Offset) const override {
|
|
|
|
return false;
|
|
|
|
}
|
2015-04-18 00:40:36 +02:00
|
|
|
std::unique_ptr<PDBSymbol>
|
2015-05-01 22:51:49 +02:00
|
|
|
findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override {
|
2015-04-18 00:40:36 +02:00
|
|
|
return nullptr;
|
|
|
|
}
|
2018-04-10 20:12:49 +02:00
|
|
|
std::unique_ptr<PDBSymbol> findSymbolByRVA(uint32_t RVA,
|
|
|
|
PDB_SymType Type) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<PDBSymbol>
|
|
|
|
findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
|
|
|
|
PDB_SymType Type) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-04-18 00:40:36 +02:00
|
|
|
std::unique_ptr<IPDBEnumLineNumbers>
|
2016-02-18 19:47:29 +01:00
|
|
|
findLineNumbers(const PDBSymbolCompiland &Compiland,
|
|
|
|
const IPDBSourceFile &File) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumLineNumbers>
|
2015-04-18 00:40:36 +02:00
|
|
|
findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2018-03-15 07:04:51 +01:00
|
|
|
std::unique_ptr<IPDBEnumLineNumbers>
|
2018-03-27 00:13:22 +02:00
|
|
|
findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumLineNumbers>
|
2018-03-15 07:04:51 +01:00
|
|
|
findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
|
|
|
|
uint32_t Length) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-02-18 19:47:29 +01:00
|
|
|
std::unique_ptr<IPDBEnumSourceFiles>
|
|
|
|
findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern,
|
|
|
|
PDB_NameSearchFlags Flags) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBSourceFile>
|
|
|
|
findOneSourceFile(const PDBSymbolCompiland *Compiland,
|
|
|
|
llvm::StringRef Pattern,
|
|
|
|
PDB_NameSearchFlags Flags) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
|
|
|
|
findCompilandsForSourceFile(llvm::StringRef Pattern,
|
|
|
|
PDB_NameSearchFlags Flags) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<PDBSymbolCompiland>
|
|
|
|
findOneCompilandForSourceFile(llvm::StringRef Pattern,
|
|
|
|
PDB_NameSearchFlags Flags) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-04-18 00:40:36 +02:00
|
|
|
|
2015-02-10 23:43:25 +01:00
|
|
|
std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumSourceFiles> getSourceFilesForCompiland(
|
|
|
|
const PDBSymbolCompiland &Compiland) const override {
|
2015-02-08 21:58:09 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
2015-02-10 23:56:21 +01:00
|
|
|
|
|
|
|
std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2017-11-16 15:33:09 +01:00
|
|
|
|
|
|
|
std::unique_ptr<IPDBEnumTables> getEnumTables() const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2018-03-13 18:58:28 +01:00
|
|
|
|
|
|
|
std::unique_ptr<IPDBEnumInjectedSources> getInjectedSources() const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2018-03-22 05:08:15 +01:00
|
|
|
|
|
|
|
std::unique_ptr<IPDBEnumSectionContribs> getSectionContribs() const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2018-10-23 10:14:53 +02:00
|
|
|
|
|
|
|
std::unique_ptr<IPDBEnumFrameData> getFrameData() const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-02-08 21:58:09 +01:00
|
|
|
};
|
|
|
|
|
2015-02-07 02:47:14 +01:00
|
|
|
class MockRawSymbol : public IPDBRawSymbol {
|
|
|
|
public:
|
2015-02-11 01:33:00 +01:00
|
|
|
MockRawSymbol(PDB_SymType SymType)
|
|
|
|
: Type(SymType) {}
|
2015-02-07 02:47:14 +01:00
|
|
|
|
2018-09-18 18:58:17 +02:00
|
|
|
void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
|
|
|
|
PdbSymbolIdField RecurseIdFields) const override {}
|
2015-02-07 02:47:14 +01:00
|
|
|
|
2015-02-10 23:43:25 +01:00
|
|
|
std::unique_ptr<IPDBEnumSymbols>
|
|
|
|
findChildren(PDB_SymType Type) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-02-07 09:12:22 +01:00
|
|
|
std::unique_ptr<IPDBEnumSymbols>
|
2015-02-07 02:47:14 +01:00
|
|
|
findChildren(PDB_SymType Type, StringRef Name,
|
2015-02-07 09:12:22 +01:00
|
|
|
PDB_NameSearchFlags Flags) const override {
|
2015-02-07 02:47:14 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
2015-02-07 09:12:22 +01:00
|
|
|
std::unique_ptr<IPDBEnumSymbols>
|
2018-02-22 20:47:43 +01:00
|
|
|
findChildrenByAddr(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags,
|
2018-02-22 21:28:40 +01:00
|
|
|
uint32_t Section, uint32_t Offset) const override {
|
2018-02-22 20:47:43 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumSymbols>
|
|
|
|
findChildrenByVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags,
|
|
|
|
uint64_t VA) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumSymbols>
|
2015-02-07 02:47:14 +01:00
|
|
|
findChildrenByRVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags,
|
2015-02-07 09:12:22 +01:00
|
|
|
uint32_t RVA) const override {
|
2015-02-07 02:47:14 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
2015-02-07 09:12:22 +01:00
|
|
|
std::unique_ptr<IPDBEnumSymbols>
|
2018-02-22 20:47:43 +01:00
|
|
|
findInlineFramesByAddr(uint32_t Section, uint32_t Offset) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumSymbols>
|
2015-02-07 09:12:22 +01:00
|
|
|
findInlineFramesByRVA(uint32_t RVA) const override {
|
2015-02-07 02:47:14 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
2018-02-22 20:47:43 +01:00
|
|
|
std::unique_ptr<IPDBEnumSymbols>
|
|
|
|
findInlineFramesByVA(uint64_t VA) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumLineNumbers> findInlineeLines() const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumLineNumbers>
|
|
|
|
findInlineeLinesByAddr(uint32_t Section, uint32_t Offset,
|
|
|
|
uint32_t Length) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumLineNumbers>
|
|
|
|
findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
std::unique_ptr<IPDBEnumLineNumbers>
|
|
|
|
findInlineeLinesByVA(uint64_t VA, uint32_t Length) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-02-07 02:47:14 +01:00
|
|
|
|
2015-02-07 09:12:22 +01:00
|
|
|
void getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) const override {}
|
2015-02-08 01:29:29 +01:00
|
|
|
void getFrontEndVersion(VersionInfo &Version) const override {}
|
|
|
|
void getBackEndVersion(VersionInfo &Version) const override {}
|
2015-02-07 02:47:14 +01:00
|
|
|
|
|
|
|
PDB_SymType getSymTag() const override { return Type; }
|
|
|
|
|
2017-11-16 15:33:09 +01:00
|
|
|
std::string getUndecoratedNameEx(PDB_UndnameFlags Flags) const override {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2018-03-07 01:33:09 +01:00
|
|
|
std::unique_ptr<IPDBLineNumber> getSrcLineOnTypeDefn() const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2015-02-07 02:47:14 +01:00
|
|
|
MOCK_SYMBOL_ACCESSOR(getAccess)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getAddressOffset)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getAddressSection)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getAge)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getArrayIndexTypeId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getBaseDataOffset)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getBaseDataSlot)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getBaseSymbolId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getBuiltinType)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getBitPosition)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getCallingConvention)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getClassParentId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getCompilerName)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getCount)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getCountLiveRanges)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getLanguage)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getLexicalParentId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getLibraryName)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getLiveRangeStartAddressOffset)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getLiveRangeStartAddressSection)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getLiveRangeStartRelativeVirtualAddress)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getLocalBasePointerRegisterId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getLowerBoundId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getMemorySpaceKind)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getName)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getNumberOfAcceleratorPointerTags)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getNumberOfColumns)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getNumberOfModifiers)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getNumberOfRegisterIndices)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getNumberOfRows)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getObjectFileName)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getOemId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getOemSymbolId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getOffsetInUdt)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getPlatform)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getRank)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getRegisterId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getRegisterType)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getRelativeVirtualAddress)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getSamplerSlot)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getSignature)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getSizeInUdt)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getSlot)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getSourceFileName)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getStride)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getSubTypeId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getSymbolsFileName)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getSymIndexId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getTargetOffset)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getTargetRelativeVirtualAddress)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getTargetVirtualAddress)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getTargetSection)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getTextureSlot)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getTimeStamp)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getToken)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getTypeId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getUavSlot)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getUndecoratedName)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getUnmodifiedTypeId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getUpperBoundId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getVirtualBaseDispIndex)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getVirtualBaseOffset)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getVirtualTableShapeId)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getDataKind)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getGuid)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getOffset)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getThisAdjust)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getVirtualBasePointerOffset)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getLocationType)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getMachineType)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getThunkOrdinal)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getLength)
|
[llvm-pdbdump] More advanced class definition dumping.
Previously the dumping of class definitions was very primitive,
and it made it hard to do more than the most trivial of output
formats when dumping. As such, we would only dump one line for
each field, and then dump non-layout items like nested types
and enums.
With this patch, we do a complete analysis of the object
hierarchy including aggregate types, bases, virtual bases,
vftable analysis, etc. The only immediately visible effects
of this are that a) we can now dump a line for the vfptr where
before we would treat that as padding, and b) we now don't
treat virtual bases that come at the end of a class as padding
since we have a more detailed analysis of the class's storage
usage.
In subsequent patches, we should be able to use this analysis
to display a complete graphical view of a class's layout including
recursing arbitrarily deep into an object's base class / aggregate
member hierarchy.
llvm-svn: 300133
2017-04-13 01:18:21 +02:00
|
|
|
MOCK_SYMBOL_ACCESSOR(getVirtualBaseTableType)
|
2015-02-07 02:47:14 +01:00
|
|
|
MOCK_SYMBOL_ACCESSOR(getLiveRangeLength)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getVirtualAddress)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getUdtKind)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasConstructor)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasCustomCallingConvention)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasFarReturn)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isCode)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isCompilerGenerated)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isConstType)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isEditAndContinueEnabled)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isFunction)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getAddressTaken)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getNoStackOrdering)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasAlloca)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasAssignmentOperator)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasCTypes)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasCastOperator)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasDebugInfo)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasEH)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasEHa)
|
2015-02-10 23:43:25 +01:00
|
|
|
MOCK_SYMBOL_ACCESSOR(hasFramePointer)
|
2015-02-07 02:47:14 +01:00
|
|
|
MOCK_SYMBOL_ACCESSOR(hasInlAsm)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasInlineAttribute)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasInterruptReturn)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasLongJump)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasManagedCode)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasNestedTypes)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasNoInlineAttribute)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasNoReturnAttribute)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasOptimizedCodeDebugInfo)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasOverloadedOperator)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasSEH)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasSecurityChecks)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasSetJump)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasStrictGSCheck)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isAcceleratorGroupSharedLocal)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isAcceleratorPointerTagLiveRange)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isAcceleratorStubFunction)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isAggregated)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isIntroVirtualFunction)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isCVTCIL)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isConstructorVirtualBase)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isCxxReturnUdt)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isDataAligned)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isHLSLData)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isHotpatchable)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isIndirectVirtualBaseClass)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isInterfaceUdt)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isIntrinsic)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isLTCG)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isLocationControlFlowDependent)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isMSILNetmodule)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isMatrixRowMajor)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isManagedCode)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isMSILCode)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isMultipleInheritance)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isNaked)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isNested)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isOptimizedAway)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isPacked)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isPointerBasedOnSymbolValue)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isPointerToDataMember)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isPointerToMemberFunction)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isPureVirtual)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isRValueReference)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isRefUdt)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isReference)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isRestrictedType)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isReturnValue)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isSafeBuffers)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isScoped)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isSdl)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isSingleInheritance)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isSplitted)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isStatic)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(hasPrivateSymbols)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isUnalignedType)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isUnreached)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isValueUdt)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isVirtual)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isVirtualBaseClass)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isVirtualInheritance)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(isVolatileType)
|
2015-02-13 02:39:22 +01:00
|
|
|
MOCK_SYMBOL_ACCESSOR(getValue)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(wasInlined)
|
|
|
|
MOCK_SYMBOL_ACCESSOR(getUnused)
|
2015-02-07 02:47:14 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
PDB_SymType Type;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PDBApiTest : public testing::Test {
|
|
|
|
public:
|
|
|
|
std::unordered_map<PDB_SymType, std::unique_ptr<PDBSymbol>> SymbolMap;
|
|
|
|
|
|
|
|
void SetUp() override {
|
2015-02-08 21:58:09 +01:00
|
|
|
Session.reset(new MockSession());
|
|
|
|
|
2015-02-07 02:47:14 +01:00
|
|
|
InsertItemWithTag(PDB_SymType::None);
|
|
|
|
InsertItemWithTag(PDB_SymType::Exe);
|
|
|
|
InsertItemWithTag(PDB_SymType::Compiland);
|
|
|
|
InsertItemWithTag(PDB_SymType::CompilandDetails);
|
|
|
|
InsertItemWithTag(PDB_SymType::CompilandEnv);
|
|
|
|
InsertItemWithTag(PDB_SymType::Function);
|
|
|
|
InsertItemWithTag(PDB_SymType::Block);
|
|
|
|
InsertItemWithTag(PDB_SymType::Data);
|
|
|
|
InsertItemWithTag(PDB_SymType::Annotation);
|
|
|
|
InsertItemWithTag(PDB_SymType::Label);
|
|
|
|
InsertItemWithTag(PDB_SymType::PublicSymbol);
|
|
|
|
InsertItemWithTag(PDB_SymType::UDT);
|
|
|
|
InsertItemWithTag(PDB_SymType::Enum);
|
|
|
|
InsertItemWithTag(PDB_SymType::FunctionSig);
|
|
|
|
InsertItemWithTag(PDB_SymType::PointerType);
|
|
|
|
InsertItemWithTag(PDB_SymType::ArrayType);
|
|
|
|
InsertItemWithTag(PDB_SymType::BuiltinType);
|
|
|
|
InsertItemWithTag(PDB_SymType::Typedef);
|
|
|
|
InsertItemWithTag(PDB_SymType::BaseClass);
|
|
|
|
InsertItemWithTag(PDB_SymType::Friend);
|
|
|
|
InsertItemWithTag(PDB_SymType::FunctionArg);
|
|
|
|
InsertItemWithTag(PDB_SymType::FuncDebugStart);
|
|
|
|
InsertItemWithTag(PDB_SymType::FuncDebugEnd);
|
|
|
|
InsertItemWithTag(PDB_SymType::UsingNamespace);
|
|
|
|
InsertItemWithTag(PDB_SymType::VTableShape);
|
|
|
|
InsertItemWithTag(PDB_SymType::VTable);
|
|
|
|
InsertItemWithTag(PDB_SymType::Custom);
|
|
|
|
InsertItemWithTag(PDB_SymType::Thunk);
|
|
|
|
InsertItemWithTag(PDB_SymType::CustomType);
|
|
|
|
InsertItemWithTag(PDB_SymType::ManagedType);
|
|
|
|
InsertItemWithTag(PDB_SymType::Dimension);
|
|
|
|
InsertItemWithTag(PDB_SymType::Max);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class ExpectedType> void VerifyDyncast(PDB_SymType Tag) {
|
|
|
|
for (auto item = SymbolMap.begin(); item != SymbolMap.end(); ++item) {
|
|
|
|
EXPECT_EQ(item->first == Tag, llvm::isa<ExpectedType>(*item->second));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void VerifyUnknownDyncasts() {
|
|
|
|
for (auto item = SymbolMap.begin(); item != SymbolMap.end(); ++item) {
|
|
|
|
bool should_match = false;
|
|
|
|
if (item->first == PDB_SymType::None || item->first >= PDB_SymType::Max)
|
|
|
|
should_match = true;
|
|
|
|
|
|
|
|
EXPECT_EQ(should_match, llvm::isa<PDBSymbolUnknown>(*item->second));
|
|
|
|
}
|
|
|
|
}
|
2015-02-08 21:58:09 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
std::unique_ptr<IPDBSession> Session;
|
|
|
|
|
|
|
|
void InsertItemWithTag(PDB_SymType Tag) {
|
2015-02-11 01:33:00 +01:00
|
|
|
auto RawSymbol = llvm::make_unique<MockRawSymbol>(Tag);
|
2015-02-08 21:58:09 +01:00
|
|
|
auto Symbol = PDBSymbol::create(*Session, std::move(RawSymbol));
|
|
|
|
SymbolMap.insert(std::make_pair(Tag, std::move(Symbol)));
|
|
|
|
}
|
2015-02-07 02:47:14 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(PDBApiTest, Dyncast) {
|
|
|
|
|
|
|
|
// Most of the types have a one-to-one mapping between Tag and concrete type.
|
|
|
|
VerifyDyncast<PDBSymbolExe>(PDB_SymType::Exe);
|
|
|
|
VerifyDyncast<PDBSymbolCompiland>(PDB_SymType::Compiland);
|
|
|
|
VerifyDyncast<PDBSymbolCompilandDetails>(PDB_SymType::CompilandDetails);
|
|
|
|
VerifyDyncast<PDBSymbolCompilandEnv>(PDB_SymType::CompilandEnv);
|
|
|
|
VerifyDyncast<PDBSymbolFunc>(PDB_SymType::Function);
|
|
|
|
VerifyDyncast<PDBSymbolBlock>(PDB_SymType::Block);
|
|
|
|
VerifyDyncast<PDBSymbolData>(PDB_SymType::Data);
|
|
|
|
VerifyDyncast<PDBSymbolAnnotation>(PDB_SymType::Annotation);
|
|
|
|
VerifyDyncast<PDBSymbolLabel>(PDB_SymType::Label);
|
|
|
|
VerifyDyncast<PDBSymbolPublicSymbol>(PDB_SymType::PublicSymbol);
|
|
|
|
VerifyDyncast<PDBSymbolTypeUDT>(PDB_SymType::UDT);
|
|
|
|
VerifyDyncast<PDBSymbolTypeEnum>(PDB_SymType::Enum);
|
|
|
|
VerifyDyncast<PDBSymbolTypeFunctionSig>(PDB_SymType::FunctionSig);
|
|
|
|
VerifyDyncast<PDBSymbolTypePointer>(PDB_SymType::PointerType);
|
|
|
|
VerifyDyncast<PDBSymbolTypeArray>(PDB_SymType::ArrayType);
|
|
|
|
VerifyDyncast<PDBSymbolTypeBuiltin>(PDB_SymType::BuiltinType);
|
|
|
|
VerifyDyncast<PDBSymbolTypeTypedef>(PDB_SymType::Typedef);
|
|
|
|
VerifyDyncast<PDBSymbolTypeBaseClass>(PDB_SymType::BaseClass);
|
|
|
|
VerifyDyncast<PDBSymbolTypeFriend>(PDB_SymType::Friend);
|
|
|
|
VerifyDyncast<PDBSymbolTypeFunctionArg>(PDB_SymType::FunctionArg);
|
|
|
|
VerifyDyncast<PDBSymbolFuncDebugStart>(PDB_SymType::FuncDebugStart);
|
|
|
|
VerifyDyncast<PDBSymbolFuncDebugEnd>(PDB_SymType::FuncDebugEnd);
|
|
|
|
VerifyDyncast<PDBSymbolUsingNamespace>(PDB_SymType::UsingNamespace);
|
|
|
|
VerifyDyncast<PDBSymbolTypeVTableShape>(PDB_SymType::VTableShape);
|
|
|
|
VerifyDyncast<PDBSymbolTypeVTable>(PDB_SymType::VTable);
|
|
|
|
VerifyDyncast<PDBSymbolCustom>(PDB_SymType::Custom);
|
|
|
|
VerifyDyncast<PDBSymbolThunk>(PDB_SymType::Thunk);
|
|
|
|
VerifyDyncast<PDBSymbolTypeCustom>(PDB_SymType::CustomType);
|
|
|
|
VerifyDyncast<PDBSymbolTypeManaged>(PDB_SymType::ManagedType);
|
|
|
|
VerifyDyncast<PDBSymbolTypeDimension>(PDB_SymType::Dimension);
|
|
|
|
|
|
|
|
VerifyUnknownDyncasts();
|
|
|
|
}
|
|
|
|
} // end anonymous namespace
|