mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
Teach llvm-pdbutil to dump types from object files.
llvm-svn: 319859
This commit is contained in:
parent
0fa3f46b55
commit
f833cb4207
@ -67,6 +67,7 @@ public:
|
||||
|
||||
void reset(ArrayRef<uint8_t> Data, uint32_t RecordCountHint);
|
||||
void reset(StringRef Data, uint32_t RecordCountHint);
|
||||
void reset(BinaryStreamReader &Reader, uint32_t RecordCountHint);
|
||||
|
||||
uint32_t getOffsetOfType(TypeIndex Index);
|
||||
|
||||
|
@ -10,12 +10,15 @@
|
||||
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEHASHING_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_TYPEHASHING_H
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
||||
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeCollection.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
||||
|
||||
#include "llvm/Support/FormatProviders.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
|
||||
@ -29,7 +32,28 @@ struct LocallyHashedType {
|
||||
hash_code Hash;
|
||||
ArrayRef<uint8_t> RecordData;
|
||||
|
||||
/// Given a type, compute its local hash.
|
||||
static LocallyHashedType hashType(ArrayRef<uint8_t> RecordData);
|
||||
|
||||
/// Given a sequence of types, compute all of the local hashes.
|
||||
template <typename Range>
|
||||
static std::vector<LocallyHashedType> hashTypes(Range &&Records) {
|
||||
std::vector<LocallyHashedType> Hashes;
|
||||
Hashes.reserve(std::distance(std::begin(Records), std::end(Records)));
|
||||
for (const auto &R : Records)
|
||||
Hashes.push_back(hashType(R));
|
||||
|
||||
return Hashes;
|
||||
}
|
||||
|
||||
static std::vector<LocallyHashedType>
|
||||
hashTypeCollection(TypeCollection &Types) {
|
||||
std::vector<LocallyHashedType> Hashes;
|
||||
Types.ForEachRecord([&Hashes](TypeIndex TI, const CVType &Type) {
|
||||
Hashes.push_back(hashType(Type.RecordData));
|
||||
});
|
||||
return Hashes;
|
||||
}
|
||||
};
|
||||
|
||||
/// A globally hashed type represents a hash value that is sufficient to
|
||||
@ -73,6 +97,15 @@ struct GloballyHashedType {
|
||||
|
||||
return Hashes;
|
||||
}
|
||||
|
||||
static std::vector<GloballyHashedType>
|
||||
hashTypeCollection(TypeCollection &Types) {
|
||||
std::vector<GloballyHashedType> Hashes;
|
||||
Types.ForEachRecord([&Hashes](TypeIndex TI, const CVType &Type) {
|
||||
Hashes.push_back(hashType(Type.RecordData, Hashes, Hashes));
|
||||
});
|
||||
return Hashes;
|
||||
}
|
||||
};
|
||||
} // namespace codeview
|
||||
|
||||
@ -114,6 +147,24 @@ template <> struct DenseMapInfo<codeview::GloballyHashedType> {
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct format_provider<codeview::LocallyHashedType> {
|
||||
public:
|
||||
static void format(const codeview::LocallyHashedType &V,
|
||||
llvm::raw_ostream &Stream, StringRef Style) {
|
||||
write_hex(Stream, V.Hash, HexPrintStyle::Upper, 8);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct format_provider<codeview::GloballyHashedType> {
|
||||
public:
|
||||
static void format(const codeview::GloballyHashedType &V,
|
||||
llvm::raw_ostream &Stream, StringRef Style) {
|
||||
for (uint8_t B : V.Hash) {
|
||||
write_hex(Stream, B, HexPrintStyle::Upper, 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -58,21 +58,27 @@ LazyRandomTypeCollection::LazyRandomTypeCollection(const CVTypeArray &Types,
|
||||
uint32_t NumRecords)
|
||||
: LazyRandomTypeCollection(Types, NumRecords, PartialOffsetArray()) {}
|
||||
|
||||
void LazyRandomTypeCollection::reset(StringRef Data, uint32_t RecordCountHint) {
|
||||
void LazyRandomTypeCollection::reset(BinaryStreamReader &Reader,
|
||||
uint32_t RecordCountHint) {
|
||||
Count = 0;
|
||||
PartialOffsets = PartialOffsetArray();
|
||||
|
||||
BinaryStreamReader Reader(Data, support::little);
|
||||
error(Reader.readArray(Types, Reader.getLength()));
|
||||
error(Reader.readArray(Types, Reader.bytesRemaining()));
|
||||
|
||||
// Clear and then resize, to make sure existing data gets destroyed.
|
||||
Records.clear();
|
||||
Records.resize(RecordCountHint);
|
||||
}
|
||||
|
||||
void LazyRandomTypeCollection::reset(StringRef Data, uint32_t RecordCountHint) {
|
||||
BinaryStreamReader Reader(Data, support::little);
|
||||
reset(Reader, RecordCountHint);
|
||||
}
|
||||
|
||||
void LazyRandomTypeCollection::reset(ArrayRef<uint8_t> Data,
|
||||
uint32_t RecordCountHint) {
|
||||
reset(toStringRef(Data), RecordCountHint);
|
||||
BinaryStreamReader Reader(Data, support::little);
|
||||
reset(Reader, RecordCountHint);
|
||||
}
|
||||
|
||||
uint32_t LazyRandomTypeCollection::getOffsetOfType(TypeIndex Index) {
|
||||
|
50
test/DebugInfo/PDB/Inputs/obj-hashes-1.yaml
Normal file
50
test/DebugInfo/PDB/Inputs/obj-hashes-1.yaml
Normal file
@ -0,0 +1,50 @@
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_I386
|
||||
Characteristics: [ ]
|
||||
sections:
|
||||
- Name: '.debug$T'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
Types:
|
||||
# char**
|
||||
- Kind: LF_POINTER
|
||||
Pointer:
|
||||
ReferentType: 272
|
||||
Attrs: 32778
|
||||
# int**
|
||||
- Kind: LF_POINTER
|
||||
Pointer:
|
||||
ReferentType: 372
|
||||
Attrs: 32778
|
||||
# int***
|
||||
- Kind: LF_POINTER
|
||||
Pointer:
|
||||
ReferentType: 4097
|
||||
Attrs: 32778
|
||||
# (char**, int***)
|
||||
- Kind: LF_ARGLIST
|
||||
ArgList:
|
||||
ArgIndices: [ 4096, 4098 ]
|
||||
# int** (char**, int***)
|
||||
- Kind: LF_PROCEDURE
|
||||
Procedure:
|
||||
ReturnType: 4097
|
||||
CallConv: NearC
|
||||
Options: [ None ]
|
||||
ParameterCount: 2
|
||||
ArgumentList: 4099
|
||||
symbols:
|
||||
- Name: '.debug$T'
|
||||
Value: 0
|
||||
SectionNumber: 6
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 68
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 2189213922
|
||||
Number: 6
|
||||
...
|
55
test/DebugInfo/PDB/Inputs/obj-hashes-2.yaml
Normal file
55
test/DebugInfo/PDB/Inputs/obj-hashes-2.yaml
Normal file
@ -0,0 +1,55 @@
|
||||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_I386
|
||||
Characteristics: [ ]
|
||||
sections:
|
||||
- Name: '.debug$T'
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
Types:
|
||||
# int**
|
||||
- Kind: LF_POINTER
|
||||
Pointer:
|
||||
ReferentType: 372
|
||||
Attrs: 32778
|
||||
# int***
|
||||
- Kind: LF_POINTER
|
||||
Pointer:
|
||||
ReferentType: 4096
|
||||
Attrs: 32778
|
||||
# char**
|
||||
- Kind: LF_POINTER
|
||||
Pointer:
|
||||
ReferentType: 272
|
||||
Attrs: 32778
|
||||
# double**
|
||||
- Kind: LF_POINTER
|
||||
Pointer:
|
||||
ReferentType: 321
|
||||
Attrs: 32778
|
||||
# (char**, int***)
|
||||
- Kind: LF_ARGLIST
|
||||
ArgList:
|
||||
ArgIndices: [ 4098, 4097 ]
|
||||
# int** (char**, int***)
|
||||
- Kind: LF_PROCEDURE
|
||||
Procedure:
|
||||
ReturnType: 4096
|
||||
CallConv: NearC
|
||||
Options: [ None ]
|
||||
ParameterCount: 2
|
||||
ArgumentList: 4100
|
||||
symbols:
|
||||
- Name: '.debug$T'
|
||||
Value: 0
|
||||
SectionNumber: 6
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 68
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 2189213922
|
||||
Number: 6
|
||||
...
|
54
test/DebugInfo/PDB/obj-globalhash.test
Normal file
54
test/DebugInfo/PDB/obj-globalhash.test
Normal file
@ -0,0 +1,54 @@
|
||||
RUN: yaml2obj %p/Inputs/obj-hashes-1.yaml > %T/obj-hashes-1.obj
|
||||
RUN: yaml2obj %p/Inputs/obj-hashes-2.yaml > %T/obj-hashes-2.obj
|
||||
RUN: echo obj-hashes-1 > %T/hashes-combined.out
|
||||
RUN: llvm-pdbutil dump -type-extras %T/obj-hashes-1.obj >> %T/hashes-combined.out
|
||||
RUN: echo obj-hashes-2 >> %T/hashes-combined.out
|
||||
RUN: llvm-pdbutil dump -type-extras %T/obj-hashes-2.obj >> %T/hashes-combined.out
|
||||
RUN: cat %T/hashes-combined.out | FileCheck --check-prefix=CHECK-ONE %s
|
||||
RUN: cat %T/hashes-combined.out | FileCheck --check-prefix=CHECK-TWO %s
|
||||
RUN: cat %T/hashes-combined.out | FileCheck --check-prefix=CHECK-THREE %s
|
||||
RUN: cat %T/hashes-combined.out | FileCheck --check-prefix=CHECK-FOUR %s
|
||||
RUN: cat %T/hashes-combined.out | FileCheck --check-prefix=CHECK-FIVE %s
|
||||
RUN: cat %T/hashes-combined.out | FileCheck --check-prefix=CHECK-SIX %s
|
||||
|
||||
; char**. Both the local and global hashes should be the same, since the only
|
||||
; back-references are for simple types which have fixed indices.
|
||||
CHECK-ONE: obj-hashes-1
|
||||
CHECK-ONE: TI: 0x1001, LocalHash: 8C051421, GlobalHash: 8B2BA87CC27BF9D290A31A6070FA296AAA577E53
|
||||
CHECK-ONE: obj-hashes-2
|
||||
CHECK-ONE: TI: 0x1000, LocalHash: 8C051421, GlobalHash: 8B2BA87CC27BF9D290A31A6070FA296AAA577E53
|
||||
|
||||
; int**. Same as char**, both the local and global hashes should be the same.
|
||||
CHECK-TWO: obj-hashes-1
|
||||
CHECK-TWO: TI: 0x1000, LocalHash: 8A50855E, GlobalHash: 1522A98D88FAF71B618D97BCAC2B89A424EC4805
|
||||
CHECK-TWO: obj-hashes-2
|
||||
CHECK-TWO: TI: 0x1002, LocalHash: 8A50855E, GlobalHash: 1522A98D88FAF71B618D97BCAC2B89A424EC4805
|
||||
|
||||
; int***. Different local hashes, since the referent type (int**) is not at the
|
||||
; same TypeIndex in both streams. Same global hash, since they represent the
|
||||
; same record.
|
||||
CHECK-THREE: obj-hashes-1
|
||||
CHECK-THREE: TI: 0x1002, LocalHash: C1B0E34B, GlobalHash: EC11CE9F78D6BF61F8D913A9E2C98293782A7EB4
|
||||
CHECK-THREE: obj-hashes-2
|
||||
CHECK-THREE: TI: 0x1001, LocalHash: 813E462C, GlobalHash: EC11CE9F78D6BF61F8D913A9E2C98293782A7EB4
|
||||
|
||||
; arg list (char**, int***). Different local hashes, since the parameter types
|
||||
; both occur at different TypeIndices in their respective input streams. Same
|
||||
; global hash, since the global hash of all referenced types is the same in
|
||||
; both streams.
|
||||
CHECK-FOUR: obj-hashes-1
|
||||
CHECK-FOUR: TI: 0x1003, LocalHash: F9B7D117, GlobalHash: 1088AD64CEBC88D9E015058A159516AF20B79286
|
||||
CHECK-FOUR: obj-hashes-2
|
||||
CHECK-FOUR: TI: 0x1004, LocalHash: 29800A81, GlobalHash: 1088AD64CEBC88D9E015058A159516AF20B79286
|
||||
|
||||
; double**. This is only in stream 2, as a means to throw off the indexing.
|
||||
CHECK-FIVE: obj-hashes-1
|
||||
CHECK-FIVE: obj-hashes-2
|
||||
CHECK-FIVE: TI: 0x1003, LocalHash: A8EEF56D, GlobalHash: 7803BBDB2947EF46BEA2310D102BD08F68315506
|
||||
|
||||
; int** (char**, int***). For the same logic as described in previous records,
|
||||
; these two records have the same global hash but different local hashes.
|
||||
CHECK-SIX: obj-hashes-1
|
||||
CHECK-SIX: TI: 0x1004, LocalHash: 25FFC8CB, GlobalHash: 457ABCB8AB70407594B5D72BF471B6BDECC99BC9
|
||||
CHECK-SIX: obj-hashes-2
|
||||
CHECK-SIX: TI: 0x1005, LocalHash: F34B0F86, GlobalHash: 457ABCB8AB70407594B5D72BF471B6BDECC99BC9
|
@ -38,6 +38,7 @@
|
||||
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
|
||||
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeHashing.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
|
||||
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
|
||||
@ -50,8 +51,8 @@
|
||||
#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/RawError.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBExtras.h"
|
||||
@ -135,16 +136,23 @@ Error DumpOutputStyle::dump() {
|
||||
return EC;
|
||||
}
|
||||
|
||||
if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() ||
|
||||
opts::dump::DumpTypeExtras) {
|
||||
if (auto EC = dumpTpiStream(StreamTPI))
|
||||
return EC;
|
||||
}
|
||||
if (File.isObj()) {
|
||||
if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() ||
|
||||
opts::dump::DumpTypeExtras)
|
||||
if (auto EC = dumpTypesFromObjectFile())
|
||||
return EC;
|
||||
} else {
|
||||
if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() ||
|
||||
opts::dump::DumpTypeExtras) {
|
||||
if (auto EC = dumpTpiStream(StreamTPI))
|
||||
return EC;
|
||||
}
|
||||
|
||||
if (opts::dump::DumpIds || !opts::dump::DumpIdIndex.empty() ||
|
||||
opts::dump::DumpIdExtras) {
|
||||
if (auto EC = dumpTpiStream(StreamIPI))
|
||||
return EC;
|
||||
if (opts::dump::DumpIds || !opts::dump::DumpIdIndex.empty() ||
|
||||
opts::dump::DumpIdExtras) {
|
||||
if (auto EC = dumpTpiStream(StreamIPI))
|
||||
return EC;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts::dump::DumpGlobals) {
|
||||
@ -913,15 +921,17 @@ static void buildDepSet(LazyRandomTypeCollection &Types,
|
||||
}
|
||||
}
|
||||
|
||||
static void dumpFullTypeStream(LinePrinter &Printer,
|
||||
LazyRandomTypeCollection &Types,
|
||||
TpiStream &Stream, bool Bytes, bool Extras) {
|
||||
Printer.formatLine("Showing {0:N} records", Stream.getNumTypeRecords());
|
||||
uint32_t Width =
|
||||
NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());
|
||||
static void
|
||||
dumpFullTypeStream(LinePrinter &Printer, LazyRandomTypeCollection &Types,
|
||||
uint32_t NumHashBuckets,
|
||||
FixedStreamArray<support::ulittle32_t> HashValues,
|
||||
bool Bytes, bool Extras) {
|
||||
|
||||
Printer.formatLine("Showing {0:N} records", Types.size());
|
||||
uint32_t Width = NumDigits(TypeIndex::FirstNonSimpleIndex + Types.size());
|
||||
|
||||
MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types,
|
||||
Stream.getNumHashBuckets(), Stream.getHashValues());
|
||||
NumHashBuckets, HashValues);
|
||||
|
||||
if (auto EC = codeview::visitTypeStream(Types, V)) {
|
||||
Printer.formatLine("An error occurred dumping type records: {0}",
|
||||
@ -967,6 +977,55 @@ static void dumpPartialTypeStream(LinePrinter &Printer,
|
||||
}
|
||||
}
|
||||
|
||||
Error DumpOutputStyle::dumpTypesFromObjectFile() {
|
||||
LazyRandomTypeCollection Types(100);
|
||||
|
||||
for (const auto &S : getObj().sections()) {
|
||||
StringRef SectionName;
|
||||
if (auto EC = S.getName(SectionName))
|
||||
return errorCodeToError(EC);
|
||||
|
||||
if (SectionName != ".debug$T")
|
||||
continue;
|
||||
StringRef Contents;
|
||||
if (auto EC = S.getContents(Contents))
|
||||
return errorCodeToError(EC);
|
||||
|
||||
uint32_t Magic;
|
||||
BinaryStreamReader Reader(Contents, llvm::support::little);
|
||||
if (auto EC = Reader.readInteger(Magic))
|
||||
return EC;
|
||||
if (Magic != COFF::DEBUG_SECTION_MAGIC)
|
||||
return make_error<StringError>("Invalid CodeView debug section.",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
Types.reset(Reader, 100);
|
||||
|
||||
if (opts::dump::DumpTypes) {
|
||||
dumpFullTypeStream(P, Types, 0, {}, opts::dump::DumpTypeData, false);
|
||||
} else if (opts::dump::DumpTypeExtras) {
|
||||
auto LocalHashes = LocallyHashedType::hashTypeCollection(Types);
|
||||
auto GlobalHashes = GloballyHashedType::hashTypeCollection(Types);
|
||||
assert(LocalHashes.size() == GlobalHashes.size());
|
||||
|
||||
P.formatLine("Local / Global hashes:");
|
||||
TypeIndex TI(TypeIndex::FirstNonSimpleIndex);
|
||||
for (const auto &H : zip(LocalHashes, GlobalHashes)) {
|
||||
AutoIndent Indent2(P);
|
||||
LocallyHashedType &L = std::get<0>(H);
|
||||
GloballyHashedType &G = std::get<1>(H);
|
||||
|
||||
P.formatLine("TI: {0}, LocalHash: {1:X}, GlobalHash: {2}", TI, L, G);
|
||||
|
||||
++TI;
|
||||
}
|
||||
P.NewLine();
|
||||
}
|
||||
}
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
|
||||
assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);
|
||||
|
||||
@ -977,10 +1036,7 @@ Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
|
||||
}
|
||||
|
||||
AutoIndent Indent(P);
|
||||
if (File.isObj()) {
|
||||
P.formatLine("Dumping types is not supported for object files");
|
||||
return Error::success();
|
||||
}
|
||||
assert(!File.isObj());
|
||||
|
||||
bool Present = false;
|
||||
bool DumpTypes = false;
|
||||
@ -1017,7 +1073,8 @@ Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
|
||||
|
||||
if (DumpTypes || !Indices.empty()) {
|
||||
if (Indices.empty())
|
||||
dumpFullTypeStream(P, Types, Stream, DumpBytes, DumpExtras);
|
||||
dumpFullTypeStream(P, Types, Stream.getNumHashBuckets(),
|
||||
Stream.getHashValues(), DumpBytes, DumpExtras);
|
||||
else {
|
||||
std::vector<TypeIndex> TiList(Indices.begin(), Indices.end());
|
||||
dumpPartialTypeStream(P, Types, Stream, TiList, DumpBytes, DumpExtras,
|
||||
|
@ -80,6 +80,7 @@ private:
|
||||
Error dumpXmi();
|
||||
Error dumpXme();
|
||||
Error dumpTpiStream(uint32_t StreamIdx);
|
||||
Error dumpTypesFromObjectFile();
|
||||
Error dumpModules();
|
||||
Error dumpModuleFiles();
|
||||
Error dumpModuleSymsForPdb();
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
|
||||
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeHashing.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
|
||||
|
Loading…
Reference in New Issue
Block a user