summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2018-09-07 23:21:33 +0000
committerZachary Turner <zturner@google.com>2018-09-07 23:21:33 +0000
commitda4b63ab9afede44bb063adf26d5e9e5f14818c2 (patch)
tree161b138a94040692344529a1273b55928b8e4975
parent28655081a476d8808e9e2c0900d4ca87fb17abe3 (diff)
downloadbcm5719-llvm-da4b63ab9afede44bb063adf26d5e9e5f14818c2.tar.gz
bcm5719-llvm-da4b63ab9afede44bb063adf26d5e9e5f14818c2.zip
[PDB] Support pointer types in the native reader.
In order to start testing this, I've added a new mode to llvm-pdbutil which is only really useful for writing tests. It just dumps the value of raw fields in record format. This isn't really ideal and it won't allow us to test some important cases, but it's better than nothing for now. llvm-svn: 341729
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h7
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h2
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h9
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h50
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h6
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp308
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp12
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp7
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp8
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp119
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp86
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp14
-rw-r--r--llvm/test/DebugInfo/PDB/Native/pdb-native-compilands.test19
-rw-r--r--llvm/test/DebugInfo/PDB/Native/pdb-native-enums.test219
-rw-r--r--llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp50
18 files changed, 725 insertions, 196 deletions
diff --git a/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h b/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
index bcb2eaa3563..5f667e1d926 100644
--- a/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
+++ b/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
@@ -24,6 +24,13 @@ namespace pdb {
class PDBSymbolTypeVTable;
class PDBSymbolTypeVTableShape;
+template <typename T>
+void dumpSymbolField(raw_ostream &OS, StringRef Name, T Value, int Indent) {
+ OS << "\n";
+ OS.indent(Indent);
+ OS << Name << ": " << Value;
+}
+
/// IPDBRawSymbol defines an interface used to represent an arbitrary symbol.
/// It exposes a monolithic interface consisting of accessors for the union of
/// all properties that are valid for any symbol type. This interface is then
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h
index bd5c09e5ff7..dd7278fc69a 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h
@@ -21,6 +21,8 @@ public:
NativeCompilandSymbol(NativeSession &Session, SymIndexId SymbolId,
DbiModuleDescriptor MI);
+ void dump(raw_ostream &OS, int Indent) const override;
+
std::unique_ptr<NativeRawSymbol> clone() const override;
PDB_SymType getSymTag() const override;
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h
index 185ec5022e8..f3869b898e9 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h
@@ -25,6 +25,8 @@ public:
const codeview::CVType &CV);
~NativeTypeEnum() override;
+ void dump(raw_ostream &OS, int Indent) const override;
+
std::unique_ptr<NativeRawSymbol> clone() const override;
std::unique_ptr<IPDBEnumSymbols>
@@ -35,8 +37,8 @@ public:
Error visitKnownMember(codeview::CVMemberRecord &CVM,
codeview::EnumeratorRecord &Record) override;
+ PDB_BuiltinType getBuiltinType() const override;
PDB_SymType getSymTag() const override;
- uint32_t getClassParentId() const override;
uint32_t getUnmodifiedTypeId() const override;
bool hasConstructor() const override;
bool hasAssignmentOperator() const override;
@@ -45,9 +47,14 @@ public:
std::string getName() const override;
bool isNested() const override;
bool hasOverloadedOperator() const override;
+ bool hasNestedTypes() const override;
+ bool isIntrinsic() const override;
bool isPacked() const override;
bool isScoped() const override;
uint32_t getTypeId() const override;
+ bool isRefUdt() const override;
+ bool isValueUdt() const override;
+ bool isInterfaceUdt() const override;
protected:
codeview::CVType CV;
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h
new file mode 100644
index 00000000000..0d454c06575
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h
@@ -0,0 +1,50 @@
+//===- NativeTypePointer.h - info about pointer 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_NATIVETYPEPOINTER_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_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 NativeTypePointer : public NativeRawSymbol {
+public:
+ NativeTypePointer(NativeSession &Session, SymIndexId Id, codeview::CVType CV);
+ NativeTypePointer(NativeSession &Session, SymIndexId Id,
+ codeview::PointerRecord PR);
+ ~NativeTypePointer() override;
+
+ void dump(raw_ostream &OS, int Indent) const override;
+ std::unique_ptr<NativeRawSymbol> clone() const override;
+
+ bool isConstType() const override;
+ uint64_t getLength() const override;
+ bool isReference() const override;
+ bool isRValueReference() const override;
+ bool isPointerToDataMember() const override;
+ bool isPointerToMemberFunction() const override;
+ uint32_t getTypeId() const override;
+ bool isRestrictedType() const override;
+ bool isVolatileType() const override;
+ bool isUnalignedType() const override;
+
+protected:
+ codeview::PointerRecord Record;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H \ No newline at end of file
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h b/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
index 8cbee8b19a0..993c594509d 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
@@ -32,6 +32,12 @@ class SymbolCache {
DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
std::vector<SymIndexId> Compilands;
+ SymIndexId createSymbolPlaceholder() {
+ SymIndexId Id = Cache.size();
+ Cache.push_back(nullptr);
+ return Id;
+ }
+
public:
SymbolCache(NativeSession &Session, DbiStream *Dbi);
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
index 1a7d14f3732..5e52515268e 100644
--- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
@@ -53,6 +53,7 @@ add_pdb_impl_folder(Native
Native/NativeRawSymbol.cpp
Native/NativeTypeBuiltin.cpp
Native/NativeTypeEnum.cpp
+ Native/NativeTypePointer.cpp
Native/NamedStreamMap.cpp
Native/NativeSession.cpp
Native/PDBFile.cpp
diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
index 4072a0b7614..25dd2090ce7 100644
--- a/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
@@ -146,11 +146,8 @@ void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
IDiaSymbol *Symbol,
HRESULT (__stdcall IDiaSymbol::*Method)(ArgType *)) {
ArgType Value;
- if (S_OK == (Symbol->*Method)(&Value)) {
- OS << "\n";
- OS.indent(Indent);
- OS << Name << ": " << Value;
- }
+ if (S_OK == (Symbol->*Method)(&Value))
+ dumpSymbolField(OS, Name, Value, Indent);
}
void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
@@ -162,11 +159,8 @@ void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
const char *Bytes = reinterpret_cast<const char *>(Value);
ArrayRef<char> ByteArray(Bytes, ::SysStringByteLen(Value));
std::string Result;
- if (llvm::convertUTF16ToUTF8String(ByteArray, Result)) {
- OS << "\n";
- OS.indent(Indent);
- OS << Name << ": " << Result;
- }
+ if (llvm::convertUTF16ToUTF8String(ByteArray, Result))
+ dumpSymbolField(OS, Name, Result, Indent);
::SysFreeString(Value);
}
@@ -177,10 +171,9 @@ void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
Value.vt = VT_EMPTY;
if (S_OK != (Symbol->*Method)(&Value))
return;
- OS << "\n";
- OS.indent(Indent);
Variant V = VariantFromVARIANT(Value);
- OS << Name << ": " << V;
+
+ dumpSymbolField(OS, Name, V, Indent);
}
}
@@ -198,179 +191,126 @@ DIARawSymbol::DIARawSymbol(const DIASession &PDBSession,
: Session(PDBSession), Symbol(DiaSymbol) {}
#define RAW_METHOD_DUMP(Stream, Method) \
- DumpDIAValue(Stream, Indent, StringRef(#Method), Symbol, &IDiaSymbol::Method);
+ DumpDIAValue(Stream, Indent, StringRef(#Method), Symbol, \
+ &IDiaSymbol::get_##Method);
void DIARawSymbol::dump(raw_ostream &OS, int Indent) const {
- RAW_METHOD_DUMP(OS, get_access)
- RAW_METHOD_DUMP(OS, get_addressOffset)
- RAW_METHOD_DUMP(OS, get_addressSection)
- RAW_METHOD_DUMP(OS, get_age)
- RAW_METHOD_DUMP(OS, get_arrayIndexTypeId)
- RAW_METHOD_DUMP(OS, get_backEndMajor)
- RAW_METHOD_DUMP(OS, get_backEndMinor)
- RAW_METHOD_DUMP(OS, get_backEndBuild)
- RAW_METHOD_DUMP(OS, get_backEndQFE)
- RAW_METHOD_DUMP(OS, get_baseDataOffset)
- RAW_METHOD_DUMP(OS, get_baseDataSlot)
- RAW_METHOD_DUMP(OS, get_baseSymbolId)
- RAW_METHOD_DUMP(OS, get_baseType)
- RAW_METHOD_DUMP(OS, get_bitPosition)
- RAW_METHOD_DUMP(OS, get_callingConvention)
- RAW_METHOD_DUMP(OS, get_classParentId)
- RAW_METHOD_DUMP(OS, get_compilerName)
- RAW_METHOD_DUMP(OS, get_count)
- RAW_METHOD_DUMP(OS, get_countLiveRanges)
- RAW_METHOD_DUMP(OS, get_frontEndMajor)
- RAW_METHOD_DUMP(OS, get_frontEndMinor)
- RAW_METHOD_DUMP(OS, get_frontEndBuild)
- RAW_METHOD_DUMP(OS, get_frontEndQFE)
- RAW_METHOD_DUMP(OS, get_lexicalParentId)
- RAW_METHOD_DUMP(OS, get_libraryName)
- RAW_METHOD_DUMP(OS, get_liveRangeStartAddressOffset)
- RAW_METHOD_DUMP(OS, get_liveRangeStartAddressSection)
- RAW_METHOD_DUMP(OS, get_liveRangeStartRelativeVirtualAddress)
- RAW_METHOD_DUMP(OS, get_localBasePointerRegisterId)
- RAW_METHOD_DUMP(OS, get_lowerBoundId)
- RAW_METHOD_DUMP(OS, get_memorySpaceKind)
- RAW_METHOD_DUMP(OS, get_name)
- RAW_METHOD_DUMP(OS, get_numberOfAcceleratorPointerTags)
- RAW_METHOD_DUMP(OS, get_numberOfColumns)
- RAW_METHOD_DUMP(OS, get_numberOfModifiers)
- RAW_METHOD_DUMP(OS, get_numberOfRegisterIndices)
- RAW_METHOD_DUMP(OS, get_numberOfRows)
- RAW_METHOD_DUMP(OS, get_objectFileName)
- RAW_METHOD_DUMP(OS, get_oemId)
- RAW_METHOD_DUMP(OS, get_oemSymbolId)
- RAW_METHOD_DUMP(OS, get_offsetInUdt)
- RAW_METHOD_DUMP(OS, get_platform)
- RAW_METHOD_DUMP(OS, get_rank)
- RAW_METHOD_DUMP(OS, get_registerId)
- RAW_METHOD_DUMP(OS, get_registerType)
- RAW_METHOD_DUMP(OS, get_relativeVirtualAddress)
- RAW_METHOD_DUMP(OS, get_samplerSlot)
- RAW_METHOD_DUMP(OS, get_signature)
- RAW_METHOD_DUMP(OS, get_sizeInUdt)
- RAW_METHOD_DUMP(OS, get_slot)
- RAW_METHOD_DUMP(OS, get_sourceFileName)
- RAW_METHOD_DUMP(OS, get_stride)
- RAW_METHOD_DUMP(OS, get_subTypeId)
- RAW_METHOD_DUMP(OS, get_symbolsFileName)
- RAW_METHOD_DUMP(OS, get_symIndexId)
- RAW_METHOD_DUMP(OS, get_targetOffset)
- RAW_METHOD_DUMP(OS, get_targetRelativeVirtualAddress)
- RAW_METHOD_DUMP(OS, get_targetVirtualAddress)
- RAW_METHOD_DUMP(OS, get_targetSection)
- RAW_METHOD_DUMP(OS, get_textureSlot)
- RAW_METHOD_DUMP(OS, get_timeStamp)
- RAW_METHOD_DUMP(OS, get_token)
- RAW_METHOD_DUMP(OS, get_typeId)
- RAW_METHOD_DUMP(OS, get_uavSlot)
- RAW_METHOD_DUMP(OS, get_undecoratedName)
- RAW_METHOD_DUMP(OS, get_unmodifiedTypeId)
- RAW_METHOD_DUMP(OS, get_upperBoundId)
- RAW_METHOD_DUMP(OS, get_virtualBaseDispIndex)
- RAW_METHOD_DUMP(OS, get_virtualBaseOffset)
- RAW_METHOD_DUMP(OS, get_virtualTableShapeId)
- RAW_METHOD_DUMP(OS, get_dataKind)
- RAW_METHOD_DUMP(OS, get_symTag)
- RAW_METHOD_DUMP(OS, get_guid)
- RAW_METHOD_DUMP(OS, get_offset)
- RAW_METHOD_DUMP(OS, get_thisAdjust)
- RAW_METHOD_DUMP(OS, get_virtualBasePointerOffset)
- RAW_METHOD_DUMP(OS, get_locationType)
- RAW_METHOD_DUMP(OS, get_machineType)
- RAW_METHOD_DUMP(OS, get_thunkOrdinal)
- RAW_METHOD_DUMP(OS, get_length)
- RAW_METHOD_DUMP(OS, get_liveRangeLength)
- RAW_METHOD_DUMP(OS, get_virtualAddress)
- RAW_METHOD_DUMP(OS, get_udtKind)
- RAW_METHOD_DUMP(OS, get_constructor)
- RAW_METHOD_DUMP(OS, get_customCallingConvention)
- RAW_METHOD_DUMP(OS, get_farReturn)
- RAW_METHOD_DUMP(OS, get_code)
- RAW_METHOD_DUMP(OS, get_compilerGenerated)
- RAW_METHOD_DUMP(OS, get_constType)
- RAW_METHOD_DUMP(OS, get_editAndContinueEnabled)
- RAW_METHOD_DUMP(OS, get_function)
- RAW_METHOD_DUMP(OS, get_stride)
- RAW_METHOD_DUMP(OS, get_noStackOrdering)
- RAW_METHOD_DUMP(OS, get_hasAlloca)
- RAW_METHOD_DUMP(OS, get_hasAssignmentOperator)
- RAW_METHOD_DUMP(OS, get_isCTypes)
- RAW_METHOD_DUMP(OS, get_hasCastOperator)
- RAW_METHOD_DUMP(OS, get_hasDebugInfo)
- RAW_METHOD_DUMP(OS, get_hasEH)
- RAW_METHOD_DUMP(OS, get_hasEHa)
- RAW_METHOD_DUMP(OS, get_hasInlAsm)
- RAW_METHOD_DUMP(OS, get_framePointerPresent)
- RAW_METHOD_DUMP(OS, get_inlSpec)
- RAW_METHOD_DUMP(OS, get_interruptReturn)
- RAW_METHOD_DUMP(OS, get_hasLongJump)
- RAW_METHOD_DUMP(OS, get_hasManagedCode)
- RAW_METHOD_DUMP(OS, get_hasNestedTypes)
- RAW_METHOD_DUMP(OS, get_noInline)
- RAW_METHOD_DUMP(OS, get_noReturn)
- RAW_METHOD_DUMP(OS, get_optimizedCodeDebugInfo)
- RAW_METHOD_DUMP(OS, get_overloadedOperator)
- RAW_METHOD_DUMP(OS, get_hasSEH)
- RAW_METHOD_DUMP(OS, get_hasSecurityChecks)
- RAW_METHOD_DUMP(OS, get_hasSetJump)
- RAW_METHOD_DUMP(OS, get_strictGSCheck)
- RAW_METHOD_DUMP(OS, get_isAcceleratorGroupSharedLocal)
- RAW_METHOD_DUMP(OS, get_isAcceleratorPointerTagLiveRange)
- RAW_METHOD_DUMP(OS, get_isAcceleratorStubFunction)
- RAW_METHOD_DUMP(OS, get_isAggregated)
- RAW_METHOD_DUMP(OS, get_intro)
- RAW_METHOD_DUMP(OS, get_isCVTCIL)
- RAW_METHOD_DUMP(OS, get_isConstructorVirtualBase)
- RAW_METHOD_DUMP(OS, get_isCxxReturnUdt)
- RAW_METHOD_DUMP(OS, get_isDataAligned)
- RAW_METHOD_DUMP(OS, get_isHLSLData)
- RAW_METHOD_DUMP(OS, get_isHotpatchable)
- RAW_METHOD_DUMP(OS, get_indirectVirtualBaseClass)
- RAW_METHOD_DUMP(OS, get_isInterfaceUdt)
- RAW_METHOD_DUMP(OS, get_intrinsic)
- RAW_METHOD_DUMP(OS, get_isLTCG)
- RAW_METHOD_DUMP(OS, get_isLocationControlFlowDependent)
- RAW_METHOD_DUMP(OS, get_isMSILNetmodule)
- RAW_METHOD_DUMP(OS, get_isMatrixRowMajor)
- RAW_METHOD_DUMP(OS, get_managed)
- RAW_METHOD_DUMP(OS, get_msil)
- RAW_METHOD_DUMP(OS, get_isMultipleInheritance)
- RAW_METHOD_DUMP(OS, get_isNaked)
- RAW_METHOD_DUMP(OS, get_nested)
- RAW_METHOD_DUMP(OS, get_isOptimizedAway)
- RAW_METHOD_DUMP(OS, get_packed)
- RAW_METHOD_DUMP(OS, get_isPointerBasedOnSymbolValue)
- RAW_METHOD_DUMP(OS, get_isPointerToDataMember)
- RAW_METHOD_DUMP(OS, get_isPointerToMemberFunction)
- RAW_METHOD_DUMP(OS, get_pure)
- RAW_METHOD_DUMP(OS, get_RValueReference)
- RAW_METHOD_DUMP(OS, get_isRefUdt)
- RAW_METHOD_DUMP(OS, get_reference)
- RAW_METHOD_DUMP(OS, get_restrictedType)
- RAW_METHOD_DUMP(OS, get_isReturnValue)
- RAW_METHOD_DUMP(OS, get_isSafeBuffers)
- RAW_METHOD_DUMP(OS, get_scoped)
- RAW_METHOD_DUMP(OS, get_isSdl)
- RAW_METHOD_DUMP(OS, get_isSingleInheritance)
- RAW_METHOD_DUMP(OS, get_isSplitted)
- RAW_METHOD_DUMP(OS, get_isStatic)
- RAW_METHOD_DUMP(OS, get_isStripped)
- RAW_METHOD_DUMP(OS, get_unalignedType)
- RAW_METHOD_DUMP(OS, get_notReached)
- RAW_METHOD_DUMP(OS, get_isValueUdt)
- RAW_METHOD_DUMP(OS, get_virtual)
- RAW_METHOD_DUMP(OS, get_virtualBaseClass)
- RAW_METHOD_DUMP(OS, get_isVirtualInheritance)
- RAW_METHOD_DUMP(OS, get_volatileType)
- RAW_METHOD_DUMP(OS, get_wasInlined)
- RAW_METHOD_DUMP(OS, get_unused)
- RAW_METHOD_DUMP(OS, get_value)
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-DIARawSymbol::findChildren(PDB_SymType Type) const {
+ RAW_METHOD_DUMP(OS, symIndexId) RAW_METHOD_DUMP(OS, symTag)
+
+ RAW_METHOD_DUMP(OS, access) RAW_METHOD_DUMP(
+ OS,
+ addressOffset) RAW_METHOD_DUMP(OS,
+ addressSection) RAW_METHOD_DUMP(OS,
+ age)
+ RAW_METHOD_DUMP(OS, arrayIndexTypeId) RAW_METHOD_DUMP(
+ OS, backEndMajor) RAW_METHOD_DUMP(OS, backEndMinor)
+ RAW_METHOD_DUMP(OS, backEndBuild) RAW_METHOD_DUMP(
+ OS, backEndQFE) RAW_METHOD_DUMP(OS, baseDataOffset)
+ RAW_METHOD_DUMP(OS, baseDataSlot) RAW_METHOD_DUMP(
+ OS, baseSymbolId) RAW_METHOD_DUMP(OS, baseType)
+ RAW_METHOD_DUMP(OS, bitPosition) RAW_METHOD_DUMP(
+ OS,
+ callingConvention) RAW_METHOD_DUMP(OS,
+ classParentId)
+ RAW_METHOD_DUMP(OS, compilerName) RAW_METHOD_DUMP(
+ OS, count) RAW_METHOD_DUMP(OS, countLiveRanges)
+ RAW_METHOD_DUMP(OS, frontEndMajor) RAW_METHOD_DUMP(
+ OS,
+ frontEndMinor) RAW_METHOD_DUMP(OS,
+ frontEndBuild)
+ RAW_METHOD_DUMP(OS, frontEndQFE) RAW_METHOD_DUMP(
+ OS,
+ lexicalParentId) RAW_METHOD_DUMP(OS,
+ libraryName)
+ RAW_METHOD_DUMP(
+ OS, liveRangeStartAddressOffset)
+ RAW_METHOD_DUMP(
+ OS,
+ liveRangeStartAddressSection)
+ RAW_METHOD_DUMP(
+ OS,
+ liveRangeStartRelativeVirtualAddress) RAW_METHOD_DUMP(OS, localBasePointerRegisterId) RAW_METHOD_DUMP(OS, lowerBoundId) RAW_METHOD_DUMP(OS, memorySpaceKind) RAW_METHOD_DUMP(OS, name) RAW_METHOD_DUMP(OS, numberOfAcceleratorPointerTags) RAW_METHOD_DUMP(OS, numberOfColumns) RAW_METHOD_DUMP(OS, numberOfModifiers) RAW_METHOD_DUMP(OS,
+ numberOfRegisterIndices) RAW_METHOD_DUMP(OS, numberOfRows) RAW_METHOD_DUMP(OS, objectFileName) RAW_METHOD_DUMP(OS, oemId) RAW_METHOD_DUMP(OS, oemSymbolId) RAW_METHOD_DUMP(OS, offsetInUdt) RAW_METHOD_DUMP(OS, platform) RAW_METHOD_DUMP(OS,
+ rank) RAW_METHOD_DUMP(OS, registerId) RAW_METHOD_DUMP(OS, registerType) RAW_METHOD_DUMP(OS, relativeVirtualAddress) RAW_METHOD_DUMP(OS, samplerSlot) RAW_METHOD_DUMP(OS, signature) RAW_METHOD_DUMP(OS, sizeInUdt) RAW_METHOD_DUMP(OS, slot) RAW_METHOD_DUMP(OS, sourceFileName) RAW_METHOD_DUMP(OS,
+ stride) RAW_METHOD_DUMP(OS,
+ subTypeId) RAW_METHOD_DUMP(OS,
+ symbolsFileName) RAW_METHOD_DUMP(OS,
+ targetOffset) RAW_METHOD_DUMP(OS,
+ targetRelativeVirtualAddress) RAW_METHOD_DUMP(OS,
+ targetVirtualAddress) RAW_METHOD_DUMP(OS,
+ targetSection) RAW_METHOD_DUMP(OS, textureSlot) RAW_METHOD_DUMP(OS, timeStamp) RAW_METHOD_DUMP(OS, token) RAW_METHOD_DUMP(OS,
+ typeId) RAW_METHOD_DUMP(OS,
+ uavSlot) RAW_METHOD_DUMP(OS,
+ undecoratedName) RAW_METHOD_DUMP(OS, unmodifiedTypeId) RAW_METHOD_DUMP(OS, upperBoundId) RAW_METHOD_DUMP(OS,
+ virtualBaseDispIndex) RAW_METHOD_DUMP(OS, virtualBaseOffset) RAW_METHOD_DUMP(OS, virtualTableShapeId) RAW_METHOD_DUMP(OS, dataKind) RAW_METHOD_DUMP(OS, guid) RAW_METHOD_DUMP(OS, offset) RAW_METHOD_DUMP(OS, thisAdjust) RAW_METHOD_DUMP(OS,
+ virtualBasePointerOffset) RAW_METHOD_DUMP(OS,
+ locationType) RAW_METHOD_DUMP(OS, machineType) RAW_METHOD_DUMP(OS, thunkOrdinal) RAW_METHOD_DUMP(OS, length) RAW_METHOD_DUMP(OS,
+ liveRangeLength) RAW_METHOD_DUMP(OS,
+ virtualAddress) RAW_METHOD_DUMP(OS,
+ udtKind) RAW_METHOD_DUMP(OS,
+ constructor) RAW_METHOD_DUMP(OS,
+ customCallingConvention) RAW_METHOD_DUMP(OS,
+ farReturn) RAW_METHOD_DUMP(OS,
+ code) RAW_METHOD_DUMP(OS,
+ compilerGenerated) RAW_METHOD_DUMP(OS, constType) RAW_METHOD_DUMP(OS, editAndContinueEnabled) RAW_METHOD_DUMP(OS, function) RAW_METHOD_DUMP(OS, stride) RAW_METHOD_DUMP(OS, noStackOrdering) RAW_METHOD_DUMP(OS, hasAlloca) RAW_METHOD_DUMP(OS, hasAssignmentOperator) RAW_METHOD_DUMP(OS, isCTypes) RAW_METHOD_DUMP(OS, hasCastOperator) RAW_METHOD_DUMP(OS, hasDebugInfo) RAW_METHOD_DUMP(OS, hasEH) RAW_METHOD_DUMP(OS, hasEHa) RAW_METHOD_DUMP(OS, hasInlAsm) RAW_METHOD_DUMP(OS,
+ framePointerPresent) RAW_METHOD_DUMP(OS,
+ inlSpec) RAW_METHOD_DUMP(OS,
+ interruptReturn) RAW_METHOD_DUMP(OS,
+ hasLongJump) RAW_METHOD_DUMP(OS, hasManagedCode) RAW_METHOD_DUMP(OS, hasNestedTypes) RAW_METHOD_DUMP(OS, noInline) RAW_METHOD_DUMP(OS, noReturn) RAW_METHOD_DUMP(OS, optimizedCodeDebugInfo) RAW_METHOD_DUMP(OS, overloadedOperator) RAW_METHOD_DUMP(OS, hasSEH) RAW_METHOD_DUMP(OS,
+ hasSecurityChecks) RAW_METHOD_DUMP(OS, hasSetJump) RAW_METHOD_DUMP(OS, strictGSCheck) RAW_METHOD_DUMP(OS, isAcceleratorGroupSharedLocal) RAW_METHOD_DUMP(OS, isAcceleratorPointerTagLiveRange) RAW_METHOD_DUMP(OS, isAcceleratorStubFunction)
+ RAW_METHOD_DUMP(OS, isAggregated) RAW_METHOD_DUMP(
+ OS,
+ intro) RAW_METHOD_DUMP(OS,
+ isCVTCIL)
+ RAW_METHOD_DUMP(OS, isConstructorVirtualBase) RAW_METHOD_DUMP(
+ OS,
+ isCxxReturnUdt) RAW_METHOD_DUMP(OS, isDataAligned)
+ RAW_METHOD_DUMP(OS, isHLSLData) RAW_METHOD_DUMP(
+ OS,
+ isHotpatchable)
+ RAW_METHOD_DUMP(
+ OS,
+ indirectVirtualBaseClass)
+ RAW_METHOD_DUMP(
+ OS,
+ isInterfaceUdt) RAW_METHOD_DUMP(OS,
+ intrinsic) RAW_METHOD_DUMP(OS,
+ isLTCG) RAW_METHOD_DUMP(OS, isLocationControlFlowDependent) RAW_METHOD_DUMP(OS, isMSILNetmodule) RAW_METHOD_DUMP(OS, isMatrixRowMajor) RAW_METHOD_DUMP(OS, managed) RAW_METHOD_DUMP(OS,
+ msil) RAW_METHOD_DUMP(OS,
+ isMultipleInheritance) RAW_METHOD_DUMP(OS, isNaked) RAW_METHOD_DUMP(OS, nested) RAW_METHOD_DUMP(OS, isOptimizedAway) RAW_METHOD_DUMP(OS, packed) RAW_METHOD_DUMP(OS, isPointerBasedOnSymbolValue) RAW_METHOD_DUMP(OS,
+ isPointerToDataMember) RAW_METHOD_DUMP(OS, isPointerToMemberFunction) RAW_METHOD_DUMP(OS,
+ pure) RAW_METHOD_DUMP(OS,
+ RValueReference) RAW_METHOD_DUMP(OS,
+ isRefUdt) RAW_METHOD_DUMP(OS,
+ reference) RAW_METHOD_DUMP(OS, restrictedType) RAW_METHOD_DUMP(OS, isReturnValue) RAW_METHOD_DUMP(OS, isSafeBuffers) RAW_METHOD_DUMP(OS, scoped) RAW_METHOD_DUMP(OS, isSdl) RAW_METHOD_DUMP(OS, isSingleInheritance)
+ RAW_METHOD_DUMP(OS, isSplitted) RAW_METHOD_DUMP(
+ OS,
+ isStatic) RAW_METHOD_DUMP(OS,
+ isStripped)
+ RAW_METHOD_DUMP(OS, unalignedType) RAW_METHOD_DUMP(
+ OS,
+ notReached) RAW_METHOD_DUMP(OS, isValueUdt)
+ RAW_METHOD_DUMP(OS, virtual) RAW_METHOD_DUMP(
+ OS,
+ virtualBaseClass)
+ RAW_METHOD_DUMP(
+ OS,
+ isVirtualInheritance)
+ RAW_METHOD_DUMP(
+ OS,
+ volatileType)
+ RAW_METHOD_DUMP(
+ OS,
+ wasInlined)
+ RAW_METHOD_DUMP(
+ OS,
+ unused)
+ RAW_METHOD_DUMP(
+ OS,
+ value)}
+
+std::unique_ptr<IPDBEnumSymbols> DIARawSymbol::findChildren(
+ PDB_SymType Type) const {
enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);
CComPtr<IDiaEnumSymbols> DiaEnumerator;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
index da22a0ed89d..7856da3854e 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
@@ -23,6 +23,18 @@ PDB_SymType NativeCompilandSymbol::getSymTag() const {
return PDB_SymType::Compiland;
}
+void NativeCompilandSymbol::dump(raw_ostream &OS, int Indent) const {
+ NativeRawSymbol::dump(OS, Indent);
+
+ dumpSymbolField(OS, "baseType", static_cast<uint32_t>(getBuiltinType()),
+ Indent);
+ dumpSymbolField(OS, "lexicalParentId", 0, Indent);
+ dumpSymbolField(OS, "libraryName", getLibraryName(), Indent);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolField(OS, "editAndContinueEnabled", isEditAndContinueEnabled(),
+ Indent);
+}
+
std::unique_ptr<NativeRawSymbol> NativeCompilandSymbol::clone() const {
return llvm::make_unique<NativeCompilandSymbol>(Session, SymbolId, Module);
}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
index 34860045726..2242106067e 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
@@ -40,8 +40,11 @@ uint32_t NativeEnumTypes::getChildCount() const {
std::unique_ptr<PDBSymbol>
NativeEnumTypes::getChildAtIndex(uint32_t Index) const {
- if (Index < Matches.size())
- return Session.getSymbolCache().createEnumSymbol(Matches[Index]);
+ if (Index < Matches.size()) {
+ SymIndexId Id =
+ Session.getSymbolCache().findSymbolByTypeIndex(Matches[Index]);
+ return Session.getSymbolCache().getSymbolById(Id);
+ }
return nullptr;
}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
index 59eaf3e8d49..1fbdc2b49ec 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
@@ -47,6 +47,8 @@ NativeExeSymbol::findChildren(PDB_SymType Type) const {
}
case PDB_SymType::Enum:
return Session.getSymbolCache().createTypeEnumerator(codeview::LF_ENUM);
+ case PDB_SymType::PointerType:
+ return Session.getSymbolCache().createTypeEnumerator(codeview::LF_POINTER);
default:
break;
}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
index 21527100461..c0e6df73b0e 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
@@ -7,9 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
using namespace llvm::pdb;
@@ -18,7 +19,10 @@ NativeRawSymbol::NativeRawSymbol(NativeSession &PDBSession, PDB_SymType Tag,
SymIndexId SymbolId)
: Session(PDBSession), Tag(Tag), SymbolId(SymbolId) {}
-void NativeRawSymbol::dump(raw_ostream &OS, int Indent) const {}
+void NativeRawSymbol::dump(raw_ostream &OS, int Indent) const {
+ dumpSymbolField(OS, "symIndexId", SymbolId, Indent);
+ dumpSymbolField(OS, "symTag", static_cast<uint32_t>(Tag), Indent);
+}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildren(PDB_SymType Type) const {
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
index 8510def344c..5a8400a5e4e 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/Support/FormatVariadic.h"
namespace llvm {
namespace pdb {
@@ -24,7 +25,6 @@ std::unique_ptr<NativeRawSymbol> NativeTypeBuiltin::clone() const {
}
void NativeTypeBuiltin::dump(raw_ostream &OS, int Indent) const {
- // TODO: Apparently nothing needs this yet.
}
PDB_SymType NativeTypeBuiltin::getSymTag() const {
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
index 10598416377..b238ace1002 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
@@ -15,9 +15,12 @@
#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/Support/FormatVariadic.h"
+
#include <cassert>
using namespace llvm;
+using namespace llvm::codeview;
using namespace llvm::pdb;
NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
@@ -30,6 +33,32 @@ NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
NativeTypeEnum::~NativeTypeEnum() {}
+void NativeTypeEnum::dump(raw_ostream &OS, int Indent) const {
+ NativeRawSymbol::dump(OS, Indent);
+
+ dumpSymbolField(OS, "baseType", static_cast<uint32_t>(getBuiltinType()),
+ Indent);
+ dumpSymbolField(OS, "lexicalParentId", 0, Indent);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolField(OS, "typeId", getTypeId(), Indent);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
+ dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
+ dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
+ dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
+ dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
+ dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
+ dumpSymbolField(OS, "nested", isNested(), Indent);
+ dumpSymbolField(OS, "packed", isPacked(), Indent);
+ dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
+ dumpSymbolField(OS, "scoped", isScoped(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
std::unique_ptr<NativeRawSymbol> NativeTypeEnum::clone() const {
return llvm::make_unique<NativeTypeEnum>(Session, SymbolId, CV);
}
@@ -38,7 +67,7 @@ std::unique_ptr<IPDBEnumSymbols>
NativeTypeEnum::findChildren(PDB_SymType Type) const {
switch (Type) {
case PDB_SymType::Data: {
- // TODO(amccarth): Provide an actual implementation.
+ // TODO(amccarth) : Provide an actual implementation.
return nullptr;
}
default:
@@ -59,9 +88,78 @@ Error NativeTypeEnum::visitKnownMember(codeview::CVMemberRecord &CVM,
PDB_SymType NativeTypeEnum::getSymTag() const { return PDB_SymType::Enum; }
-uint32_t NativeTypeEnum::getClassParentId() const { return 0xFFFFFFFF; }
+PDB_BuiltinType NativeTypeEnum::getBuiltinType() const {
+ Session.getSymbolCache().findSymbolByTypeIndex(Record.getUnderlyingType());
+
+ codeview::TypeIndex Underlying = Record.getUnderlyingType();
+
+ // This indicates a corrupt record.
+ if (!Underlying.isSimple() ||
+ Underlying.getSimpleMode() != SimpleTypeMode::Direct)
+ return PDB_BuiltinType::None;
+
+ switch (Underlying.getSimpleKind()) {
+ case SimpleTypeKind::Boolean128:
+ case SimpleTypeKind::Boolean64:
+ case SimpleTypeKind::Boolean32:
+ case SimpleTypeKind::Boolean16:
+ case SimpleTypeKind::Boolean8:
+ return PDB_BuiltinType::Bool;
+ case SimpleTypeKind::NarrowCharacter:
+ case SimpleTypeKind::UnsignedCharacter:
+ return PDB_BuiltinType::Char;
+ case SimpleTypeKind::WideCharacter:
+ return PDB_BuiltinType::WCharT;
+ case SimpleTypeKind::Character16:
+ return PDB_BuiltinType::Char16;
+ case SimpleTypeKind::Character32:
+ return PDB_BuiltinType::Char32;
+ case SimpleTypeKind::Int128:
+ case SimpleTypeKind::Int128Oct:
+ case SimpleTypeKind::Int16:
+ case SimpleTypeKind::Int16Short:
+ case SimpleTypeKind::Int32:
+ case SimpleTypeKind::Int32Long:
+ case SimpleTypeKind::Int64:
+ case SimpleTypeKind::Int64Quad:
+ return PDB_BuiltinType::Int;
+ case SimpleTypeKind::UInt128:
+ case SimpleTypeKind::UInt128Oct:
+ case SimpleTypeKind::UInt16:
+ case SimpleTypeKind::UInt16Short:
+ case SimpleTypeKind::UInt32:
+ case SimpleTypeKind::UInt32Long:
+ case SimpleTypeKind::UInt64:
+ case SimpleTypeKind::UInt64Quad:
+ return PDB_BuiltinType::UInt;
+ case SimpleTypeKind::HResult:
+ return PDB_BuiltinType::HResult;
+ case SimpleTypeKind::Complex16:
+ case SimpleTypeKind::Complex32:
+ case SimpleTypeKind::Complex32PartialPrecision:
+ case SimpleTypeKind::Complex64:
+ case SimpleTypeKind::Complex80:
+ case SimpleTypeKind::Complex128:
+ return PDB_BuiltinType::Complex;
+ case SimpleTypeKind::Float16:
+ case SimpleTypeKind::Float32:
+ case SimpleTypeKind::Float32PartialPrecision:
+ case SimpleTypeKind::Float48:
+ case SimpleTypeKind::Float64:
+ case SimpleTypeKind::Float80:
+ case SimpleTypeKind::Float128:
+ return PDB_BuiltinType::Float;
+ default:
+ return PDB_BuiltinType::None;
+ }
+ llvm_unreachable("Unreachable");
+}
-uint32_t NativeTypeEnum::getUnmodifiedTypeId() const { return 0; }
+uint32_t NativeTypeEnum::getUnmodifiedTypeId() const {
+ // FIXME: If this is const, volatile, or unaligned, we should return the
+ // SymIndexId of the unmodified type here.
+ return 0;
+}
bool NativeTypeEnum::hasConstructor() const {
return bool(Record.getOptions() &
@@ -73,6 +171,15 @@ bool NativeTypeEnum::hasAssignmentOperator() const {
codeview::ClassOptions::HasOverloadedAssignmentOperator);
}
+bool NativeTypeEnum::hasNestedTypes() const {
+ return bool(Record.getOptions() &
+ codeview::ClassOptions::ContainsNestedClass);
+}
+
+bool NativeTypeEnum::isIntrinsic() const {
+ return bool(Record.getOptions() & codeview::ClassOptions::Intrinsic);
+}
+
bool NativeTypeEnum::hasCastOperator() const {
return bool(Record.getOptions() &
codeview::ClassOptions::HasConversionOperator);
@@ -109,3 +216,9 @@ uint32_t NativeTypeEnum::getTypeId() const {
return Session.getSymbolCache().findSymbolByTypeIndex(
Record.getUnderlyingType());
}
+
+bool NativeTypeEnum::isRefUdt() const { return false; }
+
+bool NativeTypeEnum::isValueUdt() const { return false; }
+
+bool NativeTypeEnum::isInterfaceUdt() const { return false; }
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp
new file mode 100644
index 00000000000..bc3657be089
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp
@@ -0,0 +1,86 @@
+//===- NativeTypePointer.cpp - info about pointer 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/NativeTypePointer.h"
+
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+
+#include <cassert>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
+ codeview::CVType CVT)
+ : NativeRawSymbol(Session, PDB_SymType::PointerType, Id),
+ Record(TypeRecordKind::Pointer) {
+ assert(CVT.kind() == TypeLeafKind::LF_POINTER);
+ cantFail(TypeDeserializer::deserializeAs<PointerRecord>(CVT, Record));
+}
+
+NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
+ PointerRecord PR)
+ : NativeRawSymbol(Session, PDB_SymType::PointerType, Id),
+ Record(std::move(PR)) {}
+
+NativeTypePointer::~NativeTypePointer() {}
+
+void NativeTypePointer::dump(raw_ostream &OS, int Indent) const {
+ NativeRawSymbol::dump(OS, Indent);
+
+ dumpSymbolField(OS, "lexicalParentId", 0, Indent);
+ dumpSymbolField(OS, "typeId", getTypeId(), Indent);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "isPointerToDataMember", isPointerToDataMember(), Indent);
+ dumpSymbolField(OS, "isPointerToMemberFunction", isPointerToMemberFunction(),
+ Indent);
+ dumpSymbolField(OS, "RValueReference", isRValueReference(), Indent);
+ dumpSymbolField(OS, "reference", isReference(), Indent);
+ dumpSymbolField(OS, "restrictedType", isRestrictedType(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+std::unique_ptr<NativeRawSymbol> NativeTypePointer::clone() const {
+ return llvm::make_unique<NativeTypePointer>(Session, SymbolId, Record);
+}
+
+bool NativeTypePointer::isConstType() const { return false; }
+
+uint64_t NativeTypePointer::getLength() const { return Record.getSize(); }
+
+uint32_t NativeTypePointer::getTypeId() const {
+ // This is the pointee SymIndexId.
+ return Session.getSymbolCache().findSymbolByTypeIndex(Record.ReferentType);
+}
+
+bool NativeTypePointer::isReference() const {
+ return Record.getMode() == PointerMode::LValueReference ||
+ isRValueReference();
+}
+
+bool NativeTypePointer::isRValueReference() const {
+ return Record.getMode() == PointerMode::RValueReference;
+}
+
+bool NativeTypePointer::isPointerToDataMember() const {
+ return Record.getMode() == PointerMode::PointerToDataMember;
+}
+
+bool NativeTypePointer::isPointerToMemberFunction() const {
+ return Record.getMode() == PointerMode::PointerToMemberFunction;
+}
+
+bool NativeTypePointer::isRestrictedType() const { return false; }
+
+bool NativeTypePointer::isVolatileType() const { return false; }
+
+bool NativeTypePointer::isUnalignedType() const { return false; }
diff --git a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
index abba065e31d..71f8fdd34b8 100644
--- a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
@@ -7,6 +7,7 @@
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
@@ -60,7 +61,7 @@ SymbolCache::createTypeEnumerator(codeview::TypeLeafKind Kind) {
}
auto &Types = Tpi->typeCollection();
return std::unique_ptr<IPDBEnumSymbols>(
- new NativeEnumTypes(Session, Types, codeview::LF_ENUM));
+ new NativeEnumTypes(Session, Types, Kind));
}
SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) {
@@ -104,9 +105,12 @@ SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) {
case codeview::LF_ENUM:
Id = createSymbol<NativeTypeEnum>(CVT);
break;
+ case codeview::LF_POINTER:
+ Id = createSymbol<NativeTypePointer>(CVT);
+ break;
default:
- assert(false && "Unsupported native symbol type!");
- return 0;
+ Id = createSymbolPlaceholder();
+ break;
}
TypeIndexToSymbolId[Index] = Id;
return Id;
@@ -114,6 +118,10 @@ SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) {
std::unique_ptr<PDBSymbol>
SymbolCache::getSymbolById(SymIndexId SymbolId) const {
+ // Id 0 is reserved.
+ if (SymbolId == 0)
+ return nullptr;
+
// If the caller has a SymbolId, it'd better be in our SymbolCache.
return SymbolId < Cache.size() ? PDBSymbol::create(Session, *Cache[SymbolId])
: nullptr;
diff --git a/llvm/test/DebugInfo/PDB/Native/pdb-native-compilands.test b/llvm/test/DebugInfo/PDB/Native/pdb-native-compilands.test
index 2c7011c6570..028e3379377 100644
--- a/llvm/test/DebugInfo/PDB/Native/pdb-native-compilands.test
+++ b/llvm/test/DebugInfo/PDB/Native/pdb-native-compilands.test
@@ -3,6 +3,8 @@
; RUN: | FileCheck -check-prefix=EMPTY %s
; RUN: llvm-pdbutil pretty -native -compilands %p/../Inputs/big-read.pdb \
; RUN: | FileCheck -check-prefix=BIGREAD %s
+; RUN: llvm-pdbutil diadump -compilands %p/../Inputs/empty.pdb \
+; RUN: | FileCheck -check-prefix=DUMP %s
; Reference output was generated with the DIA reader to ensure that the
; `-native` option produces identical output. The paths output will have
@@ -63,3 +65,20 @@ BIGREAD: api-ms-win-crt-locale-l1-1-0.dll
BIGREAD: Import:api-ms-win-crt-heap-l1-1-0.dll
BIGREAD: api-ms-win-crt-heap-l1-1-0.dll
BIGREAD: * Linker *
+
+DUMP: {
+DUMP-NEXT: symIndexId: 1
+DUMP-NEXT: symTag: 2
+DUMP-NEXT: lexicalParentId: 2
+DUMP-NEXT: libraryName: d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj
+DUMP-NEXT: name: d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj
+DUMP-NEXT: editAndContinueEnabled: 0
+DUMP-NEXT: }
+DUMP-NEXT: {
+DUMP-NEXT: symIndexId: 3
+DUMP-NEXT: symTag: 2
+DUMP-NEXT: lexicalParentId: 2
+DUMP-NEXT: libraryName:
+DUMP-NEXT: name: * Linker *
+DUMP-NEXT: editAndContinueEnabled: 0
+DUMP-NEXT: } \ No newline at end of file
diff --git a/llvm/test/DebugInfo/PDB/Native/pdb-native-enums.test b/llvm/test/DebugInfo/PDB/Native/pdb-native-enums.test
index 90581537aa1..f175a87d38a 100644
--- a/llvm/test/DebugInfo/PDB/Native/pdb-native-enums.test
+++ b/llvm/test/DebugInfo/PDB/Native/pdb-native-enums.test
@@ -1,6 +1,225 @@
; Test that the native PDB reader can enumerate the enum types.
; RUN: llvm-pdbutil pretty -native -enums %p/../Inputs/every-type.pdb \
; RUN: | FileCheck -check-prefix=ENUMS %s
+; RUN: llvm-pdbutil diadump -native -enums %p/../Inputs/every-type.pdb \
+; RUN: | FileCheck -check-prefix=DUMP %s
ENUMS: enum FooClass::NestedEnum {
ENUMS-NEXT: }
+
+DUMP: {
+DUMP-NEXT: symIndexId: 2
+DUMP-NEXT: symTag: 12
+DUMP-NEXT: baseType: 6
+DUMP-NEXT: lexicalParentId: 0
+DUMP-NEXT: name: __vc_attributes::event_sourceAttribute::type_e
+DUMP-NEXT: typeId: 3
+DUMP-NEXT: length: 4
+DUMP-NEXT: constructor: 0
+DUMP-NEXT: constType: 0
+DUMP-NEXT: hasAssignmentOperator: 0
+DUMP-NEXT: hasCastOperator: 0
+DUMP-NEXT: hasNestedTypes: 0
+DUMP-NEXT: overloadedOperator: 0
+DUMP-NEXT: isInterfaceUdt: 0
+DUMP-NEXT: intrinsic: 0
+DUMP-NEXT: nested: 1
+DUMP-NEXT: packed: 0
+DUMP-NEXT: isRefUdt: 0
+DUMP-NEXT: scoped: 0
+DUMP-NEXT: unalignedType: 0
+DUMP-NEXT: isValueUdt: 0
+DUMP-NEXT: volatileType: 0
+DUMP-NEXT: }
+DUMP-NEXT: {
+DUMP-NEXT: symIndexId: 4
+DUMP-NEXT: symTag: 12
+DUMP-NEXT: baseType: 6
+DUMP-NEXT: lexicalParentId: 0
+DUMP-NEXT: name: __vc_attributes::event_sourceAttribute::optimize_e
+DUMP-NEXT: typeId: 3
+DUMP-NEXT: length: 4
+DUMP-NEXT: constructor: 0
+DUMP-NEXT: constType: 0
+DUMP-NEXT: hasAssignmentOperator: 0
+DUMP-NEXT: hasCastOperator: 0
+DUMP-NEXT: hasNestedTypes: 0
+DUMP-NEXT: overloadedOperator: 0
+DUMP-NEXT: isInterfaceUdt: 0
+DUMP-NEXT: intrinsic: 0
+DUMP-NEXT: nested: 1
+DUMP-NEXT: packed: 0
+DUMP-NEXT: isRefUdt: 0
+DUMP-NEXT: scoped: 0
+DUMP-NEXT: unalignedType: 0
+DUMP-NEXT: isValueUdt: 0
+DUMP-NEXT: volatileType: 0
+DUMP-NEXT: }
+DUMP-NEXT: {
+DUMP-NEXT: symIndexId: 5
+DUMP-NEXT: symTag: 12
+DUMP-NEXT: baseType: 6
+DUMP-NEXT: lexicalParentId: 0
+DUMP-NEXT: name: __vc_attributes::helper_attributes::v1_alttypeAttribute::type_e
+DUMP-NEXT: typeId: 3
+DUMP-NEXT: length: 4
+DUMP-NEXT: constructor: 0
+DUMP-NEXT: constType: 0
+DUMP-NEXT: hasAssignmentOperator: 0
+DUMP-NEXT: hasCastOperator: 0
+DUMP-NEXT: hasNestedTypes: 0
+DUMP-NEXT: overloadedOperator: 0
+DUMP-NEXT: isInterfaceUdt: 0
+DUMP-NEXT: intrinsic: 0
+DUMP-NEXT: nested: 1
+DUMP-NEXT: packed: 0
+DUMP-NEXT: isRefUdt: 0
+DUMP-NEXT: scoped: 0
+DUMP-NEXT: unalignedType: 0
+DUMP-NEXT: isValueUdt: 0
+DUMP-NEXT: volatileType: 0
+DUMP-NEXT: }
+DUMP-NEXT: {
+DUMP-NEXT: symIndexId: 6
+DUMP-NEXT: symTag: 12
+DUMP-NEXT: baseType: 6
+DUMP-NEXT: lexicalParentId: 0
+DUMP-NEXT: name: __vc_attributes::helper_attributes::usageAttribute::usage_e
+DUMP-NEXT: typeId: 3
+DUMP-NEXT: length: 4
+DUMP-NEXT: constructor: 0
+DUMP-NEXT: constType: 0
+DUMP-NEXT: hasAssignmentOperator: 0
+DUMP-NEXT: hasCastOperator: 0
+DUMP-NEXT: hasNestedTypes: 0
+DUMP-NEXT: overloadedOperator: 0
+DUMP-NEXT: isInterfaceUdt: 0
+DUMP-NEXT: intrinsic: 0
+DUMP-NEXT: nested: 1
+DUMP-NEXT: packed: 0
+DUMP-NEXT: isRefUdt: 0
+DUMP-NEXT: scoped: 0
+DUMP-NEXT: unalignedType: 0
+DUMP-NEXT: isValueUdt: 0
+DUMP-NEXT: volatileType: 0
+DUMP-NEXT: }
+DUMP-NEXT: {
+DUMP-NEXT: symIndexId: 7
+DUMP-NEXT: symTag: 12
+DUMP-NEXT: baseType: 6
+DUMP-NEXT: lexicalParentId: 0
+DUMP-NEXT: name: __vc_attributes::threadingAttribute::threading_e
+DUMP-NEXT: typeId: 3
+DUMP-NEXT: length: 4
+DUMP-NEXT: constructor: 0
+DUMP-NEXT: constType: 0
+DUMP-NEXT: hasAssignmentOperator: 0
+DUMP-NEXT: hasCastOperator: 0
+DUMP-NEXT: hasNestedTypes: 0
+DUMP-NEXT: overloadedOperator: 0
+DUMP-NEXT: isInterfaceUdt: 0
+DUMP-NEXT: intrinsic: 0
+DUMP-NEXT: nested: 1
+DUMP-NEXT: packed: 0
+DUMP-NEXT: isRefUdt: 0
+DUMP-NEXT: scoped: 0
+DUMP-NEXT: unalignedType: 0
+DUMP-NEXT: isValueUdt: 0
+DUMP-NEXT: volatileType: 0
+DUMP-NEXT: }
+DUMP-NEXT: {
+DUMP-NEXT: symIndexId: 8
+DUMP-NEXT: symTag: 12
+DUMP-NEXT: baseType: 6
+DUMP-NEXT: lexicalParentId: 0
+DUMP-NEXT: name: __vc_attributes::aggregatableAttribute::type_e
+DUMP-NEXT: typeId: 3
+DUMP-NEXT: length: 4
+DUMP-NEXT: constructor: 0
+DUMP-NEXT: constType: 0
+DUMP-NEXT: hasAssignmentOperator: 0
+DUMP-NEXT: hasCastOperator: 0
+DUMP-NEXT: hasNestedTypes: 0
+DUMP-NEXT: overloadedOperator: 0
+DUMP-NEXT: isInterfaceUdt: 0
+DUMP-NEXT: intrinsic: 0
+DUMP-NEXT: nested: 1
+DUMP-NEXT: packed: 0
+DUMP-NEXT: isRefUdt: 0
+DUMP-NEXT: scoped: 0
+DUMP-NEXT: unalignedType: 0
+DUMP-NEXT: isValueUdt: 0
+DUMP-NEXT: volatileType: 0
+DUMP-NEXT: }
+DUMP-NEXT: {
+DUMP-NEXT: symIndexId: 9
+DUMP-NEXT: symTag: 12
+DUMP-NEXT: baseType: 6
+DUMP-NEXT: lexicalParentId: 0
+DUMP-NEXT: name: __vc_attributes::event_receiverAttribute::type_e
+DUMP-NEXT: typeId: 3
+DUMP-NEXT: length: 4
+DUMP-NEXT: constructor: 0
+DUMP-NEXT: constType: 0
+DUMP-NEXT: hasAssignmentOperator: 0
+DUMP-NEXT: hasCastOperator: 0
+DUMP-NEXT: hasNestedTypes: 0
+DUMP-NEXT: overloadedOperator: 0
+DUMP-NEXT: isInterfaceUdt: 0
+DUMP-NEXT: intrinsic: 0
+DUMP-NEXT: nested: 1
+DUMP-NEXT: packed: 0
+DUMP-NEXT: isRefUdt: 0
+DUMP-NEXT: scoped: 0
+DUMP-NEXT: unalignedType: 0
+DUMP-NEXT: isValueUdt: 0
+DUMP-NEXT: volatileType: 0
+DUMP-NEXT: }
+DUMP-NEXT: {
+DUMP-NEXT: symIndexId: 10
+DUMP-NEXT: symTag: 12
+DUMP-NEXT: baseType: 6
+DUMP-NEXT: lexicalParentId: 0
+DUMP-NEXT: name: __vc_attributes::moduleAttribute::type_e
+DUMP-NEXT: typeId: 3
+DUMP-NEXT: length: 4
+DUMP-NEXT: constructor: 0
+DUMP-NEXT: constType: 0
+DUMP-NEXT: hasAssignmentOperator: 0
+DUMP-NEXT: hasCastOperator: 0
+DUMP-NEXT: hasNestedTypes: 0
+DUMP-NEXT: overloadedOperator: 0
+DUMP-NEXT: isInterfaceUdt: 0
+DUMP-NEXT: intrinsic: 0
+DUMP-NEXT: nested: 1
+DUMP-NEXT: packed: 0
+DUMP-NEXT: isRefUdt: 0
+DUMP-NEXT: scoped: 0
+DUMP-NEXT: unalignedType: 0
+DUMP-NEXT: isValueUdt: 0
+DUMP-NEXT: volatileType: 0
+DUMP-NEXT: }
+DUMP-NEXT: {
+DUMP-NEXT: symIndexId: 11
+DUMP-NEXT: symTag: 12
+DUMP-NEXT: baseType: 6
+DUMP-NEXT: lexicalParentId: 0
+DUMP-NEXT: name: FooClass::NestedEnum
+DUMP-NEXT: typeId: 3
+DUMP-NEXT: length: 4
+DUMP-NEXT: constructor: 0
+DUMP-NEXT: constType: 0
+DUMP-NEXT: hasAssignmentOperator: 0
+DUMP-NEXT: hasCastOperator: 0
+DUMP-NEXT: hasNestedTypes: 0
+DUMP-NEXT: overloadedOperator: 0
+DUMP-NEXT: isInterfaceUdt: 0
+DUMP-NEXT: intrinsic: 0
+DUMP-NEXT: nested: 1
+DUMP-NEXT: packed: 0
+DUMP-NEXT: isRefUdt: 0
+DUMP-NEXT: scoped: 0
+DUMP-NEXT: unalignedType: 0
+DUMP-NEXT: isValueUdt: 0
+DUMP-NEXT: volatileType: 0
+DUMP-NEXT: }
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
index bd77ee05e8c..0a4fb49284d 100644
--- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
+++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
@@ -101,6 +101,9 @@ namespace opts {
cl::SubCommand DumpSubcommand("dump", "Dump MSF and CodeView debug info");
cl::SubCommand BytesSubcommand("bytes", "Dump raw bytes from the PDB file");
+cl::SubCommand DiaDumpSubcommand("diadump",
+ "Dump debug information using a DIA-like API");
+
cl::SubCommand
PrettySubcommand("pretty",
"Dump semantic information about types and symbols");
@@ -154,6 +157,23 @@ cl::ValuesClass ChunkValues = cl::values(
"Any subsection not covered by another option"),
clEnumValN(ModuleSubsection::All, "all", "All known subsections"));
+namespace diadump {
+cl::list<std::string> InputFilenames(cl::Positional,
+ cl::desc("<input PDB files>"),
+ cl::OneOrMore, cl::sub(DiaDumpSubcommand));
+
+cl::opt<bool> Native("native", cl::desc("Use native PDB reader instead of DIA"),
+ cl::sub(DiaDumpSubcommand));
+
+static cl::opt<bool> Enums("enums", cl::desc("Dump enum types"),
+ cl::sub(DiaDumpSubcommand));
+static cl::opt<bool> Pointers("pointers", cl::desc("Dump enum types"),
+ cl::sub(DiaDumpSubcommand));
+static cl::opt<bool> Compilands("compilands",
+ cl::desc("Dump compiland information"),
+ cl::sub(DiaDumpSubcommand));
+} // namespace diadump
+
namespace pretty {
cl::list<std::string> InputFilenames(cl::Positional,
cl::desc("<input PDB files>"),
@@ -923,6 +943,34 @@ static void dumpInjectedSources(LinePrinter &Printer, IPDBSession &Session) {
}
}
+static void dumpDia(StringRef Path) {
+ std::unique_ptr<IPDBSession> Session;
+
+ const auto ReaderType =
+ opts::diadump::Native ? PDB_ReaderType::Native : PDB_ReaderType::DIA;
+ ExitOnErr(loadDataForPDB(ReaderType, Path, Session));
+
+ auto GlobalScope = Session->getGlobalScope();
+
+ std::vector<PDB_SymType> SymTypes;
+
+ if (opts::diadump::Compilands)
+ SymTypes.push_back(PDB_SymType::Compiland);
+ if (opts::diadump::Enums)
+ SymTypes.push_back(PDB_SymType::Enum);
+ if (opts::diadump::Pointers)
+ SymTypes.push_back(PDB_SymType::PointerType);
+
+ for (PDB_SymType ST : SymTypes) {
+ auto Children = GlobalScope->findAllChildren(ST);
+ while (auto Child = Children->getNext()) {
+ outs() << "{";
+ Child->defaultDump(outs(), 2);
+ outs() << "\n}\n";
+ }
+ }
+}
+
static void dumpPretty(StringRef Path) {
std::unique_ptr<IPDBSession> Session;
@@ -1385,6 +1433,8 @@ int main(int Argc, const char **Argv) {
yamlToPdb(opts::yaml2pdb::InputFilename);
} else if (opts::AnalyzeSubcommand) {
dumpAnalysis(opts::analyze::InputFilename.front());
+ } else if (opts::DiaDumpSubcommand) {
+ llvm::for_each(opts::diadump::InputFilenames, dumpDia);
} else if (opts::PrettySubcommand) {
if (opts::pretty::Lines)
opts::pretty::Compilands = true;
OpenPOWER on IntegriCloud