aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/DebugInfo
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/DebugInfo')
-rw-r--r--include/llvm/DebugInfo/CodeView/ByteStream.h58
-rw-r--r--include/llvm/DebugInfo/CodeView/CVRecord.h56
-rw-r--r--include/llvm/DebugInfo/CodeView/CVSymbolTypes.def258
-rw-r--r--include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h103
-rw-r--r--include/llvm/DebugInfo/CodeView/CVTypeVisitor.h44
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeView.h509
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeViewError.h44
-rw-r--r--include/llvm/DebugInfo/CodeView/EnumTables.h42
-rw-r--r--include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h37
-rw-r--r--include/llvm/DebugInfo/CodeView/Line.h50
-rw-r--r--include/llvm/DebugInfo/CodeView/ListRecordBuilder.h22
-rw-r--r--include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h48
-rw-r--r--include/llvm/DebugInfo/CodeView/ModuleSubstream.h87
-rw-r--r--include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h121
-rw-r--r--include/llvm/DebugInfo/CodeView/RecordSerialization.h278
-rw-r--r--include/llvm/DebugInfo/CodeView/StreamArray.h275
-rw-r--r--include/llvm/DebugInfo/CodeView/StreamInterface.h55
-rw-r--r--include/llvm/DebugInfo/CodeView/StreamReader.h111
-rw-r--r--include/llvm/DebugInfo/CodeView/StreamRef.h104
-rw-r--r--include/llvm/DebugInfo/CodeView/StreamWriter.h86
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h37
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolDumper.h54
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolRecord.h1452
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h33
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDumper.h105
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeIndex.h76
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeRecord.h1024
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h17
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeRecords.def252
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeStreamMerger.h26
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h3
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeTableBuilder.h26
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h63
-rw-r--r--include/llvm/DebugInfo/DIContext.h5
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h6
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFContext.h17
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h1
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h6
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h1
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFFormValue.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h6
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFUnit.h18
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h11
-rw-r--r--include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h2
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIADataStream.h2
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h2
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h3
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h3
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h3
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIAError.h46
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIALineNumber.h3
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h8
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIASession.h33
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIASourceFile.h7
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIASupport.h11
-rw-r--r--include/llvm/DebugInfo/PDB/GenericError.h42
-rw-r--r--include/llvm/DebugInfo/PDB/IPDBDataStream.h2
-rw-r--r--include/llvm/DebugInfo/PDB/IPDBEnumChildren.h2
-rw-r--r--include/llvm/DebugInfo/PDB/IPDBLineNumber.h3
-rw-r--r--include/llvm/DebugInfo/PDB/IPDBRawSymbol.h11
-rw-r--r--include/llvm/DebugInfo/PDB/IPDBSession.h22
-rw-r--r--include/llvm/DebugInfo/PDB/IPDBSourceFile.h7
-rw-r--r--include/llvm/DebugInfo/PDB/PDB.h14
-rw-r--r--include/llvm/DebugInfo/PDB/PDBContext.h73
-rw-r--r--include/llvm/DebugInfo/PDB/PDBExtras.h9
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymDumper.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbol.h12
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h4
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolBlock.h5
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h7
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h4
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h4
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolCustom.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolData.h4
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolExe.h5
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolFunc.h4
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h4
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolLabel.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolThunk.h4
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h4
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBTypes.h272
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/DbiStream.h149
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h56
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/DirectoryStreamData.h37
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/EnumTables.h22
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/Hash.h25
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/IPDBFile.h44
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h38
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h28
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h34
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/InfoStream.h77
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h53
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h68
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/ModInfo.h79
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/ModStream.h57
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/MsfBuilder.h141
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/MsfCommon.h90
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/NameHashTable.h54
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/NameMap.h45
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h41
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/PDBFile.h113
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h59
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/PublicsStream.h74
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/RawConstants.h94
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/RawError.h49
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/RawSession.h75
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/RawTypes.h86
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/SymbolStream.h41
-rw-r--r--include/llvm/DebugInfo/PDB/Raw/TpiStream.h72
-rw-r--r--include/llvm/DebugInfo/Symbolize/DIPrinter.h2
-rw-r--r--include/llvm/DebugInfo/Symbolize/SymbolizableModule.h2
-rw-r--r--include/llvm/DebugInfo/Symbolize/Symbolize.h34
130 files changed, 7474 insertions, 696 deletions
diff --git a/include/llvm/DebugInfo/CodeView/ByteStream.h b/include/llvm/DebugInfo/CodeView/ByteStream.h
new file mode 100644
index 000000000000..f398c93723e7
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/ByteStream.h
@@ -0,0 +1,58 @@
+//===- ByteStream.h - Reads stream data from a byte sequence ----*- 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_CODEVIEW_BYTESTREAM_H
+#define LLVM_DEBUGINFO_CODEVIEW_BYTESTREAM_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/StreamInterface.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <memory>
+#include <type_traits>
+
+namespace llvm {
+namespace codeview {
+class StreamReader;
+
+template <bool Writable = false> class ByteStream : public StreamInterface {
+ typedef typename std::conditional<Writable, MutableArrayRef<uint8_t>,
+ ArrayRef<uint8_t>>::type ArrayType;
+
+public:
+ ByteStream() {}
+ explicit ByteStream(ArrayType Data) : Data(Data) {}
+ ~ByteStream() override {}
+
+ Error readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) const override;
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) const override;
+
+ Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
+
+ uint32_t getLength() const override;
+
+ Error commit() const override;
+
+ ArrayRef<uint8_t> data() const { return Data; }
+ StringRef str() const;
+
+private:
+ ArrayType Data;
+};
+
+extern template class ByteStream<true>;
+extern template class ByteStream<false>;
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_BYTESTREAM_H
diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h
new file mode 100644
index 000000000000..dba359fcbe82
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/CVRecord.h
@@ -0,0 +1,56 @@
+//===- RecordIterator.h -----------------------------------------*- 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_CODEVIEW_RECORDITERATOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/StreamInterface.h"
+#include "llvm/DebugInfo/CodeView/StreamReader.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace codeview {
+
+template <typename Kind> struct CVRecord {
+ uint32_t Length;
+ Kind Type;
+ ArrayRef<uint8_t> Data;
+ ArrayRef<uint8_t> RawData;
+};
+
+template <typename Kind> struct VarStreamArrayExtractor<CVRecord<Kind>> {
+ Error operator()(StreamRef Stream, uint32_t &Len,
+ CVRecord<Kind> &Item) const {
+ const RecordPrefix *Prefix = nullptr;
+ StreamReader Reader(Stream);
+ uint32_t Offset = Reader.getOffset();
+
+ if (auto EC = Reader.readObject(Prefix))
+ return EC;
+ Item.Length = Prefix->RecordLen;
+ if (Item.Length < 2)
+ return make_error<CodeViewError>(cv_error_code::corrupt_record);
+ Item.Type = static_cast<Kind>(uint16_t(Prefix->RecordKind));
+
+ Reader.setOffset(Offset);
+ if (auto EC =
+ Reader.readBytes(Item.RawData, Item.Length + sizeof(uint16_t)))
+ return EC;
+ Item.Data = Item.RawData.slice(sizeof(RecordPrefix));
+ Len = Prefix->RecordLen + 2;
+ return Error::success();
+ }
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def b/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def
new file mode 100644
index 000000000000..32813d861d90
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def
@@ -0,0 +1,258 @@
+//===-- CVLeafTypes.def - All CodeView leaf types ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// See LEAF_ENUM_e in cvinfo.h. This should match the constants there.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CV_SYMBOL
+#define CV_SYMBOL(ename, value)
+#endif
+
+#ifndef SYMBOL_RECORD
+#define SYMBOL_RECORD(lf_ename, value, name) CV_SYMBOL(lf_ename, value)
+#endif
+
+#ifndef SYMBOL_RECORD_ALIAS
+#define SYMBOL_RECORD_ALIAS(lf_ename, value, name, alias_name) \
+ SYMBOL_RECORD(lf_ename, value, name)
+#endif
+
+// 16 bit symbol types. Not very useful, provided only for reference.
+CV_SYMBOL(S_COMPILE , 0x0001)
+CV_SYMBOL(S_REGISTER_16t , 0x0002)
+CV_SYMBOL(S_CONSTANT_16t , 0x0003)
+CV_SYMBOL(S_UDT_16t , 0x0004)
+CV_SYMBOL(S_SSEARCH , 0x0005)
+CV_SYMBOL(S_SKIP , 0x0007)
+CV_SYMBOL(S_CVRESERVE , 0x0008)
+CV_SYMBOL(S_OBJNAME_ST , 0x0009)
+CV_SYMBOL(S_ENDARG , 0x000a)
+CV_SYMBOL(S_COBOLUDT_16t , 0x000b)
+CV_SYMBOL(S_MANYREG_16t , 0x000c)
+CV_SYMBOL(S_RETURN , 0x000d)
+CV_SYMBOL(S_ENTRYTHIS , 0x000e)
+CV_SYMBOL(S_BPREL16 , 0x0100)
+CV_SYMBOL(S_LDATA16 , 0x0101)
+CV_SYMBOL(S_GDATA16 , 0x0102)
+CV_SYMBOL(S_PUB16 , 0x0103)
+CV_SYMBOL(S_LPROC16 , 0x0104)
+CV_SYMBOL(S_GPROC16 , 0x0105)
+CV_SYMBOL(S_THUNK16 , 0x0106)
+CV_SYMBOL(S_BLOCK16 , 0x0107)
+CV_SYMBOL(S_WITH16 , 0x0108)
+CV_SYMBOL(S_LABEL16 , 0x0109)
+CV_SYMBOL(S_CEXMODEL16 , 0x010a)
+CV_SYMBOL(S_VFTABLE16 , 0x010b)
+CV_SYMBOL(S_REGREL16 , 0x010c)
+CV_SYMBOL(S_BPREL32_16t , 0x0200)
+CV_SYMBOL(S_LDATA32_16t , 0x0201)
+CV_SYMBOL(S_GDATA32_16t , 0x0202)
+CV_SYMBOL(S_PUB32_16t , 0x0203)
+CV_SYMBOL(S_LPROC32_16t , 0x0204)
+CV_SYMBOL(S_GPROC32_16t , 0x0205)
+CV_SYMBOL(S_THUNK32_ST , 0x0206)
+CV_SYMBOL(S_BLOCK32_ST , 0x0207)
+CV_SYMBOL(S_WITH32_ST , 0x0208)
+CV_SYMBOL(S_LABEL32_ST , 0x0209)
+CV_SYMBOL(S_CEXMODEL32 , 0x020a)
+CV_SYMBOL(S_VFTABLE32_16t , 0x020b)
+CV_SYMBOL(S_REGREL32_16t , 0x020c)
+CV_SYMBOL(S_LTHREAD32_16t , 0x020d)
+CV_SYMBOL(S_GTHREAD32_16t , 0x020e)
+CV_SYMBOL(S_SLINK32 , 0x020f)
+CV_SYMBOL(S_LPROCMIPS_16t , 0x0300)
+CV_SYMBOL(S_GPROCMIPS_16t , 0x0301)
+CV_SYMBOL(S_PROCREF_ST , 0x0400)
+CV_SYMBOL(S_DATAREF_ST , 0x0401)
+CV_SYMBOL(S_ALIGN , 0x0402)
+CV_SYMBOL(S_LPROCREF_ST , 0x0403)
+CV_SYMBOL(S_OEM , 0x0404)
+
+// All post 16 bit symbol types have the 0x1000 bit set.
+CV_SYMBOL(S_TI16_MAX , 0x1000)
+
+// Mostly unused "start" symbol types.
+CV_SYMBOL(S_REGISTER_ST , 0x1001)
+CV_SYMBOL(S_CONSTANT_ST , 0x1002)
+CV_SYMBOL(S_UDT_ST , 0x1003)
+CV_SYMBOL(S_COBOLUDT_ST , 0x1004)
+CV_SYMBOL(S_MANYREG_ST , 0x1005)
+CV_SYMBOL(S_BPREL32_ST , 0x1006)
+CV_SYMBOL(S_LDATA32_ST , 0x1007)
+CV_SYMBOL(S_GDATA32_ST , 0x1008)
+CV_SYMBOL(S_PUB32_ST , 0x1009)
+CV_SYMBOL(S_LPROC32_ST , 0x100a)
+CV_SYMBOL(S_GPROC32_ST , 0x100b)
+CV_SYMBOL(S_VFTABLE32 , 0x100c)
+CV_SYMBOL(S_REGREL32_ST , 0x100d)
+CV_SYMBOL(S_LTHREAD32_ST , 0x100e)
+CV_SYMBOL(S_GTHREAD32_ST , 0x100f)
+CV_SYMBOL(S_LPROCMIPS_ST , 0x1010)
+CV_SYMBOL(S_GPROCMIPS_ST , 0x1011)
+
+CV_SYMBOL(S_COMPILE2_ST , 0x1013)
+CV_SYMBOL(S_MANYREG2_ST , 0x1014)
+CV_SYMBOL(S_LPROCIA64_ST , 0x1015)
+CV_SYMBOL(S_GPROCIA64_ST , 0x1016)
+CV_SYMBOL(S_LOCALSLOT_ST , 0x1017)
+CV_SYMBOL(S_PARAMSLOT_ST , 0x1018)
+CV_SYMBOL(S_ANNOTATION , 0x1019)
+CV_SYMBOL(S_GMANPROC_ST , 0x101a)
+CV_SYMBOL(S_LMANPROC_ST , 0x101b)
+CV_SYMBOL(S_RESERVED1 , 0x101c)
+CV_SYMBOL(S_RESERVED2 , 0x101d)
+CV_SYMBOL(S_RESERVED3 , 0x101e)
+CV_SYMBOL(S_RESERVED4 , 0x101f)
+CV_SYMBOL(S_LMANDATA_ST , 0x1020)
+CV_SYMBOL(S_GMANDATA_ST , 0x1021)
+CV_SYMBOL(S_MANFRAMEREL_ST, 0x1022)
+CV_SYMBOL(S_MANREGISTER_ST, 0x1023)
+CV_SYMBOL(S_MANSLOT_ST , 0x1024)
+CV_SYMBOL(S_MANMANYREG_ST , 0x1025)
+CV_SYMBOL(S_MANREGREL_ST , 0x1026)
+CV_SYMBOL(S_MANMANYREG2_ST, 0x1027)
+CV_SYMBOL(S_MANTYPREF , 0x1028)
+CV_SYMBOL(S_UNAMESPACE_ST , 0x1029)
+
+// End of S_*_ST symbols, which do not appear to be generated by modern
+// compilers.
+CV_SYMBOL(S_ST_MAX , 0x1100)
+
+
+CV_SYMBOL(S_WITH32 , 0x1104)
+CV_SYMBOL(S_MANYREG , 0x110a)
+CV_SYMBOL(S_LPROCMIPS , 0x1114)
+CV_SYMBOL(S_GPROCMIPS , 0x1115)
+CV_SYMBOL(S_MANYREG2 , 0x1117)
+CV_SYMBOL(S_LPROCIA64 , 0x1118)
+CV_SYMBOL(S_GPROCIA64 , 0x1119)
+CV_SYMBOL(S_LOCALSLOT , 0x111a)
+CV_SYMBOL(S_PARAMSLOT , 0x111b)
+
+// Managed code symbols.
+CV_SYMBOL(S_MANFRAMEREL , 0x111e)
+CV_SYMBOL(S_MANREGISTER , 0x111f)
+CV_SYMBOL(S_MANSLOT , 0x1120)
+CV_SYMBOL(S_MANMANYREG , 0x1121)
+CV_SYMBOL(S_MANREGREL , 0x1122)
+CV_SYMBOL(S_MANMANYREG2 , 0x1123)
+CV_SYMBOL(S_UNAMESPACE , 0x1124)
+CV_SYMBOL(S_DATAREF , 0x1126)
+CV_SYMBOL(S_ANNOTATIONREF , 0x1128)
+CV_SYMBOL(S_TOKENREF , 0x1129)
+CV_SYMBOL(S_GMANPROC , 0x112a)
+CV_SYMBOL(S_LMANPROC , 0x112b)
+CV_SYMBOL(S_ATTR_FRAMEREL , 0x112e)
+CV_SYMBOL(S_ATTR_REGISTER , 0x112f)
+CV_SYMBOL(S_ATTR_REGREL , 0x1130)
+CV_SYMBOL(S_ATTR_MANYREG , 0x1131)
+
+
+CV_SYMBOL(S_SEPCODE , 0x1132)
+CV_SYMBOL(S_LOCAL_2005 , 0x1133)
+CV_SYMBOL(S_DEFRANGE_2005 , 0x1134)
+CV_SYMBOL(S_DEFRANGE2_2005, 0x1135)
+CV_SYMBOL(S_DISCARDED , 0x113b)
+
+// Current symbol types for most procedures as of this writing.
+CV_SYMBOL(S_LPROCMIPS_ID , 0x1148)
+CV_SYMBOL(S_GPROCMIPS_ID , 0x1149)
+CV_SYMBOL(S_LPROCIA64_ID , 0x114a)
+CV_SYMBOL(S_GPROCIA64_ID , 0x114b)
+
+CV_SYMBOL(S_DEFRANGE_HLSL , 0x1150)
+CV_SYMBOL(S_GDATA_HLSL , 0x1151)
+CV_SYMBOL(S_LDATA_HLSL , 0x1152)
+CV_SYMBOL(S_LOCAL_DPC_GROUPSHARED, 0x1154)
+CV_SYMBOL(S_DEFRANGE_DPC_PTR_TAG, 0x1157)
+CV_SYMBOL(S_DPC_SYM_TAG_MAP, 0x1158)
+CV_SYMBOL(S_ARMSWITCHTABLE , 0x1159)
+CV_SYMBOL(S_POGODATA , 0x115c)
+CV_SYMBOL(S_INLINESITE2 , 0x115d)
+CV_SYMBOL(S_MOD_TYPEREF , 0x115f)
+CV_SYMBOL(S_REF_MINIPDB , 0x1160)
+CV_SYMBOL(S_PDBMAP , 0x1161)
+CV_SYMBOL(S_GDATA_HLSL32 , 0x1162)
+CV_SYMBOL(S_LDATA_HLSL32 , 0x1163)
+CV_SYMBOL(S_GDATA_HLSL32_EX, 0x1164)
+CV_SYMBOL(S_LDATA_HLSL32_EX, 0x1165)
+
+// Known symbol types
+SYMBOL_RECORD(S_END , 0x0006, ScopeEndSym)
+SYMBOL_RECORD_ALIAS(S_INLINESITE_END , 0x114e, InlineSiteEnd, ScopeEndSym)
+SYMBOL_RECORD_ALIAS(S_PROC_ID_END , 0x114f, ProcEnd, ScopeEndSym)
+
+SYMBOL_RECORD(S_THUNK32 , 0x1102, Thunk32Sym)
+SYMBOL_RECORD(S_TRAMPOLINE , 0x112c, TrampolineSym)
+SYMBOL_RECORD(S_SECTION , 0x1136, SectionSym)
+SYMBOL_RECORD(S_COFFGROUP , 0x1137, CoffGroupSym)
+SYMBOL_RECORD(S_EXPORT , 0x1138, ExportSym)
+
+SYMBOL_RECORD(S_LPROC32 , 0x110f, ProcSym)
+SYMBOL_RECORD_ALIAS(S_GPROC32 , 0x1110, GlobalProcSym, ProcSym)
+SYMBOL_RECORD_ALIAS(S_LPROC32_ID , 0x1146, ProcIdSym, ProcSym)
+SYMBOL_RECORD_ALIAS(S_GPROC32_ID , 0x1147, GlobalProcIdSym, ProcSym)
+SYMBOL_RECORD_ALIAS(S_LPROC32_DPC , 0x1155, DPCProcSym, ProcSym)
+SYMBOL_RECORD_ALIAS(S_LPROC32_DPC_ID , 0x1156, DPCProcIdSym, ProcSym)
+
+SYMBOL_RECORD(S_REGISTER , 0x1106, RegisterSym)
+SYMBOL_RECORD(S_PUB32 , 0x110e, PublicSym32)
+
+SYMBOL_RECORD(S_PROCREF , 0x1125, ProcRefSym)
+SYMBOL_RECORD_ALIAS(S_LPROCREF, 0x1127, LocalProcRef, ProcRefSym)
+
+
+SYMBOL_RECORD(S_ENVBLOCK , 0x113d, EnvBlockSym)
+
+SYMBOL_RECORD(S_INLINESITE , 0x114d, InlineSiteSym)
+SYMBOL_RECORD(S_LOCAL , 0x113e, LocalSym)
+SYMBOL_RECORD(S_DEFRANGE , 0x113f, DefRangeSym)
+SYMBOL_RECORD(S_DEFRANGE_SUBFIELD, 0x1140, DefRangeSubfieldSym)
+SYMBOL_RECORD(S_DEFRANGE_REGISTER, 0x1141, DefRangeRegisterSym)
+SYMBOL_RECORD(S_DEFRANGE_FRAMEPOINTER_REL, 0x1142, DefRangeFramePointerRelSym)
+SYMBOL_RECORD(S_DEFRANGE_SUBFIELD_REGISTER, 0x1143, DefRangeSubfieldRegisterSym)
+SYMBOL_RECORD(S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE, 0x1144, DefRangeFramePointerRelFullScopeSym)
+SYMBOL_RECORD(S_DEFRANGE_REGISTER_REL, 0x1145, DefRangeRegisterRelSym)
+SYMBOL_RECORD(S_BLOCK32 , 0x1103, BlockSym)
+SYMBOL_RECORD(S_LABEL32 , 0x1105, LabelSym)
+SYMBOL_RECORD(S_OBJNAME , 0x1101, ObjNameSym)
+SYMBOL_RECORD(S_COMPILE2 , 0x1116, Compile2Sym)
+SYMBOL_RECORD(S_COMPILE3 , 0x113c, Compile3Sym)
+SYMBOL_RECORD(S_FRAMEPROC , 0x1012, FrameProcSym)
+SYMBOL_RECORD(S_CALLSITEINFO , 0x1139, CallSiteInfoSym)
+SYMBOL_RECORD(S_FILESTATIC , 0x1153, FileStaticSym)
+SYMBOL_RECORD(S_HEAPALLOCSITE , 0x115e, HeapAllocationSiteSym)
+SYMBOL_RECORD(S_FRAMECOOKIE , 0x113a, FrameCookieSym)
+
+SYMBOL_RECORD(S_CALLEES , 0x115a, CallerSym)
+SYMBOL_RECORD_ALIAS(S_CALLERS , 0x115b, CalleeSym, CallerSym)
+
+SYMBOL_RECORD(S_UDT , 0x1108, UDTSym)
+SYMBOL_RECORD_ALIAS(S_COBOLUDT , 0x1109, CobolUDT, UDTSym)
+
+SYMBOL_RECORD(S_BUILDINFO , 0x114c, BuildInfoSym)
+SYMBOL_RECORD(S_BPREL32 , 0x110b, BPRelativeSym)
+SYMBOL_RECORD(S_REGREL32 , 0x1111, RegRelativeSym)
+
+SYMBOL_RECORD(S_CONSTANT , 0x1107, ConstantSym)
+SYMBOL_RECORD_ALIAS(S_MANCONSTANT , 0x112d, ManagedConstant, ConstantSym)
+
+SYMBOL_RECORD(S_LDATA32 , 0x110c, DataSym)
+SYMBOL_RECORD_ALIAS(S_GDATA32 , 0x110d, GlobalData, DataSym)
+SYMBOL_RECORD_ALIAS(S_LMANDATA , 0x111c, ManagedLocalData, DataSym)
+SYMBOL_RECORD_ALIAS(S_GMANDATA , 0x111d, ManagedGlobalData, DataSym)
+
+SYMBOL_RECORD(S_LTHREAD32 , 0x1112, ThreadLocalDataSym)
+SYMBOL_RECORD_ALIAS(S_GTHREAD32 , 0x1113, GlobalTLS, ThreadLocalDataSym)
+
+
+#undef CV_SYMBOL
+#undef SYMBOL_RECORD
+#undef SYMBOL_RECORD_ALIAS
diff --git a/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h b/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
new file mode 100644
index 000000000000..7c88956c984e
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
@@ -0,0 +1,103 @@
+//===- CVSymbolVisitor.h ----------------------------------------*- 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_CODEVIEW_CVSYMBOLVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_CVSYMBOLVISITOR_H
+
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h"
+#include "llvm/Support/ErrorOr.h"
+
+namespace llvm {
+namespace codeview {
+
+template <typename Derived> class CVSymbolVisitor {
+public:
+ CVSymbolVisitor(SymbolVisitorDelegate *Delegate) : Delegate(Delegate) {}
+
+ bool hadError() const { return HadError; }
+
+ template <typename T>
+ bool consumeObject(ArrayRef<uint8_t> &Data, const T *&Res) {
+ if (Data.size() < sizeof(*Res)) {
+ HadError = true;
+ return false;
+ }
+ Res = reinterpret_cast<const T *>(Data.data());
+ Data = Data.drop_front(sizeof(*Res));
+ return true;
+ }
+
+/// Actions to take on known symbols. By default, they do nothing. Visit methods
+/// for member records take the FieldData by non-const reference and are
+/// expected to consume the trailing bytes used by the field.
+/// FIXME: Make the visitor interpret the trailing bytes so that clients don't
+/// need to.
+#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
+ void visit##Name(SymbolRecordKind Kind, Name &Record) {}
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "CVSymbolTypes.def"
+
+ void visitSymbolRecord(const CVRecord<SymbolKind> &Record) {
+ ArrayRef<uint8_t> Data = Record.Data;
+ auto *DerivedThis = static_cast<Derived *>(this);
+ DerivedThis->visitSymbolBegin(Record.Type, Data);
+ uint32_t RecordOffset = Delegate ? Delegate->getRecordOffset(Data) : 0;
+ switch (Record.Type) {
+ default:
+ DerivedThis->visitUnknownSymbol(Record.Type, Data);
+ break;
+#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
+ case EnumName: { \
+ SymbolRecordKind RK = static_cast<SymbolRecordKind>(EnumName); \
+ auto Result = Name::deserialize(RK, RecordOffset, Data); \
+ if (Result.getError()) \
+ return parseError(); \
+ DerivedThis->visit##Name(Record.Type, *Result); \
+ break; \
+ }
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
+ SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
+#include "CVSymbolTypes.def"
+ }
+ DerivedThis->visitSymbolEnd(Record.Type, Record.Data);
+ }
+
+ /// Visits the symbol records in Data. Sets the error flag on parse failures.
+ void visitSymbolStream(const CVSymbolArray &Symbols) {
+ for (const auto &I : Symbols) {
+ visitSymbolRecord(I);
+ if (hadError())
+ break;
+ }
+ }
+
+ /// Action to take on unknown symbols. By default, they are ignored.
+ void visitUnknownSymbol(SymbolKind Kind, ArrayRef<uint8_t> Data) {}
+
+ /// Paired begin/end actions for all symbols. Receives all record data,
+ /// including the fixed-length record prefix.
+ void visitSymbolBegin(SymbolKind Leaf, ArrayRef<uint8_t> RecordData) {}
+ void visitSymbolEnd(SymbolKind Leaf, ArrayRef<uint8_t> OriginalSymData) {}
+
+ /// Helper for returning from a void function when the stream is corrupted.
+ void parseError() { HadError = true; }
+
+private:
+ SymbolVisitorDelegate *Delegate;
+ /// Whether a symbol stream parsing error was encountered.
+ bool HadError = false;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_CVSYMBOLVISITOR_H
diff --git a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
new file mode 100644
index 000000000000..930ac6930c24
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
@@ -0,0 +1,44 @@
+//===- CVTypeVisitor.h ------------------------------------------*- 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_CODEVIEW_CVTYPEVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H
+
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+class CVTypeVisitor {
+public:
+ explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
+
+ Error visitTypeRecord(const CVRecord<TypeLeafKind> &Record);
+
+ /// Visits the type records in Data. Sets the error flag on parse failures.
+ Error visitTypeStream(const CVTypeArray &Types);
+
+ Error skipPadding(ArrayRef<uint8_t> &Data);
+
+ /// Visits individual member records of a field list record. Member records do
+ /// not describe their own length, and need special handling.
+ Error visitFieldList(const CVRecord<TypeLeafKind> &Record);
+
+private:
+ /// The interface to the class that gets notified of each visitation.
+ TypeVisitorCallbacks &Callbacks;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H
diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h
index 7728120d68de..1ee203b4f8fa 100644
--- a/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -11,10 +11,156 @@
#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H
#include <cinttypes>
+#include <type_traits>
namespace llvm {
namespace codeview {
+/// Distinguishes individual records in .debug$T section or PDB type stream. The
+/// documentation and headers talk about this as the "leaf" type.
+enum class TypeRecordKind : uint16_t {
+#define TYPE_RECORD(lf_ename, value, name) name = value,
+#include "TypeRecords.def"
+ // FIXME: Add serialization support
+ FieldList = 0x1203,
+};
+
+/// Duplicate copy of the above enum, but using the official CV names. Useful
+/// for reference purposes and when dealing with unknown record types.
+enum TypeLeafKind : uint16_t {
+#define CV_TYPE(name, val) name = val,
+#include "TypeRecords.def"
+};
+
+/// Distinguishes individual records in the Symbols subsection of a .debug$S
+/// section. Equivalent to SYM_ENUM_e in cvinfo.h.
+enum class SymbolRecordKind : uint16_t {
+#define SYMBOL_RECORD(lf_ename, value, name) name = value,
+#include "CVSymbolTypes.def"
+};
+
+/// Duplicate copy of the above enum, but using the official CV names. Useful
+/// for reference purposes and when dealing with unknown record types.
+enum SymbolKind : uint16_t {
+#define CV_SYMBOL(name, val) name = val,
+#include "CVSymbolTypes.def"
+};
+
+#define CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(Class) \
+ inline Class operator|(Class a, Class b) { \
+ return static_cast<Class>( \
+ static_cast<std::underlying_type<Class>::type>(a) | \
+ static_cast<std::underlying_type<Class>::type>(b)); \
+ } \
+ inline Class operator&(Class a, Class b) { \
+ return static_cast<Class>( \
+ static_cast<std::underlying_type<Class>::type>(a) & \
+ static_cast<std::underlying_type<Class>::type>(b)); \
+ } \
+ inline Class operator~(Class a) { \
+ return static_cast<Class>( \
+ ~static_cast<std::underlying_type<Class>::type>(a)); \
+ } \
+ inline Class &operator|=(Class &a, Class b) { \
+ a = a | b; \
+ return a; \
+ } \
+ inline Class &operator&=(Class &a, Class b) { \
+ a = a & b; \
+ return a; \
+ }
+
+/// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented
+/// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
+enum class CPUType : uint16_t {
+ Intel8080 = 0x0,
+ Intel8086 = 0x1,
+ Intel80286 = 0x2,
+ Intel80386 = 0x3,
+ Intel80486 = 0x4,
+ Pentium = 0x5,
+ PentiumPro = 0x6,
+ Pentium3 = 0x7,
+ MIPS = 0x10,
+ MIPS16 = 0x11,
+ MIPS32 = 0x12,
+ MIPS64 = 0x13,
+ MIPSI = 0x14,
+ MIPSII = 0x15,
+ MIPSIII = 0x16,
+ MIPSIV = 0x17,
+ MIPSV = 0x18,
+ M68000 = 0x20,
+ M68010 = 0x21,
+ M68020 = 0x22,
+ M68030 = 0x23,
+ M68040 = 0x24,
+ Alpha = 0x30,
+ Alpha21164 = 0x31,
+ Alpha21164A = 0x32,
+ Alpha21264 = 0x33,
+ Alpha21364 = 0x34,
+ PPC601 = 0x40,
+ PPC603 = 0x41,
+ PPC604 = 0x42,
+ PPC620 = 0x43,
+ PPCFP = 0x44,
+ PPCBE = 0x45,
+ SH3 = 0x50,
+ SH3E = 0x51,
+ SH3DSP = 0x52,
+ SH4 = 0x53,
+ SHMedia = 0x54,
+ ARM3 = 0x60,
+ ARM4 = 0x61,
+ ARM4T = 0x62,
+ ARM5 = 0x63,
+ ARM5T = 0x64,
+ ARM6 = 0x65,
+ ARM_XMAC = 0x66,
+ ARM_WMMX = 0x67,
+ ARM7 = 0x68,
+ Omni = 0x70,
+ Ia64 = 0x80,
+ Ia64_2 = 0x81,
+ CEE = 0x90,
+ AM33 = 0xa0,
+ M32R = 0xb0,
+ TriCore = 0xc0,
+ X64 = 0xd0,
+ EBC = 0xe0,
+ Thumb = 0xf0,
+ ARMNT = 0xf4,
+ D3D11_Shader = 0x100,
+};
+
+/// These values correspond to the CV_CFL_LANG enumeration, and are documented
+/// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx
+enum SourceLanguage : uint8_t {
+ C = 0x00,
+ Cpp = 0x01,
+ Fortran = 0x02,
+ Masm = 0x03,
+ Pascal = 0x04,
+ Basic = 0x05,
+ Cobol = 0x06,
+ Link = 0x07,
+ Cvtres = 0x08,
+ Cvtpgd = 0x09,
+ CSharp = 0x0a,
+ VB = 0x0b,
+ ILAsm = 0x0c,
+ Java = 0x0d,
+ JScript = 0x0e,
+ MSIL = 0x0f,
+ HLSL = 0x10
+};
+
+/// These values correspond to the CV_call_e enumeration, and are documented
+/// at the following locations:
+/// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
+/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx
+///
enum class CallingConvention : uint8_t {
NearC = 0x00, // near right to left push, caller pops stack
FarC = 0x01, // far right to left push, caller pops stack
@@ -58,20 +204,7 @@ enum class ClassOptions : uint16_t {
Sealed = 0x0400,
Intrinsic = 0x2000
};
-
-inline ClassOptions operator|(ClassOptions a, ClassOptions b) {
- return static_cast<ClassOptions>(static_cast<uint16_t>(a) |
- static_cast<uint16_t>(b));
-}
-
-inline ClassOptions operator&(ClassOptions a, ClassOptions b) {
- return static_cast<ClassOptions>(static_cast<uint16_t>(a) &
- static_cast<uint16_t>(b));
-}
-
-inline ClassOptions operator~(ClassOptions a) {
- return static_cast<ClassOptions>(~static_cast<uint16_t>(a));
-}
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ClassOptions)
enum class FrameProcedureOptions : uint32_t {
None = 0x00000000,
@@ -95,22 +228,7 @@ enum class FrameProcedureOptions : uint32_t {
GuardCfg = 0x00200000,
GuardCfw = 0x00400000
};
-
-inline FrameProcedureOptions operator|(FrameProcedureOptions a,
- FrameProcedureOptions b) {
- return static_cast<FrameProcedureOptions>(static_cast<uint32_t>(a) |
- static_cast<uint32_t>(b));
-}
-
-inline FrameProcedureOptions operator&(FrameProcedureOptions a,
- FrameProcedureOptions b) {
- return static_cast<FrameProcedureOptions>(static_cast<uint32_t>(a) &
- static_cast<uint32_t>(b));
-}
-
-inline FrameProcedureOptions operator~(FrameProcedureOptions a) {
- return static_cast<FrameProcedureOptions>(~static_cast<uint32_t>(a));
-}
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(FrameProcedureOptions)
enum class FunctionOptions : uint8_t {
None = 0x00,
@@ -118,20 +236,7 @@ enum class FunctionOptions : uint8_t {
Constructor = 0x02,
ConstructorWithVirtualBases = 0x04
};
-
-inline FunctionOptions operator|(FunctionOptions a, FunctionOptions b) {
- return static_cast<FunctionOptions>(static_cast<uint8_t>(a) |
- static_cast<uint8_t>(b));
-}
-
-inline FunctionOptions operator&(FunctionOptions a, FunctionOptions b) {
- return static_cast<FunctionOptions>(static_cast<uint8_t>(a) &
- static_cast<uint8_t>(b));
-}
-
-inline FunctionOptions operator~(FunctionOptions a) {
- return static_cast<FunctionOptions>(~static_cast<uint8_t>(a));
-}
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(FunctionOptions)
enum class HfaKind : uint8_t {
None = 0x00,
@@ -140,6 +245,7 @@ enum class HfaKind : uint8_t {
Other = 0x03
};
+/// Source-level access specifier. (CV_access_e)
enum class MemberAccess : uint8_t {
None = 0,
Private = 1,
@@ -147,6 +253,7 @@ enum class MemberAccess : uint8_t {
Public = 3
};
+/// Part of member attribute flags. (CV_methodprop_e)
enum class MethodKind : uint8_t {
Vanilla = 0x00,
Virtual = 0x01,
@@ -157,49 +264,30 @@ enum class MethodKind : uint8_t {
PureIntroducingVirtual = 0x06
};
+/// Equivalent to CV_fldattr_t bitfield.
enum class MethodOptions : uint16_t {
None = 0x0000,
+ AccessMask = 0x0003,
+ MethodKindMask = 0x001c,
Pseudo = 0x0020,
+ NoInherit = 0x0040,
+ NoConstruct = 0x0080,
CompilerGenerated = 0x0100,
Sealed = 0x0200
};
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions)
-inline MethodOptions operator|(MethodOptions a, MethodOptions b) {
- return static_cast<MethodOptions>(static_cast<uint16_t>(a) |
- static_cast<uint16_t>(b));
-}
-
-inline MethodOptions operator&(MethodOptions a, MethodOptions b) {
- return static_cast<MethodOptions>(static_cast<uint16_t>(a) &
- static_cast<uint16_t>(b));
-}
-
-inline MethodOptions operator~(MethodOptions a) {
- return static_cast<MethodOptions>(~static_cast<uint16_t>(a));
-}
-
+/// Equivalent to CV_modifier_t.
enum class ModifierOptions : uint16_t {
None = 0x0000,
Const = 0x0001,
Volatile = 0x0002,
Unaligned = 0x0004
};
-
-inline ModifierOptions operator|(ModifierOptions a, ModifierOptions b) {
- return static_cast<ModifierOptions>(static_cast<uint16_t>(a) |
- static_cast<uint16_t>(b));
-}
-
-inline ModifierOptions operator&(ModifierOptions a, ModifierOptions b) {
- return static_cast<ModifierOptions>(static_cast<uint16_t>(a) &
- static_cast<uint16_t>(b));
-}
-
-inline ModifierOptions operator~(ModifierOptions a) {
- return static_cast<ModifierOptions>(~static_cast<uint16_t>(a));
-}
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ModifierOptions)
enum class ModuleSubstreamKind : uint32_t {
+ None = 0,
Symbols = 0xf1,
Lines = 0xf2,
StringTable = 0xf3,
@@ -207,9 +295,18 @@ enum class ModuleSubstreamKind : uint32_t {
FrameData = 0xf5,
InlineeLines = 0xf6,
CrossScopeImports = 0xf7,
- CrossScopeExports = 0xf8
+ CrossScopeExports = 0xf8,
+
+ // These appear to relate to .Net assembly info.
+ ILLines = 0xf9,
+ FuncMDTokenMap = 0xfa,
+ TypeMDTokenMap = 0xfb,
+ MergedAssemblyInput = 0xfc,
+
+ CoffSymbolRVA = 0xfd,
};
+/// Equivalent to CV_ptrtype_e.
enum class PointerKind : uint8_t {
Near16 = 0x00, // 16 bit pointer
Far16 = 0x01, // 16:16 far pointer
@@ -226,6 +323,7 @@ enum class PointerKind : uint8_t {
Near64 = 0x0c // 64 bit pointer
};
+/// Equivalent to CV_ptrmode_e.
enum class PointerMode : uint8_t {
Pointer = 0x00, // "normal" pointer
LValueReference = 0x01, // "old" reference
@@ -234,6 +332,7 @@ enum class PointerMode : uint8_t {
RValueReference = 0x04 // r-value reference
};
+/// Equivalent to misc lfPointerAttr bitfields.
enum class PointerOptions : uint32_t {
None = 0x00000000,
Flat32 = 0x00000100,
@@ -243,21 +342,9 @@ enum class PointerOptions : uint32_t {
Restrict = 0x00001000,
WinRTSmartPointer = 0x00080000
};
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PointerOptions)
-inline PointerOptions operator|(PointerOptions a, PointerOptions b) {
- return static_cast<PointerOptions>(static_cast<uint16_t>(a) |
- static_cast<uint16_t>(b));
-}
-
-inline PointerOptions operator&(PointerOptions a, PointerOptions b) {
- return static_cast<PointerOptions>(static_cast<uint16_t>(a) &
- static_cast<uint16_t>(b));
-}
-
-inline PointerOptions operator~(PointerOptions a) {
- return static_cast<PointerOptions>(~static_cast<uint16_t>(a));
-}
-
+/// Equivalent to CV_pmtype_e.
enum class PointerToMemberRepresentation : uint16_t {
Unknown = 0x00, // not specified (pre VC8)
SingleInheritanceData = 0x01, // member data, single inheritance
@@ -270,82 +357,7 @@ enum class PointerToMemberRepresentation : uint16_t {
GeneralFunction = 0x08 // member function, most general
};
-enum class TypeRecordKind : uint16_t {
- None = 0,
-
- VirtualTableShape = 0x000a,
- Label = 0x000e,
- EndPrecompiledHeader = 0x0014,
-
- Modifier = 0x1001,
- Pointer = 0x1002,
- Procedure = 0x1008,
- MemberFunction = 0x1009,
-
- Oem = 0x100f,
- Oem2 = 0x1011,
-
- ArgumentList = 0x1201,
- FieldList = 0x1203,
- BitField = 0x1205,
- MethodList = 0x1206,
-
- BaseClass = 0x1400,
- VirtualBaseClass = 0x1401,
- IndirectVirtualBaseClass = 0x1402,
- Index = 0x1404,
- VirtualFunctionTablePointer = 0x1409,
-
- Enumerate = 0x1502,
- Array = 0x1503,
- Class = 0x1504,
- Structure = 0x1505,
- Union = 0x1506,
- Enum = 0x1507,
- Alias = 0x150a,
- Member = 0x150d,
- StaticMember = 0x150e,
- Method = 0x150f,
- NestedType = 0x1510,
- OneMethod = 0x1511,
- VirtualFunctionTable = 0x151d,
-
- FunctionId = 0x1601,
- MemberFunctionId = 0x1602,
- BuildInfo = 0x1603,
- SubstringList = 0x1604,
- StringId = 0x1605,
- UdtSourceLine = 0x1606,
-
- SByte = 0x8000,
- Int16 = 0x8001,
- UInt16 = 0x8002,
- Int32 = 0x8003,
- UInt32 = 0x8004,
- Single = 0x8005,
- Double = 0x8006,
- Float80 = 0x8007,
- Float128 = 0x8008,
- Int64 = 0x8009,
- UInt64 = 0x800a,
- Float48 = 0x800b,
- Complex32 = 0x800c,
- Complex64 = 0x800d,
- Complex80 = 0x800e,
- Complex128 = 0x800f,
- VarString = 0x8010,
-
- Int128 = 0x8017,
- UInt128 = 0x8018,
-
- Decimal = 0x8019,
- Date = 0x801a,
- Utf8String = 0x801b,
-
- Float16 = 0x801c
-};
-
-enum class VirtualTableSlotKind : uint8_t {
+enum class VFTableSlotKind : uint8_t {
Near16 = 0x00,
Far16 = 0x01,
This = 0x02,
@@ -361,6 +373,177 @@ enum class WindowsRTClassKind : uint8_t {
ValueClass = 0x02,
Interface = 0x03
};
+
+/// Corresponds to CV_LVARFLAGS bitfield.
+enum class LocalSymFlags : uint16_t {
+ None = 0,
+ IsParameter = 1 << 0,
+ IsAddressTaken = 1 << 1,
+ IsCompilerGenerated = 1 << 2,
+ IsAggregate = 1 << 3,
+ IsAggregated = 1 << 4,
+ IsAliased = 1 << 5,
+ IsAlias = 1 << 6,
+ IsReturnValue = 1 << 7,
+ IsOptimizedOut = 1 << 8,
+ IsEnregisteredGlobal = 1 << 9,
+ IsEnregisteredStatic = 1 << 10,
+};
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(LocalSymFlags)
+
+/// Corresponds to the CV_PROCFLAGS bitfield.
+enum class ProcSymFlags : uint8_t {
+ None = 0,
+ HasFP = 1 << 0,
+ HasIRET = 1 << 1,
+ HasFRET = 1 << 2,
+ IsNoReturn = 1 << 3,
+ IsUnreachable = 1 << 4,
+ HasCustomCallingConv = 1 << 5,
+ IsNoInline = 1 << 6,
+ HasOptimizedDebugInfo = 1 << 7,
+};
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ProcSymFlags)
+
+/// Corresponds to COMPILESYM2::Flags bitfield.
+enum class CompileSym2Flags : uint32_t {
+ EC = 1 << 8,
+ NoDbgInfo = 1 << 9,
+ LTCG = 1 << 10,
+ NoDataAlign = 1 << 11,
+ ManagedPresent = 1 << 12,
+ SecurityChecks = 1 << 13,
+ HotPatch = 1 << 14,
+ CVTCIL = 1 << 15,
+ MSILModule = 1 << 16,
+};
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym2Flags)
+
+/// Corresponds to COMPILESYM3::Flags bitfield.
+enum class CompileSym3Flags : uint32_t {
+ EC = 1 << 8,
+ NoDbgInfo = 1 << 9,
+ LTCG = 1 << 10,
+ NoDataAlign = 1 << 11,
+ ManagedPresent = 1 << 12,
+ SecurityChecks = 1 << 13,
+ HotPatch = 1 << 14,
+ CVTCIL = 1 << 15,
+ MSILModule = 1 << 16,
+ Sdl = 1 << 17,
+ PGO = 1 << 18,
+ Exp = 1 << 19,
+};
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym3Flags)
+
+enum class ExportFlags : uint16_t {
+ IsConstant = 1 << 0,
+ IsData = 1 << 1,
+ IsPrivate = 1 << 2,
+ HasNoName = 1 << 3,
+ HasExplicitOrdinal = 1 << 4,
+ IsForwarder = 1 << 5
+};
+CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ExportFlags)
+
+// Corresponds to BinaryAnnotationOpcode enum.
+enum class BinaryAnnotationsOpCode : uint32_t {
+ Invalid,
+ CodeOffset,
+ ChangeCodeOffsetBase,
+ ChangeCodeOffset,
+ ChangeCodeLength,
+ ChangeFile,
+ ChangeLineOffset,
+ ChangeLineEndDelta,
+ ChangeRangeKind,
+ ChangeColumnStart,
+ ChangeColumnEndDelta,
+ ChangeCodeOffsetAndLineOffset,
+ ChangeCodeLengthAndCodeOffset,
+ ChangeColumnEnd,
+};
+
+// Corresponds to CV_cookietype_e enum.
+enum class FrameCookieKind : uint8_t {
+ Copy,
+ XorStackPointer,
+ XorFramePointer,
+ XorR13,
+};
+
+// Corresponds to CV_HREG_e enum.
+enum class RegisterId : uint16_t {
+ Unknown = 0,
+ VFrame = 30006,
+ AL = 1,
+ CL = 2,
+ DL = 3,
+ BL = 4,
+ AH = 5,
+ CH = 6,
+ DH = 7,
+ BH = 8,
+ AX = 9,
+ CX = 10,
+ DX = 11,
+ BX = 12,
+ SP = 13,
+ BP = 14,
+ SI = 15,
+ DI = 16,
+ EAX = 17,
+ ECX = 18,
+ EDX = 19,
+ EBX = 20,
+ ESP = 21,
+ EBP = 22,
+ ESI = 23,
+ EDI = 24,
+ ES = 25,
+ CS = 26,
+ SS = 27,
+ DS = 28,
+ FS = 29,
+ GS = 30,
+ IP = 31,
+ RAX = 328,
+ RBX = 329,
+ RCX = 330,
+ RDX = 331,
+ RSI = 332,
+ RDI = 333,
+ RBP = 334,
+ RSP = 335,
+ R8 = 336,
+ R9 = 337,
+ R10 = 338,
+ R11 = 339,
+ R12 = 340,
+ R13 = 341,
+ R14 = 342,
+ R15 = 343,
+};
+
+/// These values correspond to the THUNK_ORDINAL enumeration.
+enum class ThunkOrdinal {
+ Standard,
+ ThisAdjustor,
+ Vcall,
+ Pcode,
+ UnknownLoad,
+ TrampIncremental,
+ BranchIsland
+};
+
+enum class TrampolineType { TrampIncremental, BranchIsland };
+
+// These values correspond to the CV_SourceChksum_t enumeration.
+enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 };
+
+enum LineFlags : uint32_t {
+ HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
+};
}
}
diff --git a/include/llvm/DebugInfo/CodeView/CodeViewError.h b/include/llvm/DebugInfo/CodeView/CodeViewError.h
new file mode 100644
index 000000000000..69ff29aab6f1
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/CodeViewError.h
@@ -0,0 +1,44 @@
+//===- CodeViewError.h - Error extensions for CodeView ----------*- 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_CODEVIEW_CODEVIEWERROR_H
+#define LLVM_DEBUGINFO_PDB_CODEVIEW_CODEVIEWERROR_H
+
+#include "llvm/Support/Error.h"
+
+#include <string>
+
+namespace llvm {
+namespace codeview {
+enum class cv_error_code {
+ unspecified = 1,
+ insufficient_buffer,
+ operation_unsupported,
+ corrupt_record,
+};
+
+/// Base class for errors originating when parsing raw PDB files
+class CodeViewError : public ErrorInfo<CodeViewError> {
+public:
+ static char ID;
+ CodeViewError(cv_error_code C);
+ CodeViewError(const std::string &Context);
+ CodeViewError(cv_error_code C, const std::string &Context);
+
+ void log(raw_ostream &OS) const override;
+ const std::string &getErrorMessage() const;
+ std::error_code convertToErrorCode() const override;
+
+private:
+ std::string ErrMsg;
+ cv_error_code Code;
+};
+}
+}
+#endif
diff --git a/include/llvm/DebugInfo/CodeView/EnumTables.h b/include/llvm/DebugInfo/CodeView/EnumTables.h
new file mode 100644
index 000000000000..021288e57618
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/EnumTables.h
@@ -0,0 +1,42 @@
+//===- EnumTables.h Enum to string conversion tables ------------*- 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_CODEVIEW_ENUMTABLES_H
+#define LLVM_DEBUGINFO_CODEVIEW_ENUMTABLES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+#include <stdint.h>
+
+namespace llvm {
+namespace codeview {
+ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames();
+ArrayRef<EnumEntry<uint16_t>> getRegisterNames();
+ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames();
+ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames();
+ArrayRef<EnumEntry<uint8_t>> getFrameCookieKindNames();
+ArrayRef<EnumEntry<SourceLanguage>> getSourceLanguageNames();
+ArrayRef<EnumEntry<uint32_t>> getCompileSym2FlagNames();
+ArrayRef<EnumEntry<uint32_t>> getCompileSym3FlagNames();
+ArrayRef<EnumEntry<uint32_t>> getFileChecksumNames();
+ArrayRef<EnumEntry<unsigned>> getCPUTypeNames();
+ArrayRef<EnumEntry<uint32_t>> getFrameProcSymFlagNames();
+ArrayRef<EnumEntry<uint16_t>> getExportSymFlagNames();
+ArrayRef<EnumEntry<uint32_t>> getModuleSubstreamKindNames();
+ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames();
+ArrayRef<EnumEntry<uint16_t>> getTrampolineNames();
+ArrayRef<EnumEntry<COFF::SectionCharacteristics>>
+getImageSectionCharacteristicNames();
+} // namespace codeview
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_ENUMTABLES_H
diff --git a/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h b/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h
index 1ed62487aecc..75a075157d22 100644
--- a/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h
+++ b/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h
@@ -11,6 +11,7 @@
#define LLVM_DEBUGINFO_CODEVIEW_FIELDLISTRECORDBUILDER_H
#include "llvm/DebugInfo/CodeView/ListRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
namespace llvm {
namespace codeview {
@@ -46,31 +47,17 @@ private:
public:
FieldListRecordBuilder();
- void writeBaseClass(MemberAccess Access, TypeIndex Type, uint64_t Offset);
- void writeEnumerate(MemberAccess Access, uint64_t Value, StringRef Name);
- void writeIndirectVirtualBaseClass(MemberAccess Access, TypeIndex Type,
- TypeIndex VirtualBasePointerType,
- int64_t VirtualBasePointerOffset,
- uint64_t SlotIndex);
- void writeMember(MemberAccess Access, TypeIndex Type, uint64_t Offset,
- StringRef Name);
- void writeOneMethod(MemberAccess Access, MethodKind Kind,
- MethodOptions Options, TypeIndex Type,
- int32_t VTableSlotOffset, StringRef Name);
- void writeOneMethod(const MethodInfo &Method, StringRef Name);
- void writeMethod(uint16_t OverloadCount, TypeIndex MethodList,
- StringRef Name);
- void writeNestedType(TypeIndex Type, StringRef Name);
- void writeStaticMember(MemberAccess Access, TypeIndex Type, StringRef Name);
- void writeVirtualBaseClass(MemberAccess Access, TypeIndex Type,
- TypeIndex VirtualBasePointerType,
- int64_t VirtualBasePointerOffset,
- uint64_t SlotIndex);
- void writeVirtualBaseClass(TypeRecordKind Kind, MemberAccess Access,
- TypeIndex Type, TypeIndex VirtualBasePointerType,
- int64_t VirtualBasePointerOffset,
- uint64_t SlotIndex);
- void writeVirtualFunctionTablePointer(TypeIndex Type);
+ void reset() { ListRecordBuilder::reset(); }
+
+ void writeBaseClass(const BaseClassRecord &Record);
+ void writeEnumerator(const EnumeratorRecord &Record);
+ void writeDataMember(const DataMemberRecord &Record);
+ void writeOneMethod(const OneMethodRecord &Record);
+ void writeOverloadedMethod(const OverloadedMethodRecord &Record);
+ void writeNestedType(const NestedTypeRecord &Record);
+ void writeStaticDataMember(const StaticDataMemberRecord &Record);
+ void writeVirtualBaseClass(const VirtualBaseClassRecord &Record);
+ void writeVFPtr(const VFPtrRecord &Type);
};
}
}
diff --git a/include/llvm/DebugInfo/CodeView/Line.h b/include/llvm/DebugInfo/CodeView/Line.h
index a7cdbdaac32f..975b503fe30b 100644
--- a/include/llvm/DebugInfo/CodeView/Line.h
+++ b/include/llvm/DebugInfo/CodeView/Line.h
@@ -10,24 +10,32 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_LINE_H
#define LLVM_DEBUGINFO_CODEVIEW_LINE_H
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/Endian.h"
#include <cinttypes>
namespace llvm {
namespace codeview {
+using llvm::support::ulittle32_t;
+
class LineInfo {
public:
- static const uint32_t AlwaysStepIntoLineNumber = 0xfeefee;
- static const uint32_t NeverStepIntoLineNumber = 0xf00f00;
+ enum : uint32_t {
+ AlwaysStepIntoLineNumber = 0xfeefee,
+ NeverStepIntoLineNumber = 0xf00f00
+ };
-private:
- static const uint32_t StartLineMask = 0x00ffffff;
- static const uint32_t EndLineDeltaMask = 0x7f000000;
- static const int EndLineDeltaShift = 24;
- static const uint32_t StatementFlag = 0x80000000u;
+ enum : int { EndLineDeltaShift = 24 };
+
+ enum : uint32_t {
+ StartLineMask = 0x00ffffff,
+ EndLineDeltaMask = 0x7f000000,
+ StatementFlag = 0x80000000u
+ };
-public:
LineInfo(uint32_t StartLine, uint32_t EndLine, bool IsStatement);
+ LineInfo(uint32_t LineData) : LineData(LineData) {}
uint32_t getStartLine() const { return LineData & StartLineMask; }
@@ -118,7 +126,29 @@ public:
bool isNeverStepInto() const { return LineInf.isNeverStepInto(); }
};
-}
-}
+
+enum class InlineeLinesSignature : uint32_t {
+ Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE
+ ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX
+};
+
+struct InlineeSourceLine {
+ TypeIndex Inlinee; // ID of the function that was inlined.
+ ulittle32_t FileID; // Offset into FileChecksums subsection.
+ ulittle32_t SourceLineNum; // First line of inlined code.
+ // If extra files present:
+ // ulittle32_t ExtraFileCount;
+ // ulittle32_t Files[];
+};
+
+struct FileChecksum {
+ ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
+ uint8_t ChecksumSize; // Number of bytes of checksum.
+ uint8_t ChecksumKind; // FileChecksumKind
+ // Checksum bytes follow.
+};
+
+} // namespace codeview
+} // namespace llvm
#endif
diff --git a/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h b/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h
index df0a2e08a418..00bf03d417a2 100644
--- a/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h
+++ b/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h
@@ -14,6 +14,7 @@
namespace llvm {
namespace codeview {
+class TypeTableBuilder;
class ListRecordBuilder {
private:
@@ -28,14 +29,35 @@ protected:
public:
llvm::StringRef str() { return Builder.str(); }
+ void reset() {
+ Builder.reset(Kind);
+ ContinuationOffsets.clear();
+ SubrecordStart = 0;
+ }
+
+ void writeListContinuation(const ListContinuationRecord &R);
+
+ /// Writes this list record as a possible sequence of records.
+ TypeIndex writeListRecord(TypeTableBuilder &Table);
+
protected:
void finishSubRecord();
TypeRecordBuilder &getBuilder() { return Builder; }
private:
+ size_t getLastContinuationStart() const {
+ return ContinuationOffsets.empty() ? 0 : ContinuationOffsets.back();
+ }
+ size_t getLastContinuationEnd() const { return Builder.size(); }
+ size_t getLastContinuationSize() const {
+ return getLastContinuationEnd() - getLastContinuationStart();
+ }
+
+ TypeRecordKind Kind;
TypeRecordBuilder Builder;
SmallVector<size_t, 4> ContinuationOffsets;
+ size_t SubrecordStart = 0;
};
}
}
diff --git a/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h b/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h
index 5bfe2a068672..002f885c7c5a 100644
--- a/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h
+++ b/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h
@@ -10,12 +10,9 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_MEMORYTYPETABLEBUILDER_H
#define LLVM_DEBUGINFO_CODEVIEW_MEMORYTYPETABLEBUILDER_H
-#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
-#include <functional>
-#include <memory>
-#include <unordered_map>
#include <vector>
namespace llvm {
@@ -23,46 +20,29 @@ namespace codeview {
class MemoryTypeTableBuilder : public TypeTableBuilder {
public:
- class Record {
- public:
- explicit Record(llvm::StringRef RData);
-
- const char *data() const { return Data.get(); }
- uint16_t size() const { return Size; }
-
- private:
- uint16_t Size;
- std::unique_ptr<char[]> Data;
- };
-
-private:
- class RecordHash : std::unary_function<llvm::StringRef, size_t> {
- public:
- size_t operator()(llvm::StringRef Val) const {
- return static_cast<size_t>(llvm::hash_value(Val));
- }
- };
-
-public:
MemoryTypeTableBuilder() {}
+ bool empty() const { return Records.empty(); }
+
template <typename TFunc> void ForEachRecord(TFunc Func) {
uint32_t Index = TypeIndex::FirstNonSimpleIndex;
- for (const std::unique_ptr<Record> &R : Records) {
- Func(TypeIndex(Index), R.get());
+ for (StringRef R : Records) {
+ Func(TypeIndex(Index), R);
++Index;
}
}
-private:
- virtual TypeIndex writeRecord(llvm::StringRef Data) override;
+protected:
+ TypeIndex writeRecord(llvm::StringRef Data) override;
private:
- std::vector<std::unique_ptr<Record>> Records;
- std::unordered_map<llvm::StringRef, TypeIndex, RecordHash> HashedRecords;
+ std::vector<StringRef> Records;
+ BumpPtrAllocator RecordStorage;
+ DenseMap<StringRef, TypeIndex> HashedRecords;
};
-}
-}
-#endif
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_MEMORYTYPETABLEBUILDER_H
diff --git a/include/llvm/DebugInfo/CodeView/ModuleSubstream.h b/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
new file mode 100644
index 000000000000..6affac801d4d
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
@@ -0,0 +1,87 @@
+//===- ModuleSubstream.h ----------------------------------------*- 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_CODEVIEW_MODULESUBSTREAM_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
+struct ModuleSubsectionHeader {
+ support::ulittle32_t Kind; // codeview::ModuleSubstreamKind enum
+ support::ulittle32_t Length; // number of bytes occupied by this record.
+};
+
+// Corresponds to the `CV_DebugSLinesHeader_t` structure.
+struct LineSubstreamHeader {
+ support::ulittle32_t RelocOffset; // Code offset of line contribution.
+ support::ulittle16_t RelocSegment; // Code segment of line contribution.
+ support::ulittle16_t Flags; // See LineFlags enumeration.
+ support::ulittle32_t CodeSize; // Code size of this line contribution.
+};
+
+// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
+struct LineFileBlockHeader {
+ support::ulittle32_t NameIndex; // Index in DBI name buffer of filename.
+ support::ulittle32_t NumLines; // Number of lines
+ support::ulittle32_t BlockSize; // Code size of block, in bytes.
+ // The following two variable length arrays appear immediately after the
+ // header. The structure definitions follow.
+ // LineNumberEntry Lines[NumLines];
+ // ColumnNumberEntry Columns[NumLines];
+};
+
+// Corresponds to `CV_Line_t` structure
+struct LineNumberEntry {
+ support::ulittle32_t Offset; // Offset to start of code bytes for line number
+ support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1
+};
+
+// Corresponds to `CV_Column_t` structure
+struct ColumnNumberEntry {
+ support::ulittle16_t StartColumn;
+ support::ulittle16_t EndColumn;
+};
+
+class ModuleSubstream {
+public:
+ ModuleSubstream();
+ ModuleSubstream(ModuleSubstreamKind Kind, StreamRef Data);
+ static Error initialize(StreamRef Stream, ModuleSubstream &Info);
+ uint32_t getRecordLength() const;
+ ModuleSubstreamKind getSubstreamKind() const;
+ StreamRef getRecordData() const;
+
+private:
+ ModuleSubstreamKind Kind;
+ StreamRef Data;
+};
+
+template <> struct VarStreamArrayExtractor<ModuleSubstream> {
+ Error operator()(StreamRef Stream, uint32_t &Length,
+ ModuleSubstream &Info) const {
+ if (auto EC = ModuleSubstream::initialize(Stream, Info))
+ return EC;
+ Length = Info.getRecordLength();
+ return Error::success();
+ }
+};
+
+typedef VarStreamArray<ModuleSubstream> ModuleSubstreamArray;
+}
+}
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H
diff --git a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
new file mode 100644
index 000000000000..6df230903712
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
@@ -0,0 +1,121 @@
+//===- ModuleSubstreamVisitor.h ---------------------------------*- 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_CODEVIEW_MODULESUBSTREAMVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
+#include "llvm/DebugInfo/CodeView/StreamReader.h"
+#include "llvm/DebugInfo/CodeView/StreamRef.h"
+
+namespace llvm {
+namespace codeview {
+
+struct LineColumnEntry {
+ support::ulittle32_t NameIndex;
+ FixedStreamArray<LineNumberEntry> LineNumbers;
+ FixedStreamArray<ColumnNumberEntry> Columns;
+};
+
+template <> class VarStreamArrayExtractor<LineColumnEntry> {
+public:
+ VarStreamArrayExtractor(const LineSubstreamHeader *Header) : Header(Header) {}
+
+ Error operator()(StreamRef Stream, uint32_t &Len,
+ LineColumnEntry &Item) const {
+ const LineFileBlockHeader *BlockHeader;
+ StreamReader Reader(Stream);
+ if (auto EC = Reader.readObject(BlockHeader))
+ return EC;
+ bool HasColumn = Header->Flags & LineFlags::HaveColumns;
+ uint32_t LineInfoSize =
+ BlockHeader->NumLines *
+ (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
+ if (BlockHeader->BlockSize < sizeof(LineFileBlockHeader))
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Invalid line block record size");
+ uint32_t Size = BlockHeader->BlockSize - sizeof(LineFileBlockHeader);
+ if (LineInfoSize > Size)
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Invalid line block record size");
+ // The value recorded in BlockHeader->BlockSize includes the size of
+ // LineFileBlockHeader.
+ Len = BlockHeader->BlockSize;
+ Item.NameIndex = BlockHeader->NameIndex;
+ if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
+ return EC;
+ if (HasColumn) {
+ if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines))
+ return EC;
+ }
+ return Error::success();
+ }
+
+private:
+ const LineSubstreamHeader *Header;
+};
+
+struct FileChecksumEntry {
+ uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
+ FileChecksumKind Kind; // The type of checksum.
+ ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
+};
+
+template <> class VarStreamArrayExtractor<FileChecksumEntry> {
+public:
+ Error operator()(StreamRef Stream, uint32_t &Len,
+ FileChecksumEntry &Item) const {
+ const FileChecksum *Header;
+ StreamReader Reader(Stream);
+ if (auto EC = Reader.readObject(Header))
+ return EC;
+ Item.FileNameOffset = Header->FileNameOffset;
+ Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);
+ if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))
+ return EC;
+ Len = sizeof(FileChecksum) + Header->ChecksumSize;
+ return Error::success();
+ }
+};
+
+typedef VarStreamArray<LineColumnEntry> LineInfoArray;
+typedef VarStreamArray<FileChecksumEntry> FileChecksumArray;
+
+class IModuleSubstreamVisitor {
+public:
+ virtual ~IModuleSubstreamVisitor() {}
+
+ virtual Error visitUnknown(ModuleSubstreamKind Kind, StreamRef Data) = 0;
+ virtual Error visitSymbols(StreamRef Data);
+ virtual Error visitLines(StreamRef Data, const LineSubstreamHeader *Header,
+ const LineInfoArray &Lines);
+ virtual Error visitStringTable(StreamRef Data);
+ virtual Error visitFileChecksums(StreamRef Data,
+ const FileChecksumArray &Checksums);
+ virtual Error visitFrameData(StreamRef Data);
+ virtual Error visitInlineeLines(StreamRef Data);
+ virtual Error visitCrossScopeImports(StreamRef Data);
+ virtual Error visitCrossScopeExports(StreamRef Data);
+ virtual Error visitILLines(StreamRef Data);
+ virtual Error visitFuncMDTokenMap(StreamRef Data);
+ virtual Error visitTypeMDTokenMap(StreamRef Data);
+ virtual Error visitMergedAssemblyInput(StreamRef Data);
+ virtual Error visitCoffSymbolRVA(StreamRef Data);
+};
+
+Error visitModuleSubstream(const ModuleSubstream &R,
+ IModuleSubstreamVisitor &V);
+
+} // namespace codeview
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
diff --git a/include/llvm/DebugInfo/CodeView/RecordSerialization.h b/include/llvm/DebugInfo/CodeView/RecordSerialization.h
new file mode 100644
index 000000000000..84179f5f81f7
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/RecordSerialization.h
@@ -0,0 +1,278 @@
+//===- RecordSerialization.h ------------------------------------*- 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_CODEVIEW_RECORDSERIALIZATION_H
+#define LLVM_DEBUGINFO_CODEVIEW_RECORDSERIALIZATION_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include <cinttypes>
+#include <tuple>
+
+namespace llvm {
+namespace codeview {
+using llvm::support::little32_t;
+using llvm::support::ulittle16_t;
+using llvm::support::ulittle32_t;
+
+struct RecordPrefix {
+ ulittle16_t RecordLen; // Record length, starting from &Leaf.
+ ulittle16_t RecordKind; // Record kind enum (SymRecordKind or TypeRecordKind)
+};
+
+/// Reinterpret a byte array as an array of characters. Does not interpret as
+/// a C string, as StringRef has several helpers (split) that make that easy.
+StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData);
+StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData);
+
+/// Consumes sizeof(T) bytes from the given byte sequence. Returns an error if
+/// there are not enough bytes remaining. Reinterprets the consumed bytes as a
+/// T object and points 'Res' at them.
+template <typename T, typename U>
+inline std::error_code consumeObject(U &Data, const T *&Res) {
+ if (Data.size() < sizeof(*Res))
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+ Res = reinterpret_cast<const T *>(Data.data());
+ Data = Data.drop_front(sizeof(*Res));
+ return std::error_code();
+}
+
+inline std::error_code consume(ArrayRef<uint8_t> &Data) {
+ return std::error_code();
+}
+
+/// Decodes a numeric "leaf" value. These are integer literals encountered in
+/// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
+/// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
+/// that indicates the bitwidth and sign of the numeric data.
+std::error_code consume(ArrayRef<uint8_t> &Data, APSInt &Num);
+std::error_code consume(StringRef &Data, APSInt &Num);
+
+/// Decodes a numeric leaf value that is known to be a particular type.
+std::error_code consume_numeric(ArrayRef<uint8_t> &Data, uint64_t &Value);
+
+/// Decodes signed and unsigned fixed-length integers.
+std::error_code consume(ArrayRef<uint8_t> &Data, uint32_t &Item);
+std::error_code consume(StringRef &Data, uint32_t &Item);
+std::error_code consume(ArrayRef<uint8_t> &Data, int32_t &Item);
+
+/// Decodes a null terminated string.
+std::error_code consume(ArrayRef<uint8_t> &Data, StringRef &Item);
+
+/// Decodes an arbitrary object whose layout matches that of the underlying
+/// byte sequence, and returns a pointer to the object.
+template <typename T>
+std::error_code consume(ArrayRef<uint8_t> &Data, T *&Item) {
+ return consumeObject(Data, Item);
+}
+
+template <typename T, typename U> struct serialize_conditional_impl {
+ serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {}
+
+ std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ if (!Func())
+ return std::error_code();
+ return consume(Data, Item);
+ }
+
+ T &Item;
+ U Func;
+};
+
+template <typename T, typename U>
+serialize_conditional_impl<T, U> serialize_conditional(T &Item, U Func) {
+ return serialize_conditional_impl<T, U>(Item, Func);
+}
+
+template <typename T, typename U> struct serialize_array_impl {
+ serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {}
+
+ std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ uint32_t N = Func();
+ if (N == 0)
+ return std::error_code();
+
+ uint32_t Size = sizeof(T) * N;
+
+ if (Size / sizeof(T) != N)
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+
+ if (Data.size() < Size)
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+
+ Item = ArrayRef<T>(reinterpret_cast<const T *>(Data.data()), N);
+ Data = Data.drop_front(Size);
+ return std::error_code();
+ }
+
+ ArrayRef<T> &Item;
+ U Func;
+};
+
+template <typename T> struct serialize_vector_tail_impl {
+ serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {}
+
+ std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ T Field;
+ // Stop when we run out of bytes or we hit record padding bytes.
+ while (!Data.empty() && Data.front() < LF_PAD0) {
+ if (auto EC = consume(Data, Field))
+ return EC;
+ Item.push_back(Field);
+ }
+ return std::error_code();
+ }
+
+ std::vector<T> &Item;
+};
+
+struct serialize_null_term_string_array_impl {
+ serialize_null_term_string_array_impl(std::vector<StringRef> &Item)
+ : Item(Item) {}
+
+ std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ if (Data.empty())
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+
+ StringRef Field;
+ // Stop when we run out of bytes or we hit record padding bytes.
+ while (Data.front() != 0) {
+ if (auto EC = consume(Data, Field))
+ return EC;
+ Item.push_back(Field);
+ if (Data.empty())
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+ }
+ Data = Data.drop_front(1);
+ return std::error_code();
+ }
+
+ std::vector<StringRef> &Item;
+};
+
+template <typename T> struct serialize_arrayref_tail_impl {
+ serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}
+
+ std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ uint32_t Count = Data.size() / sizeof(T);
+ Item = ArrayRef<T>(reinterpret_cast<const T *>(Data.begin()), Count);
+ return std::error_code();
+ }
+
+ ArrayRef<T> &Item;
+};
+
+template <typename T> struct serialize_numeric_impl {
+ serialize_numeric_impl(T &Item) : Item(Item) {}
+
+ std::error_code deserialize(ArrayRef<uint8_t> &Data) const {
+ return consume_numeric(Data, Item);
+ }
+
+ T &Item;
+};
+
+template <typename T, typename U>
+serialize_array_impl<T, U> serialize_array(ArrayRef<T> &Item, U Func) {
+ return serialize_array_impl<T, U>(Item, Func);
+}
+
+inline serialize_null_term_string_array_impl
+serialize_null_term_string_array(std::vector<StringRef> &Item) {
+ return serialize_null_term_string_array_impl(Item);
+}
+
+template <typename T>
+serialize_vector_tail_impl<T> serialize_array_tail(std::vector<T> &Item) {
+ return serialize_vector_tail_impl<T>(Item);
+}
+
+template <typename T>
+serialize_arrayref_tail_impl<T> serialize_array_tail(ArrayRef<T> &Item) {
+ return serialize_arrayref_tail_impl<T>(Item);
+}
+
+template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) {
+ return serialize_numeric_impl<T>(Item);
+}
+
+// This field is only present in the byte record if the condition is true. The
+// condition is evaluated lazily, so it can depend on items that were
+// deserialized
+// earlier.
+#define CV_CONDITIONAL_FIELD(I, C) \
+ serialize_conditional(I, [&]() { return !!(C); })
+
+// This is an array of N items, where N is evaluated lazily, so it can refer
+// to a field deserialized earlier.
+#define CV_ARRAY_FIELD_N(I, N) serialize_array(I, [&]() { return N; })
+
+// This is an array that exhausts the remainder of the input buffer.
+#define CV_ARRAY_FIELD_TAIL(I) serialize_array_tail(I)
+
+// This is an array that consumes null terminated strings until a double null
+// is encountered.
+#define CV_STRING_ARRAY_NULL_TERM(I) serialize_null_term_string_array(I)
+
+#define CV_NUMERIC_FIELD(I) serialize_numeric(I)
+
+template <typename T, typename U>
+std::error_code consume(ArrayRef<uint8_t> &Data,
+ const serialize_conditional_impl<T, U> &Item) {
+ return Item.deserialize(Data);
+}
+
+template <typename T, typename U>
+std::error_code consume(ArrayRef<uint8_t> &Data,
+ const serialize_array_impl<T, U> &Item) {
+ return Item.deserialize(Data);
+}
+
+inline std::error_code
+consume(ArrayRef<uint8_t> &Data,
+ const serialize_null_term_string_array_impl &Item) {
+ return Item.deserialize(Data);
+}
+
+template <typename T>
+std::error_code consume(ArrayRef<uint8_t> &Data,
+ const serialize_vector_tail_impl<T> &Item) {
+ return Item.deserialize(Data);
+}
+
+template <typename T>
+std::error_code consume(ArrayRef<uint8_t> &Data,
+ const serialize_arrayref_tail_impl<T> &Item) {
+ return Item.deserialize(Data);
+}
+
+template <typename T>
+std::error_code consume(ArrayRef<uint8_t> &Data,
+ const serialize_numeric_impl<T> &Item) {
+ return Item.deserialize(Data);
+}
+
+template <typename T, typename U, typename... Args>
+std::error_code consume(ArrayRef<uint8_t> &Data, T &&X, U &&Y,
+ Args &&... Rest) {
+ if (auto EC = consume(Data, X))
+ return EC;
+ return consume(Data, Y, std::forward<Args>(Rest)...);
+}
+
+#define CV_DESERIALIZE(...) \
+ if (auto EC = consume(__VA_ARGS__)) \
+ return EC;
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/CodeView/StreamArray.h b/include/llvm/DebugInfo/CodeView/StreamArray.h
new file mode 100644
index 000000000000..0b9349aac753
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/StreamArray.h
@@ -0,0 +1,275 @@
+//===- StreamArray.h - Array backed by an arbitrary stream ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_STREAMARRAY_H
+#define LLVM_DEBUGINFO_CODEVIEW_STREAMARRAY_H
+
+#include "llvm/DebugInfo/CodeView/StreamRef.h"
+#include "llvm/Support/Error.h"
+
+#include <functional>
+#include <type_traits>
+
+namespace llvm {
+namespace codeview {
+
+/// VarStreamArrayExtractor is intended to be specialized to provide customized
+/// extraction logic. On input it receives a StreamRef pointing to the
+/// beginning of the next record, but where the length of the record is not yet
+/// known. Upon completion, it should return an appropriate Error instance if
+/// a record could not be extracted, or if one could be extracted it should
+/// return success and set Len to the number of bytes this record occupied in
+/// the underlying stream, and it should fill out the fields of the value type
+/// Item appropriately to represent the current record.
+///
+/// You can specialize this template for your own custom value types to avoid
+/// having to specify a second template argument to VarStreamArray (documented
+/// below).
+template <typename T> struct VarStreamArrayExtractor {
+ // Method intentionally deleted. You must provide an explicit specialization
+ // with the following method implemented.
+ Error operator()(StreamRef Stream, uint32_t &Len, T &Item) const = delete;
+};
+
+/// VarStreamArray represents an array of variable length records backed by a
+/// stream. This could be a contiguous sequence of bytes in memory, it could
+/// be a file on disk, or it could be a PDB stream where bytes are stored as
+/// discontiguous blocks in a file. Usually it is desirable to treat arrays
+/// as contiguous blocks of memory, but doing so with large PDB files, for
+/// example, could mean allocating huge amounts of memory just to allow
+/// re-ordering of stream data to be contiguous before iterating over it. By
+/// abstracting this out, we need not duplicate this memory, and we can
+/// iterate over arrays in arbitrarily formatted streams. Elements are parsed
+/// lazily on iteration, so there is no upfront cost associated with building
+/// a VarStreamArray, no matter how large it may be.
+///
+/// You create a VarStreamArray by specifying a ValueType and an Extractor type.
+/// If you do not specify an Extractor type, it expects you to specialize
+/// VarStreamArrayExtractor<T> for your ValueType.
+///
+/// By default an Extractor is default constructed in the class, but in some
+/// cases you might find it useful for an Extractor to maintain state across
+/// extractions. In this case you can provide your own Extractor through a
+/// secondary constructor. The following examples show various ways of
+/// creating a VarStreamArray.
+///
+/// // Will use VarStreamArrayExtractor<MyType> as the extractor.
+/// VarStreamArray<MyType> MyTypeArray;
+///
+/// // Will use a default-constructed MyExtractor as the extractor.
+/// VarStreamArray<MyType, MyExtractor> MyTypeArray2;
+///
+/// // Will use the specific instance of MyExtractor provided.
+/// // MyExtractor need not be default-constructible in this case.
+/// MyExtractor E(SomeContext);
+/// VarStreamArray<MyType, MyExtractor> MyTypeArray3(E);
+///
+template <typename ValueType, typename Extractor> class VarStreamArrayIterator;
+
+template <typename ValueType,
+ typename Extractor = VarStreamArrayExtractor<ValueType>>
+class VarStreamArray {
+ friend class VarStreamArrayIterator<ValueType, Extractor>;
+
+public:
+ typedef VarStreamArrayIterator<ValueType, Extractor> Iterator;
+
+ VarStreamArray() {}
+ explicit VarStreamArray(const Extractor &E) : E(E) {}
+
+ explicit VarStreamArray(StreamRef Stream) : Stream(Stream) {}
+ VarStreamArray(StreamRef Stream, const Extractor &E) : Stream(Stream), E(E) {}
+
+ VarStreamArray(const VarStreamArray<ValueType, Extractor> &Other)
+ : Stream(Other.Stream), E(Other.E) {}
+
+ Iterator begin(bool *HadError = nullptr) const {
+ return Iterator(*this, E, HadError);
+ }
+
+ Iterator end() const { return Iterator(E); }
+
+ const Extractor &getExtractor() const { return E; }
+
+ StreamRef getUnderlyingStream() const { return Stream; }
+
+private:
+ StreamRef Stream;
+ Extractor E;
+};
+
+template <typename ValueType, typename Extractor> class VarStreamArrayIterator {
+ typedef VarStreamArrayIterator<ValueType, Extractor> IterType;
+ typedef VarStreamArray<ValueType, Extractor> ArrayType;
+
+public:
+ VarStreamArrayIterator(const ArrayType &Array, const Extractor &E,
+ bool *HadError = nullptr)
+ : IterRef(Array.Stream), Array(&Array), HadError(HadError), Extract(E) {
+ if (IterRef.getLength() == 0)
+ moveToEnd();
+ else {
+ auto EC = Extract(IterRef, ThisLen, ThisValue);
+ if (EC) {
+ consumeError(std::move(EC));
+ markError();
+ }
+ }
+ }
+ VarStreamArrayIterator() {}
+ explicit VarStreamArrayIterator(const Extractor &E) : Extract(E) {}
+ ~VarStreamArrayIterator() {}
+
+ bool operator==(const IterType &R) const {
+ if (Array && R.Array) {
+ // Both have a valid array, make sure they're same.
+ assert(Array == R.Array);
+ return IterRef == R.IterRef;
+ }
+
+ // Both iterators are at the end.
+ if (!Array && !R.Array)
+ return true;
+
+ // One is not at the end and one is.
+ return false;
+ }
+
+ bool operator!=(const IterType &R) { return !(*this == R); }
+
+ const ValueType &operator*() const {
+ assert(Array && !HasError);
+ return ThisValue;
+ }
+
+ IterType &operator++() {
+ // We are done with the current record, discard it so that we are
+ // positioned at the next record.
+ IterRef = IterRef.drop_front(ThisLen);
+ if (IterRef.getLength() == 0) {
+ // There is nothing after the current record, we must make this an end
+ // iterator.
+ moveToEnd();
+ } else {
+ // There is some data after the current record.
+ auto EC = Extract(IterRef, ThisLen, ThisValue);
+ if (EC) {
+ consumeError(std::move(EC));
+ markError();
+ } else if (ThisLen == 0) {
+ // An empty record? Make this an end iterator.
+ moveToEnd();
+ }
+ }
+ return *this;
+ }
+
+ IterType operator++(int) {
+ IterType Original = *this;
+ ++*this;
+ return Original;
+ }
+
+private:
+ void moveToEnd() {
+ Array = nullptr;
+ ThisLen = 0;
+ }
+ void markError() {
+ moveToEnd();
+ HasError = true;
+ if (HadError != nullptr)
+ *HadError = true;
+ }
+
+ ValueType ThisValue;
+ StreamRef IterRef;
+ const ArrayType *Array{nullptr};
+ uint32_t ThisLen{0};
+ bool HasError{false};
+ bool *HadError{nullptr};
+ Extractor Extract;
+};
+
+template <typename T> class FixedStreamArrayIterator;
+
+template <typename T> class FixedStreamArray {
+ friend class FixedStreamArrayIterator<T>;
+
+public:
+ FixedStreamArray() : Stream() {}
+ FixedStreamArray(StreamRef Stream) : Stream(Stream) {
+ assert(Stream.getLength() % sizeof(T) == 0);
+ }
+
+ const T &operator[](uint32_t Index) const {
+ assert(Index < size());
+ uint32_t Off = Index * sizeof(T);
+ ArrayRef<uint8_t> Data;
+ if (auto EC = Stream.readBytes(Off, sizeof(T), Data)) {
+ assert(false && "Unexpected failure reading from stream");
+ // This should never happen since we asserted that the stream length was
+ // an exact multiple of the element size.
+ consumeError(std::move(EC));
+ }
+ return *reinterpret_cast<const T *>(Data.data());
+ }
+
+ uint32_t size() const { return Stream.getLength() / sizeof(T); }
+
+ FixedStreamArrayIterator<T> begin() const {
+ return FixedStreamArrayIterator<T>(*this, 0);
+ }
+ FixedStreamArrayIterator<T> end() const {
+ return FixedStreamArrayIterator<T>(*this, size());
+ }
+
+ StreamRef getUnderlyingStream() const { return Stream; }
+
+private:
+ StreamRef Stream;
+};
+
+template <typename T> class FixedStreamArrayIterator {
+public:
+ FixedStreamArrayIterator(const FixedStreamArray<T> &Array, uint32_t Index)
+ : Array(Array), Index(Index) {}
+
+ bool operator==(const FixedStreamArrayIterator<T> &R) {
+ assert(&Array == &R.Array);
+ return Index == R.Index;
+ }
+
+ bool operator!=(const FixedStreamArrayIterator<T> &R) {
+ return !(*this == R);
+ }
+
+ const T &operator*() const { return Array[Index]; }
+
+ FixedStreamArrayIterator<T> &operator++() {
+ assert(Index < Array.size());
+ ++Index;
+ return *this;
+ }
+
+ FixedStreamArrayIterator<T> operator++(int) {
+ FixedStreamArrayIterator<T> Original = *this;
+ ++*this;
+ return Original;
+ }
+
+private:
+ const FixedStreamArray<T> &Array;
+ uint32_t Index;
+};
+
+} // namespace codeview
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMARRAY_H
diff --git a/include/llvm/DebugInfo/CodeView/StreamInterface.h b/include/llvm/DebugInfo/CodeView/StreamInterface.h
new file mode 100644
index 000000000000..241aec457870
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/StreamInterface.h
@@ -0,0 +1,55 @@
+//===- StreamInterface.h - Base interface for a stream of data --*- 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_CODEVIEW_STREAMINTERFACE_H
+#define LLVM_DEBUGINFO_CODEVIEW_STREAMINTERFACE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+
+namespace llvm {
+namespace codeview {
+
+/// StreamInterface abstracts the notion of a data stream. This way, an
+/// implementation could implement trivial reading from a contiguous memory
+/// buffer or, as in the case of PDB files, reading from a set of possibly
+/// discontiguous blocks. The implementation is required to return references
+/// to stable memory, so if this is not possible (for example in the case of
+/// a PDB file with discontiguous blocks, it must keep its own pool of temp
+/// storage.
+class StreamInterface {
+public:
+ virtual ~StreamInterface() {}
+
+ // Given an offset into the stream and a number of bytes, attempt to read
+ // the bytes and set the output ArrayRef to point to a reference into the
+ // stream, without copying any data.
+ virtual Error readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) const = 0;
+
+ // Given an offset into the stream, read as much as possible without copying
+ // any data.
+ virtual Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) const = 0;
+
+ // Attempt to write the given bytes into the stream at the desired offset.
+ // This will always necessitate a copy. Cannot shrink or grow the stream,
+ // only writes into existing allocated space.
+ virtual Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const = 0;
+
+ virtual uint32_t getLength() const = 0;
+
+ virtual Error commit() const = 0;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMINTERFACE_H
diff --git a/include/llvm/DebugInfo/CodeView/StreamReader.h b/include/llvm/DebugInfo/CodeView/StreamReader.h
new file mode 100644
index 000000000000..2f497c2c43f1
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/StreamReader.h
@@ -0,0 +1,111 @@
+//===- StreamReader.h - Reads bytes and objects from a stream ---*- 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_CODEVIEW_STREAMREADER_H
+#define LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamInterface.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+#include <string>
+
+namespace llvm {
+namespace codeview {
+
+class StreamRef;
+
+class StreamReader {
+public:
+ StreamReader(StreamRef Stream);
+
+ Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer);
+ Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size);
+ Error readInteger(uint16_t &Dest);
+ Error readInteger(uint32_t &Dest);
+ Error readZeroString(StringRef &Dest);
+ Error readFixedString(StringRef &Dest, uint32_t Length);
+ Error readStreamRef(StreamRef &Ref);
+ Error readStreamRef(StreamRef &Ref, uint32_t Length);
+
+ template <typename T> Error readEnum(T &Dest) {
+ typename std::underlying_type<T>::type N;
+ if (auto EC = readInteger(N))
+ return EC;
+ Dest = static_cast<T>(N);
+ return Error::success();
+ }
+
+ template <typename T> Error readObject(const T *&Dest) {
+ ArrayRef<uint8_t> Buffer;
+ if (auto EC = readBytes(Buffer, sizeof(T)))
+ return EC;
+ Dest = reinterpret_cast<const T *>(Buffer.data());
+ return Error::success();
+ }
+
+ template <typename T>
+ Error readArray(ArrayRef<T> &Array, uint32_t NumElements) {
+ ArrayRef<uint8_t> Bytes;
+ if (NumElements == 0) {
+ Array = ArrayRef<T>();
+ return Error::success();
+ }
+
+ if (NumElements > UINT32_MAX/sizeof(T))
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+
+ if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
+ return EC;
+ Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements);
+ return Error::success();
+ }
+
+ template <typename T, typename U>
+ Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
+ StreamRef S;
+ if (auto EC = readStreamRef(S, Size))
+ return EC;
+ Array = VarStreamArray<T, U>(S, Array.getExtractor());
+ return Error::success();
+ }
+
+ template <typename T>
+ Error readArray(FixedStreamArray<T> &Array, uint32_t NumItems) {
+ if (NumItems == 0) {
+ Array = FixedStreamArray<T>();
+ return Error::success();
+ }
+ uint32_t Length = NumItems * sizeof(T);
+ if (Length / sizeof(T) != NumItems)
+ return make_error<CodeViewError>(cv_error_code::corrupt_record);
+ if (Offset + Length > Stream.getLength())
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+ StreamRef View = Stream.slice(Offset, Length);
+ Array = FixedStreamArray<T>(View);
+ Offset += Length;
+ return Error::success();
+ }
+
+ void setOffset(uint32_t Off) { Offset = Off; }
+ uint32_t getOffset() const { return Offset; }
+ uint32_t getLength() const { return Stream.getLength(); }
+ uint32_t bytesRemaining() const { return getLength() - getOffset(); }
+
+private:
+ StreamRef Stream;
+ uint32_t Offset;
+};
+} // namespace codeview
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
diff --git a/include/llvm/DebugInfo/CodeView/StreamRef.h b/include/llvm/DebugInfo/CodeView/StreamRef.h
new file mode 100644
index 000000000000..a4f244a32289
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/StreamRef.h
@@ -0,0 +1,104 @@
+//===- StreamRef.h - A copyable reference to a stream -----------*- 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_CODEVIEW_STREAMREF_H
+#define LLVM_DEBUGINFO_CODEVIEW_STREAMREF_H
+
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/StreamInterface.h"
+
+namespace llvm {
+namespace codeview {
+
+class StreamRef {
+public:
+ StreamRef() : Stream(nullptr), ViewOffset(0), Length(0) {}
+ StreamRef(const StreamInterface &Stream)
+ : Stream(&Stream), ViewOffset(0), Length(Stream.getLength()) {}
+ StreamRef(const StreamInterface &Stream, uint32_t Offset, uint32_t Length)
+ : Stream(&Stream), ViewOffset(Offset), Length(Length) {}
+
+ // Use StreamRef.slice() instead.
+ StreamRef(const StreamRef &S, uint32_t Offset, uint32_t Length) = delete;
+
+ Error readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) const {
+ if (ViewOffset + Offset < Offset)
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+ if (Size + Offset > Length)
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+ return Stream->readBytes(ViewOffset + Offset, Size, Buffer);
+ }
+
+ // Given an offset into the stream, read as much as possible without copying
+ // any data.
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) const {
+ if (Offset >= Length)
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+
+ if (auto EC = Stream->readLongestContiguousChunk(Offset, Buffer))
+ return EC;
+ // This StreamRef might refer to a smaller window over a larger stream. In
+ // that case we will have read out more bytes than we should return, because
+ // we should not read past the end of the current view.
+ uint32_t MaxLength = Length - Offset;
+ if (Buffer.size() > MaxLength)
+ Buffer = Buffer.slice(0, MaxLength);
+ return Error::success();
+ }
+
+ Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const {
+ if (Data.size() + Offset > Length)
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+ return Stream->writeBytes(ViewOffset + Offset, Data);
+ }
+
+ uint32_t getLength() const { return Length; }
+
+ Error commit() const { return Stream->commit(); }
+
+ StreamRef drop_front(uint32_t N) const {
+ if (!Stream)
+ return StreamRef();
+
+ N = std::min(N, Length);
+ return StreamRef(*Stream, ViewOffset + N, Length - N);
+ }
+
+ StreamRef keep_front(uint32_t N) const {
+ if (!Stream)
+ return StreamRef();
+ N = std::min(N, Length);
+ return StreamRef(*Stream, ViewOffset, N);
+ }
+
+ StreamRef slice(uint32_t Offset, uint32_t Len) const {
+ return drop_front(Offset).keep_front(Len);
+ }
+
+ bool operator==(const StreamRef &Other) const {
+ if (Stream != Other.Stream)
+ return false;
+ if (ViewOffset != Other.ViewOffset)
+ return false;
+ if (Length != Other.Length)
+ return false;
+ return true;
+ }
+
+private:
+ const StreamInterface *Stream;
+ uint32_t ViewOffset;
+ uint32_t Length;
+};
+}
+}
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMREF_H
diff --git a/include/llvm/DebugInfo/CodeView/StreamWriter.h b/include/llvm/DebugInfo/CodeView/StreamWriter.h
new file mode 100644
index 000000000000..4d393d2ef790
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/StreamWriter.h
@@ -0,0 +1,86 @@
+//===- StreamWriter.h - Writes bytes and objects to a stream ----*- 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_CODEVIEW_STREAMWRITER_H
+#define LLVM_DEBUGINFO_CODEVIEW_STREAMWRITER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamInterface.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+#include <string>
+
+namespace llvm {
+namespace codeview {
+
+class StreamRef;
+
+class StreamWriter {
+public:
+ StreamWriter(StreamRef Stream);
+
+ Error writeBytes(ArrayRef<uint8_t> Buffer);
+ Error writeInteger(uint16_t Dest);
+ Error writeInteger(uint32_t Dest);
+ Error writeZeroString(StringRef Str);
+ Error writeFixedString(StringRef Str);
+ Error writeStreamRef(StreamRef Ref);
+ Error writeStreamRef(StreamRef Ref, uint32_t Size);
+
+ template <typename T> Error writeEnum(T Num) {
+ return writeInteger(
+ static_cast<typename std::underlying_type<T>::type>(Num));
+ }
+
+ template <typename T> Error writeObject(const T &Obj) {
+ static_assert(!std::is_pointer<T>::value,
+ "writeObject should not be used with pointers, to write "
+ "the pointed-to value dereference the pointer before calling "
+ "writeObject");
+ return writeBytes(
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T)));
+ }
+
+ template <typename T> Error writeArray(ArrayRef<T> Array) {
+ if (Array.size() == 0)
+ return Error::success();
+
+ if (Array.size() > UINT32_MAX / sizeof(T))
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+
+ return writeBytes(
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()),
+ Array.size() * sizeof(T)));
+ }
+
+ template <typename T, typename U>
+ Error writeArray(VarStreamArray<T, U> Array) {
+ return writeStreamRef(Array.getUnderlyingStream());
+ }
+
+ template <typename T> Error writeArray(FixedStreamArray<T> Array) {
+ return writeStreamRef(Array.getUnderlyingStream());
+ }
+
+ void setOffset(uint32_t Off) { Offset = Off; }
+ uint32_t getOffset() const { return Offset; }
+ uint32_t getLength() const { return Stream.getLength(); }
+ uint32_t bytesRemaining() const { return getLength() - getOffset(); }
+
+private:
+ StreamRef Stream;
+ uint32_t Offset;
+};
+} // namespace codeview
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
diff --git a/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h b/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h
new file mode 100644
index 000000000000..30b0a40451cb
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/SymbolDumpDelegate.h
@@ -0,0 +1,37 @@
+//===-- SymbolDumpDelegate.h ------------------------------------*- 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_CODEVIEW_SYMBOLDUMPDELEGATE_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPDELEGATE_H
+
+#include "SymbolVisitorDelegate.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <stdint.h>
+
+namespace llvm {
+
+namespace codeview {
+
+class SymbolDumpDelegate : public SymbolVisitorDelegate {
+public:
+ virtual ~SymbolDumpDelegate() {}
+
+ virtual void printRelocatedField(StringRef Label, uint32_t RelocOffset,
+ uint32_t Offset,
+ StringRef *RelocSym = nullptr) = 0;
+ virtual void printBinaryBlockWithRelocs(StringRef Label,
+ ArrayRef<uint8_t> Block) = 0;
+};
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPDELEGATE_H
diff --git a/include/llvm/DebugInfo/CodeView/SymbolDumper.h b/include/llvm/DebugInfo/CodeView/SymbolDumper.h
new file mode 100644
index 000000000000..648e40f55810
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/SymbolDumper.h
@@ -0,0 +1,54 @@
+//===-- SymbolDumper.h - CodeView symbol info dumper ------------*- 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_CODEVIEW_SYMBOLDUMPER_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+
+namespace llvm {
+class ScopedPrinter;
+
+namespace codeview {
+class CVTypeDumper;
+
+/// Dumper for CodeView symbol streams found in COFF object files and PDB files.
+class CVSymbolDumper {
+public:
+ CVSymbolDumper(ScopedPrinter &W, CVTypeDumper &CVTD,
+ std::unique_ptr<SymbolDumpDelegate> ObjDelegate,
+ bool PrintRecordBytes)
+ : W(W), CVTD(CVTD), ObjDelegate(std::move(ObjDelegate)),
+ PrintRecordBytes(PrintRecordBytes) {}
+
+ /// Dumps one type record. Returns false if there was a type parsing error,
+ /// and true otherwise. This should be called in order, since the dumper
+ /// maintains state about previous records which are necessary for cross
+ /// type references.
+ bool dump(const CVRecord<SymbolKind> &Record);
+
+ /// Dumps the type records in Data. Returns false if there was a type stream
+ /// parse error, and true otherwise.
+ bool dump(const CVSymbolArray &Symbols);
+
+private:
+ ScopedPrinter &W;
+ CVTypeDumper &CVTD;
+ std::unique_ptr<SymbolDumpDelegate> ObjDelegate;
+
+ bool PrintRecordBytes;
+};
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLDUMPER_H
diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h
new file mode 100644
index 000000000000..77e894fba4a9
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -0,0 +1,1452 @@
+//===- SymbolRecord.h -------------------------------------------*- 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_CODEVIEW_SYMBOLRECORD_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamInterface.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+using llvm::support::ulittle16_t;
+using llvm::support::ulittle32_t;
+using llvm::support::little32_t;
+
+class SymbolRecord {
+protected:
+ explicit SymbolRecord(SymbolRecordKind Kind) : Kind(Kind) {}
+
+public:
+ SymbolRecordKind getKind() const { return Kind; }
+
+private:
+ SymbolRecordKind Kind;
+};
+
+// S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or
+// S_LPROC32_DPC_ID
+class ProcSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t PtrParent;
+ ulittle32_t PtrEnd;
+ ulittle32_t PtrNext;
+ ulittle32_t CodeSize;
+ ulittle32_t DbgStart;
+ ulittle32_t DbgEnd;
+ TypeIndex FunctionType;
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ uint8_t Flags; // ProcSymFlags enum
+ // Name: The null-terminated name follows.
+ };
+
+ ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H,
+ StringRef Name)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) {
+ }
+
+ static ErrorOr<ProcSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return ProcSym(Kind, RecordOffset, H, Name);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_THUNK32
+class Thunk32Sym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Parent;
+ ulittle32_t End;
+ ulittle32_t Next;
+ ulittle32_t Off;
+ ulittle16_t Seg;
+ ulittle16_t Len;
+ uint8_t Ord; // ThunkOrdinal enumeration
+ // Name: The null-terminated name follows.
+ // Variant portion of thunk
+ };
+
+ Thunk32Sym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H,
+ StringRef Name, ArrayRef<uint8_t> VariantData)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name),
+ VariantData(VariantData) {}
+
+ static ErrorOr<Thunk32Sym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ ArrayRef<uint8_t> VariantData;
+
+ CV_DESERIALIZE(Data, H, Name, CV_ARRAY_FIELD_TAIL(VariantData));
+
+ return Thunk32Sym(Kind, RecordOffset, H, Name, VariantData);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+ ArrayRef<uint8_t> VariantData;
+};
+
+// S_TRAMPOLINE
+class TrampolineSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle16_t Type; // TrampolineType enum
+ ulittle16_t Size;
+ ulittle32_t ThunkOff;
+ ulittle32_t TargetOff;
+ ulittle16_t ThunkSection;
+ ulittle16_t TargetSection;
+ };
+
+ TrampolineSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<TrampolineSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+
+ CV_DESERIALIZE(Data, H);
+
+ return TrampolineSym(Kind, RecordOffset, H);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+};
+
+// S_SECTION
+class SectionSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle16_t SectionNumber;
+ uint8_t Alignment;
+ uint8_t Reserved; // Must be 0
+ ulittle32_t Rva;
+ ulittle32_t Length;
+ ulittle32_t Characteristics;
+ // Name: The null-terminated name follows.
+ };
+
+ SectionSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H,
+ StringRef Name)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) {
+ }
+
+ static ErrorOr<SectionSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+
+ CV_DESERIALIZE(Data, H, Name);
+
+ return SectionSym(Kind, RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_COFFGROUP
+class CoffGroupSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Size;
+ ulittle32_t Characteristics;
+ ulittle32_t Offset;
+ ulittle16_t Segment;
+ // Name: The null-terminated name follows.
+ };
+
+ CoffGroupSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H,
+ StringRef Name)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) {
+ }
+
+ static ErrorOr<CoffGroupSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+
+ CV_DESERIALIZE(Data, H, Name);
+
+ return CoffGroupSym(Kind, RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+class ScopeEndSym : public SymbolRecord {
+public:
+ ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
+
+ static ErrorOr<ScopeEndSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ return ScopeEndSym(Kind, RecordOffset);
+ }
+ uint32_t RecordOffset;
+};
+
+class CallerSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Count;
+ };
+
+ CallerSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *Header,
+ ArrayRef<TypeIndex> Indices)
+ : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*Header),
+ Indices(Indices) {}
+
+ static ErrorOr<CallerSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *Header;
+ ArrayRef<TypeIndex> Indices;
+
+ CV_DESERIALIZE(Data, Header, CV_ARRAY_FIELD_N(Indices, Header->Count));
+
+ return CallerSym(Kind, RecordOffset, Header, Indices);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<TypeIndex> Indices;
+};
+
+struct BinaryAnnotationIterator {
+ struct AnnotationData {
+ BinaryAnnotationsOpCode OpCode;
+ StringRef Name;
+ uint32_t U1;
+ uint32_t U2;
+ int32_t S1;
+ };
+
+ BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
+ BinaryAnnotationIterator() {}
+ BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
+ : Data(Other.Data) {}
+
+ bool operator==(BinaryAnnotationIterator Other) const {
+ return Data == Other.Data;
+ }
+
+ bool operator!=(BinaryAnnotationIterator Other) const {
+ return !(*this == Other);
+ }
+
+ BinaryAnnotationIterator &operator=(const BinaryAnnotationIterator Other) {
+ Data = Other.Data;
+ return *this;
+ }
+
+ BinaryAnnotationIterator &operator++() {
+ if (!ParseCurrentAnnotation()) {
+ *this = BinaryAnnotationIterator();
+ return *this;
+ }
+ Data = Next;
+ Next = ArrayRef<uint8_t>();
+ Current.reset();
+ return *this;
+ }
+
+ BinaryAnnotationIterator operator++(int) {
+ BinaryAnnotationIterator Orig(*this);
+ ++(*this);
+ return Orig;
+ }
+
+ const AnnotationData &operator*() {
+ ParseCurrentAnnotation();
+ return Current.getValue();
+ }
+
+private:
+ static uint32_t GetCompressedAnnotation(ArrayRef<uint8_t> &Annotations) {
+ if (Annotations.empty())
+ return -1;
+
+ uint8_t FirstByte = Annotations.front();
+ Annotations = Annotations.drop_front();
+
+ if ((FirstByte & 0x80) == 0x00)
+ return FirstByte;
+
+ if (Annotations.empty())
+ return -1;
+
+ uint8_t SecondByte = Annotations.front();
+ Annotations = Annotations.drop_front();
+
+ if ((FirstByte & 0xC0) == 0x80)
+ return ((FirstByte & 0x3F) << 8) | SecondByte;
+
+ if (Annotations.empty())
+ return -1;
+
+ uint8_t ThirdByte = Annotations.front();
+ Annotations = Annotations.drop_front();
+
+ if (Annotations.empty())
+ return -1;
+
+ uint8_t FourthByte = Annotations.front();
+ Annotations = Annotations.drop_front();
+
+ if ((FirstByte & 0xE0) == 0xC0)
+ return ((FirstByte & 0x1F) << 24) | (SecondByte << 16) |
+ (ThirdByte << 8) | FourthByte;
+
+ return -1;
+ };
+
+ static int32_t DecodeSignedOperand(uint32_t Operand) {
+ if (Operand & 1)
+ return -(Operand >> 1);
+ return Operand >> 1;
+ };
+
+ static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) {
+ return DecodeSignedOperand(GetCompressedAnnotation(Annotations));
+ };
+
+ bool ParseCurrentAnnotation() {
+ if (Current.hasValue())
+ return true;
+
+ Next = Data;
+ uint32_t Op = GetCompressedAnnotation(Next);
+ AnnotationData Result;
+ Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op);
+ switch (Result.OpCode) {
+ case BinaryAnnotationsOpCode::Invalid:
+ Result.Name = "Invalid";
+ Next = ArrayRef<uint8_t>();
+ break;
+ case BinaryAnnotationsOpCode::CodeOffset:
+ Result.Name = "CodeOffset";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
+ Result.Name = "ChangeCodeOffsetBase";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffset:
+ Result.Name = "ChangeCodeOffset";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ Result.Name = "ChangeCodeLength";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeFile:
+ Result.Name = "ChangeFile";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeLineEndDelta:
+ Result.Name = "ChangeLineEndDelta";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeRangeKind:
+ Result.Name = "ChangeRangeKind";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeColumnStart:
+ Result.Name = "ChangeColumnStart";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeColumnEnd:
+ Result.Name = "ChangeColumnEnd";
+ Result.U1 = GetCompressedAnnotation(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeLineOffset:
+ Result.Name = "ChangeLineOffset";
+ Result.S1 = DecodeSignedOperand(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
+ Result.Name = "ChangeColumnEndDelta";
+ Result.S1 = DecodeSignedOperand(Next);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
+ Result.Name = "ChangeCodeOffsetAndLineOffset";
+ uint32_t Annotation = GetCompressedAnnotation(Next);
+ Result.S1 = DecodeSignedOperand(Annotation >> 4);
+ Result.U1 = Annotation & 0xf;
+ break;
+ }
+ case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
+ Result.Name = "ChangeCodeLengthAndCodeOffset";
+ Result.U1 = GetCompressedAnnotation(Next);
+ Result.U2 = GetCompressedAnnotation(Next);
+ break;
+ }
+ }
+ Current = Result;
+ return true;
+ }
+
+ Optional<AnnotationData> Current;
+ ArrayRef<uint8_t> Data;
+ ArrayRef<uint8_t> Next;
+};
+
+// S_INLINESITE
+class InlineSiteSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t PtrParent;
+ ulittle32_t PtrEnd;
+ TypeIndex Inlinee;
+ // BinaryAnnotations
+ };
+
+ InlineSiteSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<uint8_t> Annotations)
+ : SymbolRecord(SymbolRecordKind::InlineSiteSym),
+ RecordOffset(RecordOffset), Header(*H), Annotations(Annotations) {}
+
+ static ErrorOr<InlineSiteSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<uint8_t> Annotations;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Annotations));
+
+ return InlineSiteSym(RecordOffset, H, Annotations);
+ }
+
+ llvm::iterator_range<BinaryAnnotationIterator> annotations() const {
+ return llvm::make_range(BinaryAnnotationIterator(Annotations),
+ BinaryAnnotationIterator());
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+
+private:
+ ArrayRef<uint8_t> Annotations;
+};
+
+// S_PUB32
+class PublicSym32 : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Index; // Type index, or Metadata token if a managed symbol
+ ulittle32_t Off;
+ ulittle16_t Seg;
+ // Name: The null-terminated name follows.
+ };
+
+ PublicSym32(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::PublicSym32), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<PublicSym32> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return PublicSym32(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_REGISTER
+class RegisterSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Index; // Type index or Metadata token
+ ulittle16_t Register; // RegisterId enumeration
+ // Name: The null-terminated name follows.
+ };
+
+ RegisterSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::RegisterSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<RegisterSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return RegisterSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_PROCREF, S_LPROCREF
+class ProcRefSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t SumName; // SUC of the name (?)
+ ulittle32_t SymOffset; // Offset of actual symbol in $$Symbols
+ ulittle16_t Mod; // Module containing the actual symbol
+ // Name: The null-terminated name follows.
+ };
+
+ ProcRefSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<ProcRefSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return ProcRefSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_LOCAL
+class LocalSym : public SymbolRecord {
+public:
+ struct Hdr {
+ TypeIndex Type;
+ ulittle16_t Flags; // LocalSymFlags enum
+ // Name: The null-terminated name follows.
+ };
+
+ LocalSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::LocalSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<LocalSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return LocalSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+struct LocalVariableAddrRange {
+ ulittle32_t OffsetStart;
+ ulittle16_t ISectStart;
+ ulittle16_t Range;
+};
+
+struct LocalVariableAddrGap {
+ ulittle16_t GapStartOffset;
+ ulittle16_t Range;
+};
+
+enum : uint16_t { MaxDefRange = 0xf000 };
+
+// S_DEFRANGE
+class DefRangeSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Program;
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+
+ DefRangeSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeSym), RecordOffset(RecordOffset),
+ Header(*H), Gaps(Gaps) {}
+
+ static ErrorOr<DefRangeSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeSym(RecordOffset, H, Gaps);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+};
+
+// S_DEFRANGE_SUBFIELD
+class DefRangeSubfieldSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Program;
+ ulittle16_t OffsetInParent;
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+ DefRangeSubfieldSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym),
+ RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
+
+ static ErrorOr<DefRangeSubfieldSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeSubfieldSym(RecordOffset, H, Gaps);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+};
+
+// S_DEFRANGE_REGISTER
+class DefRangeRegisterSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle16_t Register;
+ ulittle16_t MayHaveNoName;
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+
+ DefRangeRegisterSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
+ RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
+
+ DefRangeRegisterSym(uint16_t Register, uint16_t MayHaveNoName,
+ uint32_t OffsetStart, uint16_t ISectStart, uint16_t Range,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym), RecordOffset(0),
+ Gaps(Gaps) {
+ Header.Register = Register;
+ Header.MayHaveNoName = MayHaveNoName;
+ Header.Range.OffsetStart = OffsetStart;
+ Header.Range.ISectStart = ISectStart;
+ Header.Range.Range = Range;
+ }
+
+ static ErrorOr<DefRangeRegisterSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeRegisterSym(RecordOffset, H, Gaps);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+};
+
+// S_DEFRANGE_SUBFIELD_REGISTER
+class DefRangeSubfieldRegisterSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle16_t Register; // Register to which the variable is relative
+ ulittle16_t MayHaveNoName;
+ ulittle32_t OffsetInParent;
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+
+ DefRangeSubfieldRegisterSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
+ RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
+
+ DefRangeSubfieldRegisterSym(uint16_t Register, uint16_t MayHaveNoName,
+ uint32_t OffsetInParent,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
+ RecordOffset(0), Gaps(Gaps) {
+ Header.Register = Register;
+ Header.MayHaveNoName = MayHaveNoName;
+ Header.OffsetInParent = OffsetInParent;
+ }
+
+ static ErrorOr<DefRangeSubfieldRegisterSym>
+ deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeSubfieldRegisterSym(RecordOffset, H, Gaps);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+};
+
+// S_DEFRANGE_FRAMEPOINTER_REL
+class DefRangeFramePointerRelSym : public SymbolRecord {
+public:
+ struct Hdr {
+ little32_t Offset; // Offset from the frame pointer register
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+
+ DefRangeFramePointerRelSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym),
+ RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
+
+ static ErrorOr<DefRangeFramePointerRelSym>
+ deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeFramePointerRelSym(RecordOffset, H, Gaps);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+};
+
+// S_DEFRANGE_REGISTER_REL
+class DefRangeRegisterRelSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle16_t BaseRegister;
+ ulittle16_t Flags;
+ little32_t BasePointerOffset;
+ LocalVariableAddrRange Range;
+ // LocalVariableAddrGap Gaps[];
+ };
+
+ DefRangeRegisterRelSym(uint32_t RecordOffset, const Hdr *H,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
+ RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {}
+
+ DefRangeRegisterRelSym(uint16_t BaseRegister, uint16_t Flags,
+ int32_t BasePointerOffset, uint32_t OffsetStart,
+ uint16_t ISectStart, uint16_t Range,
+ ArrayRef<LocalVariableAddrGap> Gaps)
+ : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym), RecordOffset(0),
+ Gaps(Gaps) {
+ Header.BaseRegister = BaseRegister;
+ Header.Flags = Flags;
+ Header.BasePointerOffset = BasePointerOffset;
+ Header.Range.OffsetStart = OffsetStart;
+ Header.Range.ISectStart = ISectStart;
+ Header.Range.Range = Range;
+ }
+
+ static ErrorOr<DefRangeRegisterRelSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+ CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps));
+
+ return DefRangeRegisterRelSym(RecordOffset, H, Gaps);
+ }
+
+ bool hasSpilledUDTMember() const { return Header.Flags & 1; }
+ uint16_t offsetInParent() const { return Header.Flags >> 4; }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, Range);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ ArrayRef<LocalVariableAddrGap> Gaps;
+};
+
+// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
+class DefRangeFramePointerRelFullScopeSym : public SymbolRecord {
+public:
+ struct Hdr {
+ little32_t Offset; // Offset from the frame pointer register
+ };
+
+ DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<DefRangeFramePointerRelFullScopeSym>
+ deserialize(SymbolRecordKind Kind, uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return DefRangeFramePointerRelFullScopeSym(RecordOffset, H);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+};
+
+// S_BLOCK32
+class BlockSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t PtrParent;
+ ulittle32_t PtrEnd;
+ ulittle32_t CodeSize;
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ // Name: The null-terminated name follows.
+ };
+
+ BlockSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<BlockSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return BlockSym(RecordOffset, H, Name);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_LABEL32
+class LabelSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ uint8_t Flags; // CV_PROCFLAGS
+ // Name: The null-terminated name follows.
+ };
+
+ LabelSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<LabelSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return LabelSym(RecordOffset, H, Name);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_OBJNAME
+class ObjNameSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Signature;
+ // Name: The null-terminated name follows.
+ };
+
+ ObjNameSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<ObjNameSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return ObjNameSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_ENVBLOCK
+class EnvBlockSym : public SymbolRecord {
+public:
+ struct Hdr {
+ uint8_t Reserved;
+ // Sequence of zero terminated strings.
+ };
+
+ EnvBlockSym(uint32_t RecordOffset, const Hdr *H,
+ const std::vector<StringRef> &Fields)
+ : SymbolRecord(SymbolRecordKind::EnvBlockSym), RecordOffset(RecordOffset),
+ Header(*H), Fields(Fields) {}
+
+ static ErrorOr<EnvBlockSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ std::vector<StringRef> Fields;
+ CV_DESERIALIZE(Data, H, CV_STRING_ARRAY_NULL_TERM(Fields));
+
+ return EnvBlockSym(RecordOffset, H, Fields);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ std::vector<StringRef> Fields;
+};
+
+// S_EXPORT
+class ExportSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle16_t Ordinal;
+ ulittle16_t Flags; // ExportFlags
+ // Name: The null-terminated name follows.
+ };
+
+ ExportSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<ExportSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return ExportSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_FILESTATIC
+class FileStaticSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Index; // Type Index
+ ulittle32_t ModFilenameOffset; // Index of mod filename in string table
+ ulittle16_t Flags; // LocalSymFlags enum
+ // Name: The null-terminated name follows.
+ };
+
+ FileStaticSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::FileStaticSym),
+ RecordOffset(RecordOffset), Header(*H), Name(Name) {}
+
+ static ErrorOr<FileStaticSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return FileStaticSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_COMPILE2
+class Compile2Sym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t flags; // CompileSym2Flags enum
+ uint8_t getLanguage() const { return flags & 0xFF; }
+ unsigned short Machine; // CPUType enum
+ unsigned short VersionFrontendMajor;
+ unsigned short VersionFrontendMinor;
+ unsigned short VersionFrontendBuild;
+ unsigned short VersionBackendMajor;
+ unsigned short VersionBackendMinor;
+ unsigned short VersionBackendBuild;
+ // Version: The null-terminated version string follows.
+ // Optional block of zero terminated strings terminated with a double zero.
+ };
+
+ Compile2Sym(uint32_t RecordOffset, const Hdr *H, StringRef Version)
+ : SymbolRecord(SymbolRecordKind::Compile2Sym), RecordOffset(RecordOffset),
+ Header(*H), Version(Version) {}
+
+ static ErrorOr<Compile2Sym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Version;
+ CV_DESERIALIZE(Data, H, Version);
+
+ return Compile2Sym(RecordOffset, H, Version);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Version;
+};
+
+// S_COMPILE3
+class Compile3Sym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t flags; // CompileSym3Flags enum
+ uint8_t getLanguage() const { return flags & 0xff; }
+ ulittle16_t Machine; // CPUType enum
+ ulittle16_t VersionFrontendMajor;
+ ulittle16_t VersionFrontendMinor;
+ ulittle16_t VersionFrontendBuild;
+ ulittle16_t VersionFrontendQFE;
+ ulittle16_t VersionBackendMajor;
+ ulittle16_t VersionBackendMinor;
+ ulittle16_t VersionBackendBuild;
+ ulittle16_t VersionBackendQFE;
+ // VersionString: The null-terminated version string follows.
+ };
+
+ Compile3Sym(uint32_t RecordOffset, const Hdr *H, StringRef Version)
+ : SymbolRecord(SymbolRecordKind::Compile3Sym), RecordOffset(RecordOffset),
+ Header(*H), Version(Version) {}
+
+ static ErrorOr<Compile3Sym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Version;
+ CV_DESERIALIZE(Data, H, Version);
+
+ return Compile3Sym(RecordOffset, H, Version);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Version;
+};
+
+// S_FRAMEPROC
+class FrameProcSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t TotalFrameBytes;
+ ulittle32_t PaddingFrameBytes;
+ ulittle32_t OffsetToPadding;
+ ulittle32_t BytesOfCalleeSavedRegisters;
+ ulittle32_t OffsetOfExceptionHandler;
+ ulittle16_t SectionIdOfExceptionHandler;
+ ulittle32_t Flags;
+ };
+
+ FrameProcSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::FrameProcSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<FrameProcSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return FrameProcSym(RecordOffset, H);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+};
+
+// S_CALLSITEINFO
+class CallSiteInfoSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ ulittle16_t Reserved;
+ TypeIndex Type;
+ };
+
+ CallSiteInfoSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::CallSiteInfoSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<CallSiteInfoSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return CallSiteInfoSym(RecordOffset, H);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+};
+
+// S_HEAPALLOCSITE
+class HeapAllocationSiteSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ ulittle16_t CallInstructionSize;
+ TypeIndex Type;
+ };
+
+ HeapAllocationSiteSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<HeapAllocationSiteSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return HeapAllocationSiteSym(RecordOffset, H);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+};
+
+// S_FRAMECOOKIE
+class FrameCookieSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t CodeOffset;
+ ulittle16_t Register;
+ uint8_t CookieKind;
+ uint8_t Flags;
+ };
+
+ FrameCookieSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::FrameCookieSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<FrameCookieSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return FrameCookieSym(RecordOffset, H);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, CodeOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+};
+
+// S_UDT, S_COBOLUDT
+class UDTSym : public SymbolRecord {
+public:
+ struct Hdr {
+ TypeIndex Type; // Type of the UDT
+ // Name: The null-terminated name follows.
+ };
+
+ UDTSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::UDTSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<UDTSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return UDTSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_BUILDINFO
+class BuildInfoSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t BuildId;
+ };
+
+ BuildInfoSym(uint32_t RecordOffset, const Hdr *H)
+ : SymbolRecord(SymbolRecordKind::BuildInfoSym),
+ RecordOffset(RecordOffset), Header(*H) {}
+
+ static ErrorOr<BuildInfoSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ CV_DESERIALIZE(Data, H);
+
+ return BuildInfoSym(RecordOffset, H);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+};
+
+// S_BPREL32
+class BPRelativeSym : public SymbolRecord {
+public:
+ struct Hdr {
+ little32_t Offset; // Offset from the base pointer register
+ TypeIndex Type; // Type of the variable
+ // Name: The null-terminated name follows.
+ };
+
+ BPRelativeSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::BPRelativeSym),
+ RecordOffset(RecordOffset), Header(*H), Name(Name) {}
+
+ static ErrorOr<BPRelativeSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return BPRelativeSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_REGREL32
+class RegRelativeSym : public SymbolRecord {
+public:
+ struct Hdr {
+ ulittle32_t Offset; // Offset from the register
+ TypeIndex Type; // Type of the variable
+ ulittle16_t Register; // Register to which the variable is relative
+ // Name: The null-terminated name follows.
+ };
+
+ RegRelativeSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::RegRelativeSym),
+ RecordOffset(RecordOffset), Header(*H), Name(Name) {}
+
+ static ErrorOr<RegRelativeSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return RegRelativeSym(RecordOffset, H, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_CONSTANT, S_MANCONSTANT
+class ConstantSym : public SymbolRecord {
+public:
+ struct Hdr {
+ TypeIndex Type;
+ // Value: The value of the constant.
+ // Name: The null-terminated name follows.
+ };
+
+ ConstantSym(uint32_t RecordOffset, const Hdr *H, const APSInt &Value,
+ StringRef Name)
+ : SymbolRecord(SymbolRecordKind::ConstantSym), RecordOffset(RecordOffset),
+ Header(*H), Value(Value), Name(Name) {}
+
+ static ErrorOr<ConstantSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ APSInt Value;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Value, Name);
+
+ return ConstantSym(RecordOffset, H, Value, Name);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ APSInt Value;
+ StringRef Name;
+};
+
+// S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
+class DataSym : public SymbolRecord {
+public:
+ struct Hdr {
+ TypeIndex Type;
+ ulittle32_t DataOffset;
+ ulittle16_t Segment;
+ // Name: The null-terminated name follows.
+ };
+
+ DataSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset),
+ Header(*H), Name(Name) {}
+
+ static ErrorOr<DataSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return DataSym(RecordOffset, H, Name);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, DataOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+// S_LTHREAD32, S_GTHREAD32
+class ThreadLocalDataSym : public SymbolRecord {
+public:
+ struct Hdr {
+ TypeIndex Type;
+ ulittle32_t DataOffset;
+ ulittle16_t Segment;
+ // Name: The null-terminated name follows.
+ };
+
+ ThreadLocalDataSym(uint32_t RecordOffset, const Hdr *H, StringRef Name)
+ : SymbolRecord(SymbolRecordKind::ThreadLocalDataSym),
+ RecordOffset(RecordOffset), Header(*H), Name(Name) {}
+
+ static ErrorOr<ThreadLocalDataSym> deserialize(SymbolRecordKind Kind,
+ uint32_t RecordOffset,
+ ArrayRef<uint8_t> &Data) {
+ const Hdr *H = nullptr;
+ StringRef Name;
+ CV_DESERIALIZE(Data, H, Name);
+
+ return ThreadLocalDataSym(RecordOffset, H, Name);
+ }
+
+ uint32_t getRelocationOffset() const {
+ return RecordOffset + offsetof(Hdr, DataOffset);
+ }
+
+ uint32_t RecordOffset;
+ Hdr Header;
+ StringRef Name;
+};
+
+typedef CVRecord<SymbolKind> CVSymbol;
+typedef VarStreamArray<CVSymbol> CVSymbolArray;
+
+} // namespace codeview
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
new file mode 100644
index 000000000000..a4965168c3db
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
@@ -0,0 +1,33 @@
+//===-- SymbolVisitorDelegate.h ---------------------------------*- 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_CODEVIEW_SYMBOLVISITORDELEGATE_H
+#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORDELEGATE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <stdint.h>
+
+namespace llvm {
+
+namespace codeview {
+
+class SymbolVisitorDelegate {
+public:
+ virtual ~SymbolVisitorDelegate() {}
+
+ virtual uint32_t getRecordOffset(ArrayRef<uint8_t> Record) = 0;
+ virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0;
+ virtual StringRef getStringTable() = 0;
+};
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLVISITORDELEGATE_H
diff --git a/include/llvm/DebugInfo/CodeView/TypeDumper.h b/include/llvm/DebugInfo/CodeView/TypeDumper.h
new file mode 100644
index 000000000000..ca79ab076e5e
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/TypeDumper.h
@@ -0,0 +1,105 @@
+//===-- TypeDumper.h - CodeView type info dumper ----------------*- 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_CODEVIEW_TYPEDUMPER_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+
+namespace llvm {
+class ScopedPrinter;
+
+namespace codeview {
+
+/// Dumper for CodeView type streams found in COFF object files and PDB files.
+class CVTypeDumper : public TypeVisitorCallbacks {
+public:
+ CVTypeDumper(ScopedPrinter *W, bool PrintRecordBytes)
+ : W(W), PrintRecordBytes(PrintRecordBytes) {}
+
+ StringRef getTypeName(TypeIndex TI);
+ void printTypeIndex(StringRef FieldName, TypeIndex TI);
+
+ /// Dumps one type record. Returns false if there was a type parsing error,
+ /// and true otherwise. This should be called in order, since the dumper
+ /// maintains state about previous records which are necessary for cross
+ /// type references.
+ Error dump(const CVRecord<TypeLeafKind> &Record);
+
+ /// Dumps the type records in Types. Returns false if there was a type stream
+ /// parse error, and true otherwise.
+ Error dump(const CVTypeArray &Types);
+
+ /// Dumps the type records in Data. Returns false if there was a type stream
+ /// parse error, and true otherwise. Use this method instead of the
+ /// CVTypeArray overload when type records are laid out contiguously in
+ /// memory.
+ Error dump(ArrayRef<uint8_t> Data);
+
+ /// Gets the type index for the next type record.
+ unsigned getNextTypeIndex() const {
+ return 0x1000 + CVUDTNames.size();
+ }
+
+ /// Records the name of a type, and reserves its type index.
+ void recordType(StringRef Name) { CVUDTNames.push_back(Name); }
+
+ /// Saves the name in a StringSet and creates a stable StringRef.
+ StringRef saveName(StringRef TypeName) {
+ return TypeNames.insert(TypeName).first->getKey();
+ }
+
+ void setPrinter(ScopedPrinter *P);
+ ScopedPrinter *getPrinter() { return W; }
+
+ /// Action to take on unknown types. By default, they are ignored.
+ Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) override;
+ Error visitUnknownMember(const CVRecord<TypeLeafKind> &Record) override;
+
+ /// Paired begin/end actions for all types. Receives all record data,
+ /// including the fixed-length record prefix.
+ Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
+ Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override;
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ Error visit##Name(Name##Record &Record) override;
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ TYPE_RECORD(EnumName, EnumVal, Name)
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "TypeRecords.def"
+
+private:
+ void printMemberAttributes(MemberAttributes Attrs);
+ void printMemberAttributes(MemberAccess Access, MethodKind Kind,
+ MethodOptions Options);
+
+ ScopedPrinter *W;
+
+ bool PrintRecordBytes = false;
+
+ /// Name of the current type. Only valid before visitTypeEnd.
+ StringRef Name;
+
+ /// All user defined type records in .debug$T live in here. Type indices
+ /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
+ /// index into this vector.
+ SmallVector<StringRef, 10> CVUDTNames;
+
+ StringSet<> TypeNames;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
diff --git a/include/llvm/DebugInfo/CodeView/TypeIndex.h b/include/llvm/DebugInfo/CodeView/TypeIndex.h
index d3a541be4c62..c2ebf3848892 100644
--- a/include/llvm/DebugInfo/CodeView/TypeIndex.h
+++ b/include/llvm/DebugInfo/CodeView/TypeIndex.h
@@ -10,6 +10,7 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
+#include "llvm/Support/Endian.h"
#include <cassert>
#include <cinttypes>
@@ -26,6 +27,8 @@ enum class SimpleTypeKind : uint32_t {
UnsignedCharacter = 0x0020, // 8 bit unsigned
NarrowCharacter = 0x0070, // really a char
WideCharacter = 0x0071, // wide char
+ Character16 = 0x007a, // char16_t
+ Character32 = 0x007b, // char32_t
SByte = 0x0068, // 8 bit signed int
Byte = 0x0069, // 8 bit unsigned int
@@ -41,6 +44,8 @@ enum class SimpleTypeKind : uint32_t {
UInt64Quad = 0x0023, // 64 bit unsigned
Int64 = 0x0076, // 64 bit signed int
UInt64 = 0x0077, // 64 bit unsigned int
+ Int128Oct = 0x0014, // 128 bit signed int
+ UInt128Oct = 0x0024, // 128 bit unsigned int
Int128 = 0x0078, // 128 bit signed int
UInt128 = 0x0079, // 128 bit unsigned int
@@ -52,15 +57,19 @@ enum class SimpleTypeKind : uint32_t {
Float80 = 0x0042, // 80 bit real
Float128 = 0x0043, // 128 bit real
- Complex32 = 0x0050, // 32 bit complex
- Complex64 = 0x0051, // 64 bit complex
- Complex80 = 0x0052, // 80 bit complex
- Complex128 = 0x0053, // 128 bit complex
-
- Boolean8 = 0x0030, // 8 bit boolean
- Boolean16 = 0x0031, // 16 bit boolean
- Boolean32 = 0x0032, // 32 bit boolean
- Boolean64 = 0x0033 // 64 bit boolean
+ Complex16 = 0x0056, // 16 bit complex
+ Complex32 = 0x0050, // 32 bit complex
+ Complex32PartialPrecision = 0x0055, // 32 bit PP complex
+ Complex48 = 0x0054, // 48 bit complex
+ Complex64 = 0x0051, // 64 bit complex
+ Complex80 = 0x0052, // 80 bit complex
+ Complex128 = 0x0053, // 128 bit complex
+
+ Boolean8 = 0x0030, // 8 bit boolean
+ Boolean16 = 0x0031, // 16 bit boolean
+ Boolean32 = 0x0032, // 32 bit boolean
+ Boolean64 = 0x0033, // 64 bit boolean
+ Boolean128 = 0x0034, // 128 bit boolean
};
enum class SimpleTypeMode : uint32_t {
@@ -74,6 +83,9 @@ enum class SimpleTypeMode : uint32_t {
NearPointer128 = 0x00000700 // 128 bit near pointer
};
+/// A 32-bit type reference. Types are indexed by their order of appearance in
+/// .debug$T plus 0x1000. Type indices less than 0x1000 are "simple" types,
+/// composed of a SimpleTypeMode byte followed by a SimpleTypeKind byte.
class TypeIndex {
public:
static const uint32_t FirstNonSimpleIndex = 0x1000;
@@ -91,6 +103,8 @@ public:
uint32_t getIndex() const { return Index; }
bool isSimple() const { return Index < FirstNonSimpleIndex; }
+ bool isNoneType() const { return *this == None(); }
+
SimpleTypeKind getSimpleKind() const {
assert(isSimple());
return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
@@ -101,6 +115,7 @@ public:
return static_cast<SimpleTypeMode>(Index & SimpleModeMask);
}
+ static TypeIndex None() { return TypeIndex(SimpleTypeKind::None); }
static TypeIndex Void() { return TypeIndex(SimpleTypeKind::Void); }
static TypeIndex VoidPointer32() {
return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer32);
@@ -143,33 +158,34 @@ public:
static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); }
static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }
-private:
- uint32_t Index;
-};
+ friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() == B.getIndex();
+ }
-inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
- return A.getIndex() == B.getIndex();
-}
+ friend inline bool operator!=(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() != B.getIndex();
+ }
-inline bool operator!=(const TypeIndex &A, const TypeIndex &B) {
- return A.getIndex() != B.getIndex();
-}
+ friend inline bool operator<(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() < B.getIndex();
+ }
-inline bool operator<(const TypeIndex &A, const TypeIndex &B) {
- return A.getIndex() < B.getIndex();
-}
+ friend inline bool operator<=(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() <= B.getIndex();
+ }
-inline bool operator<=(const TypeIndex &A, const TypeIndex &B) {
- return A.getIndex() <= B.getIndex();
-}
+ friend inline bool operator>(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() > B.getIndex();
+ }
-inline bool operator>(const TypeIndex &A, const TypeIndex &B) {
- return A.getIndex() > B.getIndex();
-}
+ friend inline bool operator>=(const TypeIndex &A, const TypeIndex &B) {
+ return A.getIndex() >= B.getIndex();
+ }
+
+private:
+ support::ulittle32_t Index;
+};
-inline bool operator>=(const TypeIndex &A, const TypeIndex &B) {
- return A.getIndex() >= B.getIndex();
-}
}
}
diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h
index 21755f5d9b09..42751fbd4af1 100644
--- a/include/llvm/DebugInfo/CodeView/TypeRecord.h
+++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h
@@ -10,15 +10,96 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/ErrorOr.h"
#include <cinttypes>
+#include <utility>
namespace llvm {
namespace codeview {
+using llvm::support::little32_t;
+using llvm::support::ulittle16_t;
+using llvm::support::ulittle32_t;
+
+/// Equvalent to CV_fldattr_t in cvinfo.h.
+struct MemberAttributes {
+ ulittle16_t Attrs;
+ enum {
+ MethodKindShift = 2,
+ };
+
+ /// Get the access specifier. Valid for any kind of member.
+ MemberAccess getAccess() const {
+ return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
+ }
+
+ /// Indicates if a method is defined with friend, virtual, static, etc.
+ MethodKind getMethodKind() const {
+ return MethodKind(
+ (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
+ MethodKindShift);
+ }
+
+ /// Get the flags that are not included in access control or method
+ /// properties.
+ MethodOptions getFlags() const {
+ return MethodOptions(
+ unsigned(Attrs) &
+ ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
+ }
+
+ /// Is this method virtual.
+ bool isVirtual() const {
+ auto MP = getMethodKind();
+ return MP != MethodKind::Vanilla && MP != MethodKind::Friend &&
+ MP != MethodKind::Static;
+ }
+
+ /// Does this member introduce a new virtual method.
+ bool isIntroducedVirtual() const {
+ auto MP = getMethodKind();
+ return MP == MethodKind::IntroducingVirtual ||
+ MP == MethodKind::PureIntroducingVirtual;
+ }
+};
+
+// Does not correspond to any tag, this is the tail of an LF_POINTER record
+// if it represents a member pointer.
+class MemberPointerInfo {
+public:
+ MemberPointerInfo() {}
+
+ MemberPointerInfo(TypeIndex ContainingType,
+ PointerToMemberRepresentation Representation)
+ : ContainingType(ContainingType), Representation(Representation) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<MemberPointerInfo> deserialize(ArrayRef<uint8_t> &Data);
+
+ TypeIndex getContainingType() const { return ContainingType; }
+ PointerToMemberRepresentation getRepresentation() const {
+ return Representation;
+ }
+
+private:
+ struct Layout {
+ TypeIndex ClassType;
+ ulittle16_t Representation; // PointerToMemberRepresentation
+ };
+
+ TypeIndex ContainingType;
+ PointerToMemberRepresentation Representation;
+};
+
class TypeRecord {
protected:
explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
@@ -30,20 +111,34 @@ private:
TypeRecordKind Kind;
};
+// LF_MODIFIER
class ModifierRecord : public TypeRecord {
public:
- ModifierRecord(TypeIndex ModifiedType, ModifierOptions Options)
+ ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
: TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
- Options(Options) {}
+ Modifiers(Modifiers) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<ModifierRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getModifiedType() const { return ModifiedType; }
- ModifierOptions getOptions() const { return Options; }
+ ModifierOptions getModifiers() const { return Modifiers; }
private:
+ struct Layout {
+ TypeIndex ModifiedType;
+ ulittle16_t Modifiers; // ModifierOptions
+ };
+
TypeIndex ModifiedType;
- ModifierOptions Options;
+ ModifierOptions Modifiers;
};
+// LF_PROCEDURE
class ProcedureRecord : public TypeRecord {
public:
ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
@@ -53,6 +148,15 @@ public:
CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
ArgumentList(ArgumentList) {}
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<ProcedureRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
+
TypeIndex getReturnType() const { return ReturnType; }
CallingConvention getCallConv() const { return CallConv; }
FunctionOptions getOptions() const { return Options; }
@@ -60,6 +164,14 @@ public:
TypeIndex getArgumentList() const { return ArgumentList; }
private:
+ struct Layout {
+ TypeIndex ReturnType;
+ CallingConvention CallConv;
+ FunctionOptions Options;
+ ulittle16_t NumParameters;
+ TypeIndex ArgListType;
+ };
+
TypeIndex ReturnType;
CallingConvention CallConv;
FunctionOptions Options;
@@ -67,6 +179,7 @@ private:
TypeIndex ArgumentList;
};
+// LF_MFUNCTION
class MemberFunctionRecord : public TypeRecord {
public:
MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
@@ -79,6 +192,13 @@ public:
ArgumentList(ArgumentList),
ThisPointerAdjustment(ThisPointerAdjustment) {}
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<MemberFunctionRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
TypeIndex getReturnType() const { return ReturnType; }
TypeIndex getClassType() const { return ClassType; }
TypeIndex getThisType() const { return ThisType; }
@@ -89,6 +209,17 @@ public:
int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }
private:
+ struct Layout {
+ TypeIndex ReturnType;
+ TypeIndex ClassType;
+ TypeIndex ThisType;
+ CallingConvention CallConv;
+ FunctionOptions Options;
+ ulittle16_t NumParameters;
+ TypeIndex ArgListType;
+ little32_t ThisAdjustment;
+ };
+
TypeIndex ReturnType;
TypeIndex ClassType;
TypeIndex ThisType;
@@ -99,78 +230,210 @@ private:
int32_t ThisPointerAdjustment;
};
-class ArgumentListRecord : public TypeRecord {
+// LF_MFUNC_ID
+class MemberFuncIdRecord : public TypeRecord {
public:
- explicit ArgumentListRecord(llvm::ArrayRef<TypeIndex> ArgumentTypes)
- : TypeRecord(TypeRecordKind::ArgumentList), ArgumentTypes(ArgumentTypes) {
- }
+ MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
+ StringRef Name)
+ : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
+ FunctionType(FunctionType), Name(Name) {}
- llvm::ArrayRef<TypeIndex> getArgumentTypes() const { return ArgumentTypes; }
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<MemberFuncIdRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+ TypeIndex getClassType() const { return ClassType; }
+ TypeIndex getFunctionType() const { return FunctionType; }
+ StringRef getName() const { return Name; }
private:
- llvm::ArrayRef<TypeIndex> ArgumentTypes;
+ struct Layout {
+ TypeIndex ClassType;
+ TypeIndex FunctionType;
+ // Name: The null-terminated name follows.
+ };
+ TypeIndex ClassType;
+ TypeIndex FunctionType;
+ StringRef Name;
};
-class PointerRecordBase : public TypeRecord {
+// LF_ARGLIST, LF_SUBSTR_LIST
+class ArgListRecord : public TypeRecord {
public:
- PointerRecordBase(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
- PointerOptions Options, uint8_t Size)
+ ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
+ : TypeRecord(Kind), StringIndices(Indices) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<ArgListRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
+
+ static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
+
+private:
+ struct Layout {
+ ulittle32_t NumArgs; // Number of arguments
+ // ArgTypes[]: Type indicies of arguments
+ };
+
+ std::vector<TypeIndex> StringIndices;
+};
+
+// LF_POINTER
+class PointerRecord : public TypeRecord {
+public:
+ static const uint32_t PointerKindShift = 0;
+ static const uint32_t PointerKindMask = 0x1F;
+
+ static const uint32_t PointerModeShift = 5;
+ static const uint32_t PointerModeMask = 0x07;
+
+ static const uint32_t PointerSizeShift = 13;
+ static const uint32_t PointerSizeMask = 0xFF;
+
+ PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
+ PointerOptions Options, uint8_t Size)
+ : PointerRecord(ReferentType, Kind, Mode, Options, Size,
+ MemberPointerInfo()) {}
+
+ PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
+ PointerOptions Options, uint8_t Size,
+ const MemberPointerInfo &Member)
: TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
- PtrKind(Kind), Mode(Mode), Options(Options), Size(Size) {}
+ PtrKind(Kind), Mode(Mode), Options(Options), Size(Size),
+ MemberInfo(Member) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<PointerRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
TypeIndex getReferentType() const { return ReferentType; }
PointerKind getPointerKind() const { return PtrKind; }
PointerMode getMode() const { return Mode; }
PointerOptions getOptions() const { return Options; }
uint8_t getSize() const { return Size; }
+ MemberPointerInfo getMemberInfo() const { return MemberInfo; }
+
+ bool isPointerToMember() const {
+ return Mode == PointerMode::PointerToDataMember ||
+ Mode == PointerMode::PointerToMemberFunction;
+ }
+ bool isFlat() const {
+ return !!(uint32_t(Options) & uint32_t(PointerOptions::Flat32));
+ }
+ bool isConst() const {
+ return !!(uint32_t(Options) & uint32_t(PointerOptions::Const));
+ }
+ bool isVolatile() const {
+ return !!(uint32_t(Options) & uint32_t(PointerOptions::Volatile));
+ }
+ bool isUnaligned() const {
+ return !!(uint32_t(Options) & uint32_t(PointerOptions::Unaligned));
+ }
private:
+ struct Layout {
+ TypeIndex PointeeType;
+ ulittle32_t Attrs; // pointer attributes
+ // if pointer to member:
+ // PointerToMemberTail
+ PointerKind getPtrKind() const {
+ return PointerKind(Attrs & PointerKindMask);
+ }
+ PointerMode getPtrMode() const {
+ return PointerMode((Attrs >> PointerModeShift) & PointerModeMask);
+ }
+ uint8_t getPtrSize() const {
+ return (Attrs >> PointerSizeShift) & PointerSizeMask;
+ }
+ bool isFlat() const { return Attrs & (1 << 8); }
+ bool isVolatile() const { return Attrs & (1 << 9); }
+ bool isConst() const { return Attrs & (1 << 10); }
+ bool isUnaligned() const { return Attrs & (1 << 11); }
+
+ bool isPointerToDataMember() const {
+ return getPtrMode() == PointerMode::PointerToDataMember;
+ }
+ bool isPointerToMemberFunction() const {
+ return getPtrMode() == PointerMode::PointerToMemberFunction;
+ }
+ bool isPointerToMember() const {
+ return isPointerToMemberFunction() || isPointerToDataMember();
+ }
+ };
+
TypeIndex ReferentType;
PointerKind PtrKind;
PointerMode Mode;
PointerOptions Options;
uint8_t Size;
+ MemberPointerInfo MemberInfo;
};
-class PointerRecord : public PointerRecordBase {
+// LF_NESTTYPE
+class NestedTypeRecord : public TypeRecord {
public:
- PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
- PointerOptions Options, uint8_t Size)
- : PointerRecordBase(ReferentType, Kind, Mode, Options, Size) {}
-};
+ NestedTypeRecord(TypeIndex Type, StringRef Name)
+ : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
-class PointerToMemberRecord : public PointerRecordBase {
-public:
- PointerToMemberRecord(TypeIndex ReferentType, PointerKind Kind,
- PointerMode Mode, PointerOptions Options, uint8_t Size,
- TypeIndex ContainingType,
- PointerToMemberRepresentation Representation)
- : PointerRecordBase(ReferentType, Kind, Mode, Options, Size),
- ContainingType(ContainingType), Representation(Representation) {}
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
- TypeIndex getContainingType() const { return ContainingType; }
- PointerToMemberRepresentation getRepresentation() const {
- return Representation;
- }
+ static ErrorOr<NestedTypeRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ TypeIndex getNestedType() const { return Type; }
+ StringRef getName() const { return Name; }
private:
- TypeIndex ContainingType;
- PointerToMemberRepresentation Representation;
+ struct Layout {
+ ulittle16_t Pad0; // Should be zero
+ TypeIndex Type; // Type index of nested type
+ // Name: Null-terminated string
+ };
+
+ TypeIndex Type;
+ StringRef Name;
};
+// LF_ARRAY
class ArrayRecord : public TypeRecord {
public:
ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
- llvm::StringRef Name)
+ StringRef Name)
: TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
IndexType(IndexType), Size(Size), Name(Name) {}
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<ArrayRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
TypeIndex getElementType() const { return ElementType; }
TypeIndex getIndexType() const { return IndexType; }
uint64_t getSize() const { return Size; }
llvm::StringRef getName() const { return Name; }
private:
+ struct Layout {
+ TypeIndex ElementType;
+ TypeIndex IndexType;
+ // SizeOf: LF_NUMERIC encoded size in bytes. Not element count!
+ // Name: The null-terminated name follows.
+ };
+
TypeIndex ElementType;
TypeIndex IndexType;
uint64_t Size;
@@ -185,6 +448,15 @@ protected:
FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
public:
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static const int HfaKindShift = 11;
+ static const int HfaKindMask = 0x1800;
+ static const int WinRTKindShift = 14;
+ static const int WinRTKindMask = 0xC000;
+
uint16_t getMemberCount() const { return MemberCount; }
ClassOptions getOptions() const { return Options; }
TypeIndex getFieldList() const { return FieldList; }
@@ -199,17 +471,24 @@ private:
StringRef UniqueName;
};
-class AggregateRecord : public TagRecord {
+// LF_CLASS, LF_STRUCTURE, LF_INTERFACE
+class ClassRecord : public TagRecord {
public:
- AggregateRecord(TypeRecordKind Kind, uint16_t MemberCount,
- ClassOptions Options, HfaKind Hfa,
- WindowsRTClassKind WinRTKind, TypeIndex FieldList,
- TypeIndex DerivationList, TypeIndex VTableShape,
- uint64_t Size, StringRef Name, StringRef UniqueName)
+ ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
+ HfaKind Hfa, WindowsRTClassKind WinRTKind, TypeIndex FieldList,
+ TypeIndex DerivationList, TypeIndex VTableShape, uint64_t Size,
+ StringRef Name, StringRef UniqueName)
: TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
Hfa(Hfa), WinRTKind(WinRTKind), DerivationList(DerivationList),
VTableShape(VTableShape), Size(Size) {}
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<ClassRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
HfaKind getHfa() const { return Hfa; }
WindowsRTClassKind getWinRTKind() const { return WinRTKind; }
TypeIndex getDerivationList() const { return DerivationList; }
@@ -217,6 +496,21 @@ public:
uint64_t getSize() const { return Size; }
private:
+ struct Layout {
+ ulittle16_t MemberCount; // Number of members in FieldList.
+ ulittle16_t Properties; // ClassOptions bitset
+ TypeIndex FieldList; // LF_FIELDLIST: List of all kinds of members
+ TypeIndex DerivedFrom; // LF_DERIVED: List of known derived classes
+ TypeIndex VShape; // LF_VTSHAPE: Shape of the vftable
+ // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC
+ // integer.
+ // Name: The null-terminated name follows.
+
+ bool hasUniqueName() const {
+ return Properties & uint16_t(ClassOptions::HasUniqueName);
+ }
+ };
+
HfaKind Hfa;
WindowsRTClassKind WinRTKind;
TypeIndex DerivationList;
@@ -224,6 +518,40 @@ private:
uint64_t Size;
};
+// LF_UNION
+struct UnionRecord : public TagRecord {
+ UnionRecord(uint16_t MemberCount, ClassOptions Options, HfaKind Hfa,
+ TypeIndex FieldList, uint64_t Size, StringRef Name,
+ StringRef UniqueName)
+ : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
+ UniqueName),
+ Hfa(Hfa), Size(Size) {}
+
+ static ErrorOr<UnionRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ HfaKind getHfa() const { return Hfa; }
+ uint64_t getSize() const { return Size; }
+
+private:
+ struct Layout {
+ ulittle16_t MemberCount; // Number of members in FieldList.
+ ulittle16_t Properties; // ClassOptions bitset
+ TypeIndex FieldList; // LF_FIELDLIST: List of all kinds of members
+ // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC
+ // integer.
+ // Name: The null-terminated name follows.
+
+ bool hasUniqueName() const {
+ return Properties & uint16_t(ClassOptions::HasUniqueName);
+ }
+ };
+
+ HfaKind Hfa;
+ uint64_t Size;
+};
+
+// LF_ENUM
class EnumRecord : public TagRecord {
public:
EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
@@ -232,38 +560,642 @@ public:
UniqueName),
UnderlyingType(UnderlyingType) {}
+ /// Rewrite member type indices with IndexMap. Returns false if a type index is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<EnumRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
TypeIndex getUnderlyingType() const { return UnderlyingType; }
private:
+ struct Layout {
+ ulittle16_t NumEnumerators; // Number of enumerators
+ ulittle16_t Properties;
+ TypeIndex UnderlyingType;
+ TypeIndex FieldListType;
+ // Name: The null-terminated name follows.
+
+ bool hasUniqueName() const {
+ return Properties & uint16_t(ClassOptions::HasUniqueName);
+ }
+ };
+
TypeIndex UnderlyingType;
};
-class BitFieldRecord : TypeRecord {
+// LF_BITFIELD
+class BitFieldRecord : public TypeRecord {
public:
BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
: TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
BitOffset(BitOffset) {}
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<BitFieldRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
TypeIndex getType() const { return Type; }
uint8_t getBitOffset() const { return BitOffset; }
uint8_t getBitSize() const { return BitSize; }
private:
+ struct Layout {
+ TypeIndex Type;
+ uint8_t BitSize;
+ uint8_t BitOffset;
+ };
+
TypeIndex Type;
uint8_t BitSize;
uint8_t BitOffset;
};
-class VirtualTableShapeRecord : TypeRecord {
+// LF_VTSHAPE
+class VFTableShapeRecord : public TypeRecord {
+public:
+ explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
+ : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
+ explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
+ : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<VFTableShapeRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ ArrayRef<VFTableSlotKind> getSlots() const {
+ if (!SlotsRef.empty())
+ return SlotsRef;
+ return Slots;
+ }
+ uint32_t getEntryCount() const { return getSlots().size(); }
+
+private:
+ struct Layout {
+ // Number of vftable entries. Each method may have more than one entry due
+ // to
+ // things like covariant return types.
+ ulittle16_t VFEntryCount;
+ // Descriptors[]: 4-bit virtual method descriptors of type CV_VTS_desc_e.
+ };
+
+private:
+ ArrayRef<VFTableSlotKind> SlotsRef;
+ std::vector<VFTableSlotKind> Slots;
+};
+
+// LF_TYPESERVER2
+class TypeServer2Record : public TypeRecord {
+public:
+ TypeServer2Record(StringRef Guid, uint32_t Age, StringRef Name)
+ : TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age),
+ Name(Name) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<TypeServer2Record> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ StringRef getGuid() const { return Guid; }
+
+ uint32_t getAge() const { return Age; }
+
+ StringRef getName() const { return Name; }
+
+private:
+ struct Layout {
+ char Guid[16]; // GUID
+ ulittle32_t Age;
+ // Name: Name of the PDB as a null-terminated string
+ };
+
+ StringRef Guid;
+ uint32_t Age;
+ StringRef Name;
+};
+
+// LF_STRING_ID
+class StringIdRecord : public TypeRecord {
+public:
+ StringIdRecord(TypeIndex Id, StringRef String)
+ : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<StringIdRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ TypeIndex getId() const { return Id; }
+
+ StringRef getString() const { return String; }
+
+private:
+ struct Layout {
+ TypeIndex id;
+ // Name: Name of the PDB as a null-terminated string
+ };
+
+ TypeIndex Id;
+ StringRef String;
+};
+
+// LF_FUNC_ID
+class FuncIdRecord : public TypeRecord {
+public:
+ FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
+ : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
+ FunctionType(FunctionType), Name(Name) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<FuncIdRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ TypeIndex getParentScope() const { return ParentScope; }
+
+ TypeIndex getFunctionType() const { return FunctionType; }
+
+ StringRef getName() const { return Name; }
+
+private:
+ struct Layout {
+ TypeIndex ParentScope;
+ TypeIndex FunctionType;
+ // Name: The null-terminated name follows.
+ };
+
+ TypeIndex ParentScope;
+ TypeIndex FunctionType;
+ StringRef Name;
+};
+
+// LF_UDT_SRC_LINE
+class UdtSourceLineRecord : public TypeRecord {
public:
- explicit VirtualTableShapeRecord(ArrayRef<VirtualTableSlotKind> Slots)
- : TypeRecord(TypeRecordKind::VirtualTableShape), Slots(Slots) {}
+ UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
+ : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
+ SourceFile(SourceFile), LineNumber(LineNumber) {}
- ArrayRef<VirtualTableSlotKind> getSlots() const { return Slots; }
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<UdtSourceLineRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ TypeIndex getUDT() const { return UDT; }
+ TypeIndex getSourceFile() const { return SourceFile; }
+ uint32_t getLineNumber() const { return LineNumber; }
private:
- ArrayRef<VirtualTableSlotKind> Slots;
+ struct Layout {
+ TypeIndex UDT; // The user-defined type
+ TypeIndex SourceFile; // StringID containing the source filename
+ ulittle32_t LineNumber;
+ };
+
+ TypeIndex UDT;
+ TypeIndex SourceFile;
+ uint32_t LineNumber;
};
+
+// LF_UDT_MOD_SRC_LINE
+class UdtModSourceLineRecord : public TypeRecord {
+public:
+ UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
+ uint32_t LineNumber, uint16_t Module)
+ : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
+ SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
+
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<UdtModSourceLineRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data) {
+ const Layout *L = nullptr;
+ CV_DESERIALIZE(Data, L);
+
+ return UdtModSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber,
+ L->Module);
+ }
+
+ TypeIndex getUDT() const { return UDT; }
+ TypeIndex getSourceFile() const { return SourceFile; }
+ uint32_t getLineNumber() const { return LineNumber; }
+ uint16_t getModule() const { return Module; }
+
+private:
+ struct Layout {
+ TypeIndex UDT; // The user-defined type
+ TypeIndex SourceFile; // StringID containing the source filename
+ ulittle32_t LineNumber;
+ ulittle16_t Module; // Module that contributes this UDT definition
+ };
+
+ TypeIndex UDT;
+ TypeIndex SourceFile;
+ uint32_t LineNumber;
+ uint16_t Module;
+};
+
+// LF_BUILDINFO
+class BuildInfoRecord : public TypeRecord {
+public:
+ BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
+ : TypeRecord(TypeRecordKind::BuildInfo),
+ ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<BuildInfoRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
+
+private:
+ struct Layout {
+ ulittle16_t NumArgs; // Number of arguments
+ // ArgTypes[]: Type indicies of arguments
+ };
+ SmallVector<TypeIndex, 4> ArgIndices;
+};
+
+// LF_VFTABLE
+class VFTableRecord : public TypeRecord {
+public:
+ VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
+ uint32_t VFPtrOffset, StringRef Name,
+ ArrayRef<StringRef> Methods)
+ : TypeRecord(TypeRecordKind::VFTable),
+ CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable),
+ VFPtrOffset(VFPtrOffset), Name(Name), MethodNamesRef(Methods) {}
+ VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
+ uint32_t VFPtrOffset, StringRef Name,
+ const std::vector<StringRef> &Methods)
+ : TypeRecord(TypeRecordKind::VFTable),
+ CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable),
+ VFPtrOffset(VFPtrOffset), Name(Name), MethodNames(Methods) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<VFTableRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ TypeIndex getCompleteClass() const { return CompleteClass; }
+ TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
+ uint32_t getVFPtrOffset() const { return VFPtrOffset; }
+ StringRef getName() const { return Name; }
+ ArrayRef<StringRef> getMethodNames() const {
+ if (!MethodNamesRef.empty())
+ return MethodNamesRef;
+ return MethodNames;
+ }
+
+private:
+ struct Layout {
+ TypeIndex CompleteClass; // Class that owns this vftable.
+ TypeIndex OverriddenVFTable; // VFTable that this overrides.
+ ulittle32_t VFPtrOffset; // VFPtr offset in CompleteClass
+ ulittle32_t NamesLen; // Length of subsequent names array in bytes.
+ // Names: A sequence of null-terminated strings. First string is vftable
+ // names.
+ };
+
+ TypeIndex CompleteClass;
+ TypeIndex OverriddenVFTable;
+ ulittle32_t VFPtrOffset;
+ StringRef Name;
+ ArrayRef<StringRef> MethodNamesRef;
+ std::vector<StringRef> MethodNames;
+};
+
+// LF_ONEMETHOD
+class OneMethodRecord : public TypeRecord {
+public:
+ OneMethodRecord(TypeIndex Type, MethodKind Kind, MethodOptions Options,
+ MemberAccess Access, int32_t VFTableOffset, StringRef Name)
+ : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Kind(Kind),
+ Options(Options), Access(Access), VFTableOffset(VFTableOffset),
+ Name(Name) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<OneMethodRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ TypeIndex getType() const { return Type; }
+ MethodKind getKind() const { return Kind; }
+ MethodOptions getOptions() const { return Options; }
+ MemberAccess getAccess() const { return Access; }
+ int32_t getVFTableOffset() const { return VFTableOffset; }
+ StringRef getName() const { return Name; }
+
+ bool isIntroducingVirtual() const {
+ return Kind == MethodKind::IntroducingVirtual ||
+ Kind == MethodKind::PureIntroducingVirtual;
+ }
+
+private:
+ struct Layout {
+ MemberAttributes Attrs;
+ TypeIndex Type;
+ // If is introduced virtual method:
+ // VFTableOffset: int32_t offset in vftable
+ // Name: Null-terminated string
+ };
+
+ TypeIndex Type;
+ MethodKind Kind;
+ MethodOptions Options;
+ MemberAccess Access;
+ int32_t VFTableOffset;
+ StringRef Name;
+};
+
+// LF_METHODLIST
+class MethodOverloadListRecord : public TypeRecord {
+public:
+ MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
+ : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<MethodOverloadListRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
+
+private:
+ struct Layout {
+ MemberAttributes Attrs;
+ ulittle16_t Padding;
+
+ TypeIndex Type;
+ // If is introduced virtual method:
+ // VFTableOffset: int32_t offset in vftable
+ };
+
+ std::vector<OneMethodRecord> Methods;
+};
+
+/// For method overload sets. LF_METHOD
+class OverloadedMethodRecord : public TypeRecord {
+public:
+ OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
+ StringRef Name)
+ : TypeRecord(TypeRecordKind::OverloadedMethod),
+ NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<OverloadedMethodRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ uint16_t getNumOverloads() const { return NumOverloads; }
+ TypeIndex getMethodList() const { return MethodList; }
+ StringRef getName() const { return Name; }
+
+private:
+ struct Layout {
+ ulittle16_t MethodCount; // Size of overload set
+ TypeIndex MethList; // Type index of methods in overload set
+ // Name: Null-terminated string
+ };
+
+ uint16_t NumOverloads;
+ TypeIndex MethodList;
+ StringRef Name;
+};
+
+// LF_MEMBER
+class DataMemberRecord : public TypeRecord {
+public:
+ DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
+ StringRef Name)
+ : TypeRecord(TypeRecordKind::DataMember), Access(Access), Type(Type),
+ FieldOffset(Offset), Name(Name) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<DataMemberRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ MemberAccess getAccess() const { return Access; }
+ TypeIndex getType() const { return Type; }
+ uint64_t getFieldOffset() const { return FieldOffset; }
+ StringRef getName() const { return Name; }
+
+private:
+ struct Layout {
+ MemberAttributes Attrs; // Access control attributes, etc
+ TypeIndex Type;
+ // FieldOffset: LF_NUMERIC encoded byte offset
+ // Name: Null-terminated string
+ };
+
+ MemberAccess Access;
+ TypeIndex Type;
+ uint64_t FieldOffset;
+ StringRef Name;
+};
+
+// LF_STMEMBER
+class StaticDataMemberRecord : public TypeRecord {
+public:
+ StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
+ : TypeRecord(TypeRecordKind::StaticDataMember), Access(Access),
+ Type(Type), Name(Name) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<StaticDataMemberRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ MemberAccess getAccess() const { return Access; }
+ TypeIndex getType() const { return Type; }
+ StringRef getName() const { return Name; }
+
+private:
+ struct Layout {
+ MemberAttributes Attrs; // Access control attributes, etc
+ TypeIndex Type;
+ // Name: Null-terminated string
+ };
+
+ MemberAccess Access;
+ TypeIndex Type;
+ StringRef Name;
+};
+
+// LF_ENUMERATE
+class EnumeratorRecord : public TypeRecord {
+public:
+ EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
+ : TypeRecord(TypeRecordKind::Enumerator), Access(Access),
+ Value(std::move(Value)), Name(Name) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<EnumeratorRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ MemberAccess getAccess() const { return Access; }
+ APSInt getValue() const { return Value; }
+ StringRef getName() const { return Name; }
+
+private:
+ struct Layout {
+ MemberAttributes Attrs; // Access control attributes, etc
+ // EnumValue: LF_NUMERIC encoded enumerator value
+ // Name: Null-terminated string
+ };
+
+ MemberAccess Access;
+ APSInt Value;
+ StringRef Name;
+};
+
+// LF_VFUNCTAB
+class VFPtrRecord : public TypeRecord {
+public:
+ VFPtrRecord(TypeIndex Type)
+ : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<VFPtrRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ TypeIndex getType() const { return Type; }
+
+private:
+ struct Layout {
+ ulittle16_t Pad0;
+ TypeIndex Type; // Type of vfptr
+ };
+ TypeIndex Type;
+};
+
+// LF_BCLASS, LF_BINTERFACE
+class BaseClassRecord : public TypeRecord {
+public:
+ BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
+ : TypeRecord(TypeRecordKind::BaseClass), Access(Access), Type(Type),
+ Offset(Offset) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<BaseClassRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ MemberAccess getAccess() const { return Access; }
+ TypeIndex getBaseType() const { return Type; }
+ uint64_t getBaseOffset() const { return Offset; }
+
+private:
+ struct Layout {
+ MemberAttributes Attrs; // Access control attributes, etc
+ TypeIndex BaseType; // Base class type
+ // BaseOffset: LF_NUMERIC encoded byte offset of base from derived.
+ };
+ MemberAccess Access;
+ TypeIndex Type;
+ uint64_t Offset;
+};
+
+// LF_VBCLASS, LF_IVBCLASS
+class VirtualBaseClassRecord : public TypeRecord {
+public:
+ VirtualBaseClassRecord(MemberAccess Access, TypeIndex BaseType,
+ TypeIndex VBPtrType, uint64_t Offset, uint64_t Index)
+ : TypeRecord(TypeRecordKind::VirtualBaseClass), Access(Access),
+ BaseType(BaseType), VBPtrType(VBPtrType), VBPtrOffset(Offset),
+ VTableIndex(Index) {}
+
+ /// Rewrite member type indices with IndexMap. Returns false if a type index
+ /// is not in the map.
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<VirtualBaseClassRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+ MemberAccess getAccess() const { return Access; }
+ TypeIndex getBaseType() const { return BaseType; }
+ TypeIndex getVBPtrType() const { return VBPtrType; }
+ uint64_t getVBPtrOffset() const { return VBPtrOffset; }
+ uint64_t getVTableIndex() const { return VTableIndex; }
+
+private:
+ struct Layout {
+ MemberAttributes Attrs; // Access control attributes, etc.
+ TypeIndex BaseType; // Base class type
+ TypeIndex VBPtrType; // Virtual base pointer type
+ // VBPtrOffset: Offset of vbptr from vfptr encoded as LF_NUMERIC.
+ // VBTableIndex: Index of vbase within vbtable encoded as LF_NUMERIC.
+ };
+ MemberAccess Access;
+ TypeIndex BaseType;
+ TypeIndex VBPtrType;
+ uint64_t VBPtrOffset;
+ uint64_t VTableIndex;
+};
+
+/// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
+/// together. The first will end in an LF_INDEX record that points to the next.
+class ListContinuationRecord : public TypeRecord {
+public:
+ ListContinuationRecord(TypeIndex ContinuationIndex)
+ : TypeRecord(TypeRecordKind::ListContinuation),
+ ContinuationIndex(ContinuationIndex) {}
+
+ TypeIndex getContinuationIndex() const { return ContinuationIndex; }
+
+ bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+ static ErrorOr<ListContinuationRecord> deserialize(TypeRecordKind Kind,
+ ArrayRef<uint8_t> &Data);
+
+private:
+ struct Layout {
+ ulittle16_t Pad0;
+ TypeIndex ContinuationIndex;
+ };
+ TypeIndex ContinuationIndex;
+};
+
+typedef CVRecord<TypeLeafKind> CVType;
+typedef VarStreamArray<CVType> CVTypeArray;
}
}
diff --git a/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h b/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h
index 1f48cf70666d..eb7993baab89 100644
--- a/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h
+++ b/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h
@@ -10,9 +10,10 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORDBUILDER_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORDBUILDER_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/raw_ostream.h"
@@ -39,13 +40,25 @@ public:
void writeEncodedInteger(int64_t Value);
void writeEncodedSignedInteger(int64_t Value);
void writeEncodedUnsignedInteger(uint64_t Value);
- void writeNullTerminatedString(const char *Value);
void writeNullTerminatedString(StringRef Value);
+ void writeGuid(StringRef Guid);
+ void writeBytes(StringRef Value) { Stream << Value; }
llvm::StringRef str();
uint64_t size() const { return Stream.tell(); }
+ void truncate(uint64_t Size) {
+ // This works because raw_svector_ostream is not buffered.
+ assert(Size < Buffer.size());
+ Buffer.resize(Size);
+ }
+
+ void reset(TypeRecordKind K) {
+ Buffer.clear();
+ writeTypeRecordKind(K);
+ }
+
private:
llvm::SmallVector<char, 256> Buffer;
llvm::raw_svector_ostream Stream;
diff --git a/include/llvm/DebugInfo/CodeView/TypeRecords.def b/include/llvm/DebugInfo/CodeView/TypeRecords.def
new file mode 100644
index 000000000000..0959f4bf19c7
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/TypeRecords.def
@@ -0,0 +1,252 @@
+
+//===-- CVLeafTypes.def - All CodeView leaf types ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// See LEAF_ENUM_e in cvinfo.h. This should match the constants there.
+//
+//===----------------------------------------------------------------------===//
+
+// If the type is known, then we have a record describing it in TypeRecord.h.
+
+#ifndef CV_TYPE
+#define CV_TYPE(lf_ename, value)
+#endif
+
+// If the type is known, then we have a record describing it in TypeRecord.h.
+#ifndef TYPE_RECORD
+#define TYPE_RECORD(lf_ename, value, name) CV_TYPE(lf_ename, value)
+#endif
+
+#ifndef TYPE_RECORD_ALIAS
+#define TYPE_RECORD_ALIAS(lf_ename, value, name, alias_name) \
+ TYPE_RECORD(lf_ename, value, name)
+#endif
+
+#ifndef MEMBER_RECORD
+#define MEMBER_RECORD(lf_ename, value, name) TYPE_RECORD(lf_ename, value, name)
+#endif
+
+#ifndef MEMBER_RECORD_ALIAS
+#define MEMBER_RECORD_ALIAS(lf_ename, value, name, alias_name) \
+ MEMBER_RECORD(lf_ename, value, name)
+#endif
+
+TYPE_RECORD(LF_POINTER, 0x1002, Pointer)
+TYPE_RECORD(LF_MODIFIER, 0x1001, Modifier)
+TYPE_RECORD(LF_PROCEDURE, 0x1008, Procedure)
+TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunction)
+TYPE_RECORD(LF_ARGLIST, 0x1201, ArgList)
+
+TYPE_RECORD(LF_ARRAY, 0x1503, Array)
+TYPE_RECORD(LF_CLASS, 0x1504, Class)
+TYPE_RECORD_ALIAS(LF_STRUCTURE, 0x1505, Struct, Class)
+TYPE_RECORD_ALIAS(LF_INTERFACE, 0x1519, Interface, Class)
+TYPE_RECORD(LF_UNION, 0x1506, Union)
+TYPE_RECORD(LF_ENUM, 0x1507, Enum)
+TYPE_RECORD(LF_TYPESERVER2, 0x1515, TypeServer2)
+TYPE_RECORD(LF_VFTABLE, 0x151d, VFTable)
+TYPE_RECORD(LF_VTSHAPE, 0x000a, VFTableShape)
+
+TYPE_RECORD(LF_BITFIELD, 0x1205, BitField)
+
+// Member type records. These are generally not length prefixed, and appear
+// inside of a field list record.
+MEMBER_RECORD(LF_BCLASS, 0x1400, BaseClass)
+MEMBER_RECORD_ALIAS(LF_BINTERFACE, 0x151a, BaseInterface, BaseClass)
+
+MEMBER_RECORD(LF_VBCLASS, 0x1401, VirtualBaseClass)
+MEMBER_RECORD_ALIAS(LF_IVBCLASS, 0x1402, IndirectVirtualBaseClass,
+ VirtualBaseClass)
+
+MEMBER_RECORD(LF_VFUNCTAB, 0x1409, VFPtr)
+MEMBER_RECORD(LF_STMEMBER, 0x150e, StaticDataMember)
+MEMBER_RECORD(LF_METHOD, 0x150f, OverloadedMethod)
+MEMBER_RECORD(LF_MEMBER, 0x150d, DataMember)
+MEMBER_RECORD(LF_NESTTYPE, 0x1510, NestedType)
+MEMBER_RECORD(LF_ONEMETHOD, 0x1511, OneMethod)
+MEMBER_RECORD(LF_ENUMERATE, 0x1502, Enumerator)
+MEMBER_RECORD(LF_INDEX, 0x1404, ListContinuation)
+
+// ID leaf records. Subsequent leaf types may be referenced from .debug$S.
+TYPE_RECORD(LF_FUNC_ID, 0x1601, FuncId)
+TYPE_RECORD(LF_MFUNC_ID, 0x1602, MemberFuncId)
+TYPE_RECORD(LF_BUILDINFO, 0x1603, BuildInfo)
+// FIXME: We reuse the structure of ArgListRecord for substring lists, but it
+// makes for confusing dumper output.
+TYPE_RECORD_ALIAS(LF_SUBSTR_LIST, 0x1604, StringList, ArgList)
+TYPE_RECORD(LF_STRING_ID, 0x1605, StringId)
+TYPE_RECORD(LF_UDT_SRC_LINE, 0x1606, UdtSourceLine)
+TYPE_RECORD(LF_UDT_MOD_SRC_LINE, 0x1607, UdtModSourceLine)
+
+
+TYPE_RECORD(LF_METHODLIST, 0x1206, MethodOverloadList)
+
+
+// 16 bit type records.
+CV_TYPE(LF_MODIFIER_16t, 0x0001)
+CV_TYPE(LF_POINTER_16t, 0x0002)
+CV_TYPE(LF_ARRAY_16t, 0x0003)
+CV_TYPE(LF_CLASS_16t, 0x0004)
+CV_TYPE(LF_STRUCTURE_16t, 0x0005)
+CV_TYPE(LF_UNION_16t, 0x0006)
+CV_TYPE(LF_ENUM_16t, 0x0007)
+CV_TYPE(LF_PROCEDURE_16t, 0x0008)
+CV_TYPE(LF_MFUNCTION_16t, 0x0009)
+CV_TYPE(LF_COBOL0_16t, 0x000b)
+CV_TYPE(LF_COBOL1, 0x000c)
+CV_TYPE(LF_BARRAY_16t, 0x000d)
+CV_TYPE(LF_LABEL, 0x000e)
+CV_TYPE(LF_NULLLEAF, 0x000f) // LF_NULL
+CV_TYPE(LF_NOTTRAN, 0x0010)
+CV_TYPE(LF_DIMARRAY_16t, 0x0011)
+CV_TYPE(LF_VFTPATH_16t, 0x0012)
+CV_TYPE(LF_PRECOMP_16t, 0x0013)
+CV_TYPE(LF_ENDPRECOMP, 0x0014)
+CV_TYPE(LF_OEM_16t, 0x0015)
+CV_TYPE(LF_TYPESERVER_ST, 0x0016)
+
+CV_TYPE(LF_SKIP_16t, 0x0200)
+CV_TYPE(LF_ARGLIST_16t, 0x0201)
+CV_TYPE(LF_DEFARG_16t, 0x0202)
+CV_TYPE(LF_LIST, 0x0203)
+CV_TYPE(LF_FIELDLIST_16t, 0x0204)
+CV_TYPE(LF_DERIVED_16t, 0x0205)
+CV_TYPE(LF_BITFIELD_16t, 0x0206)
+CV_TYPE(LF_METHODLIST_16t, 0x0207)
+CV_TYPE(LF_DIMCONU_16t, 0x0208)
+CV_TYPE(LF_DIMCONLU_16t, 0x0209)
+CV_TYPE(LF_DIMVARU_16t, 0x020a)
+CV_TYPE(LF_DIMVARLU_16t, 0x020b)
+CV_TYPE(LF_REFSYM, 0x020c)
+
+// 16 bit member types. Generally not length prefixed.
+CV_TYPE(LF_BCLASS_16t, 0x0400)
+CV_TYPE(LF_VBCLASS_16t, 0x0401)
+CV_TYPE(LF_IVBCLASS_16t, 0x0402)
+CV_TYPE(LF_ENUMERATE_ST, 0x0403)
+CV_TYPE(LF_FRIENDFCN_16t, 0x0404)
+CV_TYPE(LF_INDEX_16t, 0x0405)
+CV_TYPE(LF_MEMBER_16t, 0x0406)
+CV_TYPE(LF_STMEMBER_16t, 0x0407)
+CV_TYPE(LF_METHOD_16t, 0x0408)
+CV_TYPE(LF_NESTTYPE_16t, 0x0409)
+CV_TYPE(LF_VFUNCTAB_16t, 0x040a)
+CV_TYPE(LF_FRIENDCLS_16t, 0x040b)
+CV_TYPE(LF_ONEMETHOD_16t, 0x040c)
+CV_TYPE(LF_VFUNCOFF_16t, 0x040d)
+
+CV_TYPE(LF_TI16_MAX, 0x1000)
+
+CV_TYPE(LF_ARRAY_ST, 0x1003)
+CV_TYPE(LF_CLASS_ST, 0x1004)
+CV_TYPE(LF_STRUCTURE_ST, 0x1005)
+CV_TYPE(LF_UNION_ST, 0x1006)
+CV_TYPE(LF_ENUM_ST, 0x1007)
+CV_TYPE(LF_COBOL0, 0x100a)
+CV_TYPE(LF_BARRAY, 0x100b)
+CV_TYPE(LF_DIMARRAY_ST, 0x100c)
+CV_TYPE(LF_VFTPATH, 0x100d)
+CV_TYPE(LF_PRECOMP_ST, 0x100e)
+CV_TYPE(LF_OEM, 0x100f)
+CV_TYPE(LF_ALIAS_ST, 0x1010)
+CV_TYPE(LF_OEM2, 0x1011)
+
+CV_TYPE(LF_SKIP, 0x1200)
+CV_TYPE(LF_DEFARG_ST, 0x1202)
+CV_TYPE(LF_FIELDLIST, 0x1203)
+CV_TYPE(LF_DERIVED, 0x1204)
+CV_TYPE(LF_DIMCONU, 0x1207)
+CV_TYPE(LF_DIMCONLU, 0x1208)
+CV_TYPE(LF_DIMVARU, 0x1209)
+CV_TYPE(LF_DIMVARLU, 0x120a)
+
+// Member type records. These are generally not length prefixed, and appear
+// inside of a field list record.
+CV_TYPE(LF_FRIENDFCN_ST, 0x1403)
+CV_TYPE(LF_MEMBER_ST, 0x1405)
+CV_TYPE(LF_STMEMBER_ST, 0x1406)
+CV_TYPE(LF_METHOD_ST, 0x1407)
+CV_TYPE(LF_NESTTYPE_ST, 0x1408)
+CV_TYPE(LF_FRIENDCLS, 0x140a)
+CV_TYPE(LF_ONEMETHOD_ST, 0x140b)
+CV_TYPE(LF_VFUNCOFF, 0x140c)
+CV_TYPE(LF_NESTTYPEEX_ST, 0x140d)
+CV_TYPE(LF_MEMBERMODIFY_ST, 0x140e)
+CV_TYPE(LF_MANAGED_ST, 0x140f)
+
+CV_TYPE(LF_ST_MAX, 0x1500)
+CV_TYPE(LF_TYPESERVER, 0x1501)
+CV_TYPE(LF_DIMARRAY, 0x1508)
+CV_TYPE(LF_PRECOMP, 0x1509)
+CV_TYPE(LF_ALIAS, 0x150a)
+CV_TYPE(LF_DEFARG, 0x150b)
+CV_TYPE(LF_FRIENDFCN, 0x150c)
+CV_TYPE(LF_NESTTYPEEX, 0x1512)
+CV_TYPE(LF_MEMBERMODIFY, 0x1513)
+CV_TYPE(LF_MANAGED, 0x1514)
+CV_TYPE(LF_STRIDED_ARRAY, 0x1516)
+CV_TYPE(LF_HLSL, 0x1517)
+CV_TYPE(LF_MODIFIER_EX, 0x1518)
+CV_TYPE(LF_VECTOR, 0x151b)
+CV_TYPE(LF_MATRIX, 0x151c)
+
+// ID leaf records. Subsequent leaf types may be referenced from .debug$S.
+
+// Numeric leaf types. These are generally contained in other records, and not
+// encountered in the main type stream.
+
+CV_TYPE(LF_NUMERIC, 0x8000)
+CV_TYPE(LF_CHAR, 0x8000)
+CV_TYPE(LF_SHORT, 0x8001)
+CV_TYPE(LF_USHORT, 0x8002)
+CV_TYPE(LF_LONG, 0x8003)
+CV_TYPE(LF_ULONG, 0x8004)
+CV_TYPE(LF_REAL32, 0x8005)
+CV_TYPE(LF_REAL64, 0x8006)
+CV_TYPE(LF_REAL80, 0x8007)
+CV_TYPE(LF_REAL128, 0x8008)
+CV_TYPE(LF_QUADWORD, 0x8009)
+CV_TYPE(LF_UQUADWORD, 0x800a)
+CV_TYPE(LF_REAL48, 0x800b)
+CV_TYPE(LF_COMPLEX32, 0x800c)
+CV_TYPE(LF_COMPLEX64, 0x800d)
+CV_TYPE(LF_COMPLEX80, 0x800e)
+CV_TYPE(LF_COMPLEX128, 0x800f)
+CV_TYPE(LF_VARSTRING, 0x8010)
+CV_TYPE(LF_OCTWORD, 0x8017)
+CV_TYPE(LF_UOCTWORD, 0x8018)
+CV_TYPE(LF_DECIMAL, 0x8019)
+CV_TYPE(LF_DATE, 0x801a)
+CV_TYPE(LF_UTF8STRING, 0x801b)
+CV_TYPE(LF_REAL16, 0x801c)
+
+// Padding bytes. These are emitted into alignment bytes in the type stream.
+
+CV_TYPE(LF_PAD0, 0xf0)
+CV_TYPE(LF_PAD1, 0xf1)
+CV_TYPE(LF_PAD2, 0xf2)
+CV_TYPE(LF_PAD3, 0xf3)
+CV_TYPE(LF_PAD4, 0xf4)
+CV_TYPE(LF_PAD5, 0xf5)
+CV_TYPE(LF_PAD6, 0xf6)
+CV_TYPE(LF_PAD7, 0xf7)
+CV_TYPE(LF_PAD8, 0xf8)
+CV_TYPE(LF_PAD9, 0xf9)
+CV_TYPE(LF_PAD10, 0xfa)
+CV_TYPE(LF_PAD11, 0xfb)
+CV_TYPE(LF_PAD12, 0xfc)
+CV_TYPE(LF_PAD13, 0xfd)
+CV_TYPE(LF_PAD14, 0xfe)
+CV_TYPE(LF_PAD15, 0xff)
+
+#undef CV_TYPE
+#undef TYPE_RECORD
+#undef TYPE_RECORD_ALIAS
+#undef MEMBER_RECORD
+#undef MEMBER_RECORD_ALIAS
diff --git a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
new file mode 100644
index 000000000000..af396c79d074
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
@@ -0,0 +1,26 @@
+//===- TypeStreamMerger.h ---------------------------------------*- 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_CODEVIEW_TYPESTREAMMERGER_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPESTREAMMERGER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+
+namespace llvm {
+namespace codeview {
+
+/// Merges one type stream into another. Returns true on success.
+bool mergeTypeStreams(TypeTableBuilder &DestStream, const CVTypeArray &Types);
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPESTREAMMERGER_H
diff --git a/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h b/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h
index 9de110e8236f..dfba83d62fce 100644
--- a/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h
+++ b/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h
@@ -10,11 +10,12 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESYMBOLEMITTER_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPESYMBOLEMITTER_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
namespace llvm {
+class StringRef;
+
namespace codeview {
class TypeSymbolEmitter {
diff --git a/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h b/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
index 2c950e8af792..5b2aa6186147 100644
--- a/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
+++ b/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
@@ -10,13 +10,15 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
+
+class StringRef;
+
namespace codeview {
class FieldListRecordBuilder;
@@ -38,20 +40,28 @@ public:
TypeIndex writeModifier(const ModifierRecord &Record);
TypeIndex writeProcedure(const ProcedureRecord &Record);
TypeIndex writeMemberFunction(const MemberFunctionRecord &Record);
- TypeIndex writeArgumentList(const ArgumentListRecord &Record);
- TypeIndex writeRecord(TypeRecordBuilder &builder);
+ TypeIndex writeArgList(const ArgListRecord &Record);
TypeIndex writePointer(const PointerRecord &Record);
- TypeIndex writePointerToMember(const PointerToMemberRecord &Record);
TypeIndex writeArray(const ArrayRecord &Record);
- TypeIndex writeAggregate(const AggregateRecord &Record);
+ TypeIndex writeClass(const ClassRecord &Record);
+ TypeIndex writeUnion(const UnionRecord &Record);
TypeIndex writeEnum(const EnumRecord &Record);
TypeIndex writeBitField(const BitFieldRecord &Record);
- TypeIndex writeVirtualTableShape(const VirtualTableShapeRecord &Record);
+ TypeIndex writeVFTableShape(const VFTableShapeRecord &Record);
+ TypeIndex writeStringId(const StringIdRecord &Record);
+ TypeIndex writeVFTable(const VFTableRecord &Record);
+ TypeIndex writeUdtSourceLine(const UdtSourceLineRecord &Record);
+ TypeIndex writeUdtModSourceLine(const UdtModSourceLineRecord &Record);
+ TypeIndex writeFuncId(const FuncIdRecord &Record);
+ TypeIndex writeMemberFuncId(const MemberFuncIdRecord &Record);
+ TypeIndex writeBuildInfo(const BuildInfoRecord &Record);
+ TypeIndex writeMethodOverloadList(const MethodOverloadListRecord &Record);
+ TypeIndex writeTypeServer2(const TypeServer2Record &Record);
TypeIndex writeFieldList(FieldListRecordBuilder &FieldList);
- TypeIndex writeMethodList(MethodListRecordBuilder &MethodList);
-private:
+ TypeIndex writeRecord(TypeRecordBuilder &builder);
+
virtual TypeIndex writeRecord(llvm::StringRef record) = 0;
};
}
diff --git a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
new file mode 100644
index 000000000000..310847ec5d2d
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
@@ -0,0 +1,63 @@
+//===- TypeVisitorCallbacks.h -----------------------------------*- 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_CODEVIEW_TYPEVISITORCALLBACKS_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+class TypeVisitorCallbacks {
+ friend class CVTypeVisitor;
+
+public:
+ virtual ~TypeVisitorCallbacks() {}
+
+ /// Action to take on unknown types. By default, they are ignored.
+ virtual Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) {
+ return Error::success();
+ }
+ virtual Error visitUnknownMember(const CVRecord<TypeLeafKind> &Record) {
+ return Error::success();
+ }
+
+ /// Paired begin/end actions for all types. Receives all record data,
+ /// including the fixed-length record prefix.
+ virtual Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
+ return Error::success();
+ }
+ virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
+ return Error::success();
+ }
+
+ virtual Error visitFieldListBegin(const CVRecord<TypeLeafKind> &Record) {
+ return Error::success();
+ }
+
+ virtual Error visitFieldListEnd(const CVRecord<TypeLeafKind> &Record) {
+ return Error::success();
+ }
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ virtual Error visit##Name(Name##Record &Record) { return Error::success(); }
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ TYPE_RECORD(EnumName, EnumVal, Name)
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "TypeRecords.def"
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h
index 6659a97a042b..2f88371979ea 100644
--- a/include/llvm/DebugInfo/DIContext.h
+++ b/include/llvm/DebugInfo/DIContext.h
@@ -15,10 +15,8 @@
#ifndef LLVM_DEBUGINFO_DICONTEXT_H
#define LLVM_DEBUGINFO_DICONTEXT_H
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/RelocVisitor.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include <string>
@@ -140,7 +138,8 @@ public:
DIContext(DIContextKind K) : Kind(K) {}
virtual ~DIContext() {}
- virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) = 0;
+ virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
+ bool DumpEH = false) = 0;
virtual DILineInfo getLineInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
diff --git a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
index bae3154b3b5f..bba3abe6e9e9 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
@@ -19,10 +19,10 @@ public:
DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
StringRef SOS, StringRef AOS, StringRef LS, bool LE,
- const DWARFUnitSectionBase &UnitSection,
+ bool IsDWO, const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *Entry)
- : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, UnitSection,
- Entry) {}
+ : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
+ UnitSection, Entry) {}
void dump(raw_ostream &OS);
static const DWARFSectionKind Section = DW_SECT_INFO;
// VTable anchor.
diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h
index c91012bc9a24..741a31cb582b 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -22,7 +22,6 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
-#include <vector>
namespace llvm {
@@ -40,7 +39,7 @@ typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
class DWARFContext : public DIContext {
DWARFUnitSection<DWARFCompileUnit> CUs;
- std::vector<DWARFUnitSection<DWARFTypeUnit>> TUs;
+ std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs;
std::unique_ptr<DWARFUnitIndex> CUIndex;
std::unique_ptr<DWARFUnitIndex> TUIndex;
std::unique_ptr<DWARFDebugAbbrev> Abbrev;
@@ -48,10 +47,11 @@ class DWARFContext : public DIContext {
std::unique_ptr<DWARFDebugAranges> Aranges;
std::unique_ptr<DWARFDebugLine> Line;
std::unique_ptr<DWARFDebugFrame> DebugFrame;
+ std::unique_ptr<DWARFDebugFrame> EHFrame;
std::unique_ptr<DWARFDebugMacro> Macro;
DWARFUnitSection<DWARFCompileUnit> DWOCUs;
- std::vector<DWARFUnitSection<DWARFTypeUnit>> DWOTUs;
+ std::deque<DWARFUnitSection<DWARFTypeUnit>> DWOTUs;
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
std::unique_ptr<DWARFDebugLocDWO> LocDWO;
@@ -81,11 +81,12 @@ public:
return DICtx->getKind() == CK_DWARF;
}
- void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
+ void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
+ bool DumpEH = false) override;
typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range;
typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range;
- typedef iterator_range<std::vector<DWARFUnitSection<DWARFTypeUnit>>::iterator> tu_section_iterator_range;
+ typedef iterator_range<decltype(TUs)::iterator> tu_section_iterator_range;
/// Get compile units in this context.
cu_iterator_range compile_units() {
@@ -168,6 +169,9 @@ public:
/// Get a pointer to the parsed frame information object.
const DWARFDebugFrame *getDebugFrame();
+ /// Get a pointer to the parsed eh frame information object.
+ const DWARFDebugFrame *getEHFrame();
+
/// Get a pointer to the parsed DebugMacro object.
const DWARFDebugMacro *getDebugMacro();
@@ -191,6 +195,7 @@ public:
virtual const DWARFSection &getLocSection() = 0;
virtual StringRef getARangeSection() = 0;
virtual StringRef getDebugFrameSection() = 0;
+ virtual StringRef getEHFrameSection() = 0;
virtual const DWARFSection &getLineSection() = 0;
virtual StringRef getStringSection() = 0;
virtual StringRef getRangeSection() = 0;
@@ -242,6 +247,7 @@ class DWARFContextInMemory : public DWARFContext {
DWARFSection LocSection;
StringRef ARangeSection;
StringRef DebugFrameSection;
+ StringRef EHFrameSection;
DWARFSection LineSection;
StringRef StringSection;
StringRef RangeSection;
@@ -281,6 +287,7 @@ public:
const DWARFSection &getLocSection() override { return LocSection; }
StringRef getARangeSection() override { return ARangeSection; }
StringRef getDebugFrameSection() override { return DebugFrameSection; }
+ StringRef getEHFrameSection() override { return EHFrameSection; }
const DWARFSection &getLineSection() override { return LineSection; }
StringRef getStringSection() override { return StringSection; }
StringRef getRangeSection() override { return RangeSection; }
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
index 21142089da6b..67c4a2bb3e67 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
@@ -11,7 +11,6 @@
#define LLVM_LIB_DEBUGINFO_DWARFDEBUGABBREV_H
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
-#include <list>
#include <map>
#include <vector>
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
index be925cbe7519..cd76c909ddae 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
@@ -19,11 +19,13 @@ namespace llvm {
class FrameEntry;
-/// \brief A parsed .debug_frame section
+/// \brief A parsed .debug_frame or .eh_frame section
///
class DWARFDebugFrame {
+ // True if this is parsing an eh_frame section.
+ bool IsEH;
public:
- DWARFDebugFrame();
+ DWARFDebugFrame(bool IsEH);
~DWARFDebugFrame();
/// \brief Dump the section data into the given stream.
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
index f7910962a03f..731c521b9edb 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
@@ -11,7 +11,6 @@
#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Dwarf.h"
diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
index 3c32a3e5b794..b2f750dd7945 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
@@ -10,12 +10,12 @@
#ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H
#define LLVM_DEBUGINFO_DWARFFORMVALUE_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/DataExtractor.h"
namespace llvm {
+template <typename T> class ArrayRef;
class DWARFUnit;
class raw_ostream;
diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
index 894a88dce440..a697edd32072 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
@@ -21,11 +21,11 @@ private:
public:
DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE,
+ StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *Entry)
- : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, UnitSection,
- Entry) {}
+ : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
+ UnitSection, Entry) {}
uint32_t getHeaderSize() const override {
return DWARFUnit::getHeaderSize() + 12;
}
diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index 681b2aa19a79..9c3fe3be6aa6 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -47,7 +47,7 @@ protected:
virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
StringRef SOS, StringRef AOS, StringRef LS,
- bool isLittleEndian) = 0;
+ bool isLittleEndian, bool isDWO) = 0;
~DWARFUnitSectionBase() = default;
};
@@ -59,13 +59,9 @@ const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
template<typename UnitType>
class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
public DWARFUnitSectionBase {
- bool Parsed;
+ bool Parsed = false;
public:
- DWARFUnitSection() : Parsed(false) {}
- DWARFUnitSection(DWARFUnitSection &&DUS) :
- SmallVector<std::unique_ptr<UnitType>, 1>(std::move(DUS)), Parsed(DUS.Parsed) {}
-
typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector;
typedef typename UnitVector::iterator iterator;
typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range;
@@ -84,7 +80,8 @@ public:
private:
void parseImpl(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE) override {
+ StringRef SOS, StringRef AOS, StringRef LS, bool LE,
+ bool IsDWO) override {
if (Parsed)
return;
const auto &Index = getDWARFUnitIndex(Context, UnitType::Section);
@@ -92,7 +89,7 @@ private:
uint32_t Offset = 0;
while (Data.isValidOffset(Offset)) {
auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS,
- AOS, LS, LE, *this,
+ AOS, LS, LE, IsDWO, *this,
Index.getFromOffset(Offset));
if (!U->extract(Data, &Offset))
break;
@@ -117,6 +114,7 @@ class DWARFUnit {
StringRef AddrOffsetSection;
uint32_t AddrOffsetSectionBase;
bool isLittleEndian;
+ bool isDWO;
const DWARFUnitSectionBase &UnitSection;
uint32_t Offset;
@@ -148,7 +146,7 @@ protected:
public:
DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
- StringRef SOS, StringRef AOS, StringRef LS, bool LE,
+ StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *IndexEntry = nullptr);
@@ -249,7 +247,7 @@ public:
/// \brief Return the DIE object for a given offset inside the
/// unit's DIE vector.
///
- /// The unit needs to have his DIEs extracted for this method to work.
+ /// The unit needs to have its DIEs extracted for this method to work.
const DWARFDebugInfoEntryMinimal *getDIEForOffset(uint32_t Offset) const {
assert(!DieArray.empty());
auto it = std::lower_bound(
diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
index a85c2f9f0a23..9f051cd7081c 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
@@ -10,6 +10,7 @@
#ifndef LLVM_LIB_DEBUGINFO_DWARFUNITINDEX_H
#define LLVM_LIB_DEBUGINFO_DWARFUNITINDEX_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -56,6 +57,10 @@ public:
public:
const SectionContribution *getOffset(DWARFSectionKind Sec) const;
const SectionContribution *getOffset() const;
+ const SectionContribution *getOffsets() const {
+ return Contributions.get();
+ }
+ uint64_t getSignature() const { return Signature; }
};
private:
@@ -75,6 +80,12 @@ public:
: InfoColumnKind(InfoColumnKind) {}
void dump(raw_ostream &OS) const;
const Entry *getFromOffset(uint32_t Offset) const;
+ ArrayRef<DWARFSectionKind> getColumnKinds() const {
+ return makeArrayRef(ColumnKinds.get(), Header.NumColumns);
+ }
+ ArrayRef<Entry> getRows() const {
+ return makeArrayRef(Rows.get(), Header.NumBuckets);
+ }
};
}
diff --git a/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h b/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h
index b5fa8c33414d..50f5c40bcac9 100644
--- a/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h
+++ b/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h
@@ -15,6 +15,7 @@
#include <memory>
namespace llvm {
+namespace pdb {
template <typename ChildType>
class ConcreteSymbolEnumerator : public IPDBEnumChildren<ChildType> {
@@ -55,5 +56,6 @@ private:
std::unique_ptr<IPDBEnumSymbols> Enumerator;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIADataStream.h b/include/llvm/DebugInfo/PDB/DIA/DIADataStream.h
index 7b2bc146b32d..930bea6060b2 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIADataStream.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIADataStream.h
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
namespace llvm {
+namespace pdb {
class DIADataStream : public IPDBDataStream {
public:
explicit DIADataStream(CComPtr<IDiaEnumDebugStreamData> DiaStreamData);
@@ -29,5 +30,6 @@ private:
CComPtr<IDiaEnumDebugStreamData> StreamData;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h
index 375bcdd7e3bd..941e16a35fac 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
namespace llvm {
+namespace pdb {
class IPDBDataStream;
@@ -31,5 +32,6 @@ private:
CComPtr<IDiaEnumDebugStreams> Enumerator;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h
index 4cc85eda477f..106b84cecfff 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h
@@ -14,7 +14,7 @@
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
namespace llvm {
-
+namespace pdb {
class IPDBLineNumber;
class DIAEnumLineNumbers : public IPDBEnumChildren<IPDBLineNumber> {
@@ -31,5 +31,6 @@ private:
CComPtr<IDiaEnumLineNumbers> Enumerator;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h
index 88625f64e49e..6c00d6a5e29d 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h
@@ -14,7 +14,7 @@
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
namespace llvm {
-
+namespace pdb {
class DIASession;
class DIAEnumSourceFiles : public IPDBEnumChildren<IPDBSourceFile> {
@@ -33,5 +33,6 @@ private:
CComPtr<IDiaEnumSourceFiles> Enumerator;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h
index fe343f778aad..b206ff59a6a4 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h
@@ -14,7 +14,7 @@
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
namespace llvm {
-
+namespace pdb {
class DIASession;
class DIAEnumSymbols : public IPDBEnumChildren<PDBSymbol> {
@@ -33,5 +33,6 @@ private:
CComPtr<IDiaEnumSymbols> Enumerator;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAError.h b/include/llvm/DebugInfo/PDB/DIA/DIAError.h
new file mode 100644
index 000000000000..f198d07e99d4
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/DIA/DIAError.h
@@ -0,0 +1,46 @@
+//===- DIAError.h - Error extensions for PDB DIA implementation -*- 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_DIA_DIAERROR_H
+#define LLVM_DEBUGINFO_PDB_DIA_DIAERROR_H
+
+#include "llvm/Support/Error.h"
+
+#include <string>
+
+namespace llvm {
+namespace pdb {
+enum class dia_error_code {
+ unspecified = 1,
+ could_not_create_impl,
+ invalid_file_format,
+ invalid_parameter,
+ already_loaded,
+ debug_info_mismatch,
+};
+
+/// Base class for errors originating in DIA SDK, e.g. COM calls
+class DIAError : public ErrorInfo<DIAError> {
+public:
+ static char ID;
+ DIAError(dia_error_code C);
+ DIAError(const std::string &Context);
+ DIAError(dia_error_code C, const std::string &Context);
+
+ void log(raw_ostream &OS) const override;
+ const std::string &getErrorMessage() const;
+ std::error_code convertToErrorCode() const override;
+
+private:
+ std::string ErrMsg;
+ dia_error_code Code;
+};
+}
+}
+#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIALineNumber.h b/include/llvm/DebugInfo/PDB/DIA/DIALineNumber.h
index 5950a0d3835f..a59e3a19c8c2 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIALineNumber.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIALineNumber.h
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
namespace llvm {
+namespace pdb {
class DIALineNumber : public IPDBLineNumber {
public:
explicit DIALineNumber(CComPtr<IDiaLineNumber> DiaLineNumber);
@@ -35,5 +36,5 @@ private:
CComPtr<IDiaLineNumber> LineNumber;
};
}
-
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
index 9308b8e82657..1e40c46f8a27 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
namespace llvm {
+namespace pdb {
class DIASession;
class DIARawSymbol : public IPDBRawSymbol {
public:
@@ -58,7 +59,7 @@ public:
uint32_t getLiveRangeStartAddressOffset() const override;
uint32_t getLiveRangeStartAddressSection() const override;
uint32_t getLiveRangeStartRelativeVirtualAddress() const override;
- PDB_RegisterId getLocalBasePointerRegisterId() const override;
+ codeview::RegisterId getLocalBasePointerRegisterId() const override;
uint32_t getLowerBoundId() const override;
uint32_t getMemorySpaceKind() const override;
std::string getName() const override;
@@ -73,7 +74,7 @@ public:
uint32_t getOffsetInUdt() const override;
PDB_Cpu getPlatform() const override;
uint32_t getRank() const override;
- PDB_RegisterId getRegisterId() const override;
+ codeview::RegisterId getRegisterId() const override;
uint32_t getRegisterType() const override;
uint32_t getRelativeVirtualAddress() const override;
uint32_t getSamplerSlot() const override;
@@ -109,7 +110,7 @@ public:
int32_t getVirtualBasePointerOffset() const override;
PDB_LocType getLocationType() const override;
PDB_Machine getMachineType() const override;
- PDB_ThunkOrdinal getThunkOrdinal() const override;
+ codeview::ThunkOrdinal getThunkOrdinal() const override;
uint64_t getLength() const override;
uint64_t getLiveRangeLength() const override;
uint64_t getVirtualAddress() const override;
@@ -202,5 +203,6 @@ private:
CComPtr<IDiaSymbol> Symbol;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/include/llvm/DebugInfo/PDB/DIA/DIASession.h
index 9a8600fb85ec..3f5818631e7b 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIASession.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIASession.h
@@ -11,18 +11,23 @@
#define LLVM_DEBUGINFO_PDB_DIA_DIASESSION_H
#include "DIASupport.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/Support/Error.h"
+
+#include <system_error>
namespace llvm {
+class StringRef;
+
+namespace pdb {
class DIASession : public IPDBSession {
public:
explicit DIASession(CComPtr<IDiaSession> DiaSession);
- static PDB_ErrorCode createFromPdb(StringRef Path,
- std::unique_ptr<IPDBSession> &Session);
- static PDB_ErrorCode createFromExe(StringRef Path,
- std::unique_ptr<IPDBSession> &Session);
+ static Error createFromPdb(StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
+ static Error createFromExe(StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
uint64_t getLoadAddress() const override;
void setLoadAddress(uint64_t Address) override;
@@ -33,8 +38,24 @@ public:
findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override;
std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbers(const PDBSymbolCompiland &Compiland,
+ const IPDBSourceFile &File) const override;
+ std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override;
+ std::unique_ptr<IPDBEnumSourceFiles>
+ findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<IPDBSourceFile>
+ findOneSourceFile(const PDBSymbolCompiland *Compiland,
+ llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+ findCompilandsForSourceFile(llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<PDBSymbolCompiland>
+ findOneCompilandForSourceFile(llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const override;
std::unique_ptr<IPDBEnumSourceFiles> getSourceFilesForCompiland(
const PDBSymbolCompiland &Compiland) const override;
@@ -47,5 +68,5 @@ private:
CComPtr<IDiaSession> Session;
};
}
-
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASourceFile.h b/include/llvm/DebugInfo/PDB/DIA/DIASourceFile.h
index c424e27493c1..1088ea54981c 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIASourceFile.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIASourceFile.h
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
namespace llvm {
+namespace pdb {
class DIASession;
class DIASourceFile : public IPDBSourceFile {
@@ -25,12 +26,16 @@ public:
uint32_t getUniqueId() const override;
std::string getChecksum() const override;
PDB_Checksum getChecksumType() const override;
- std::unique_ptr<IPDBEnumSymbols> getCompilands() const override;
+ std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+ getCompilands() const override;
+
+ CComPtr<IDiaSourceFile> getDiaFile() const { return SourceFile; }
private:
const DIASession &Session;
CComPtr<IDiaSourceFile> SourceFile;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASupport.h b/include/llvm/DebugInfo/PDB/DIA/DIASupport.h
index 407a34551cc7..3b4a348289df 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIASupport.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIASupport.h
@@ -22,6 +22,14 @@
#define NOMINMAX
#endif
+// llvm/Support/Debug.h unconditionally #defines DEBUG as a macro.
+// DIA headers #define it if it is not already defined, so we have
+// an order of includes problem. The real fix is to make LLVM use
+// something less generic than DEBUG, such as LLVM_DEBUG(), but it's
+// fairly prevalent. So for now, we save the definition state and
+// restore it.
+#pragma push_macro("DEBUG")
+
// atlbase.h has to come before windows.h
#include <atlbase.h>
#include <windows.h>
@@ -29,5 +37,8 @@
// DIA headers must come after windows headers.
#include <cvconst.h>
#include <dia2.h>
+#include <diacreate.h>
+
+#pragma pop_macro("DEBUG")
#endif // LLVM_DEBUGINFO_PDB_DIA_DIASUPPORT_H
diff --git a/include/llvm/DebugInfo/PDB/GenericError.h b/include/llvm/DebugInfo/PDB/GenericError.h
new file mode 100644
index 000000000000..959c26161044
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/GenericError.h
@@ -0,0 +1,42 @@
+//===- Error.h - system_error extensions for PDB ----------------*- 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_ERROR_H
+#define LLVM_DEBUGINFO_PDB_ERROR_H
+
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace pdb {
+
+enum class generic_error_code {
+ invalid_path = 1,
+ dia_sdk_not_present,
+ unspecified,
+};
+
+/// Base class for errors originating when parsing raw PDB files
+class GenericError : public ErrorInfo<GenericError> {
+public:
+ static char ID;
+ GenericError(generic_error_code C);
+ GenericError(const std::string &Context);
+ GenericError(generic_error_code C, const std::string &Context);
+
+ void log(raw_ostream &OS) const override;
+ const std::string &getErrorMessage() const;
+ std::error_code convertToErrorCode() const override;
+
+private:
+ std::string ErrMsg;
+ generic_error_code Code;
+};
+}
+}
+#endif
diff --git a/include/llvm/DebugInfo/PDB/IPDBDataStream.h b/include/llvm/DebugInfo/PDB/IPDBDataStream.h
index 808a0f3ec3a9..9594dc1591a7 100644
--- a/include/llvm/DebugInfo/PDB/IPDBDataStream.h
+++ b/include/llvm/DebugInfo/PDB/IPDBDataStream.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/SmallVector.h"
namespace llvm {
+namespace pdb {
/// IPDBDataStream defines an interface used to represent a stream consisting
/// of a name and a series of records whose formats depend on the particular
@@ -33,5 +34,6 @@ public:
virtual IPDBDataStream *clone() const = 0;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h b/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h
index 645ac96e23a5..8e9f6f883679 100644
--- a/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h
+++ b/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h
@@ -14,6 +14,7 @@
#include <memory>
namespace llvm {
+namespace pdb {
template <typename ChildType> class IPDBEnumChildren {
public:
@@ -29,5 +30,6 @@ public:
virtual MyType *clone() const = 0;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/IPDBLineNumber.h b/include/llvm/DebugInfo/PDB/IPDBLineNumber.h
index 92cd58d86649..e20080f2fbfc 100644
--- a/include/llvm/DebugInfo/PDB/IPDBLineNumber.h
+++ b/include/llvm/DebugInfo/PDB/IPDBLineNumber.h
@@ -13,7 +13,7 @@
#include "PDBTypes.h"
namespace llvm {
-
+namespace pdb {
class IPDBLineNumber {
public:
virtual ~IPDBLineNumber();
@@ -32,5 +32,6 @@ public:
virtual bool isStatement() const = 0;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
index 139bff56fd5d..49866b8bb2f2 100644
--- a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
+++ b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
@@ -13,12 +13,14 @@
#include "PDBTypes.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include <memory>
namespace llvm {
-
class raw_ostream;
+namespace pdb {
+
/// 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
@@ -66,7 +68,7 @@ public:
virtual uint32_t getLiveRangeStartAddressOffset() const = 0;
virtual uint32_t getLiveRangeStartAddressSection() const = 0;
virtual uint32_t getLiveRangeStartRelativeVirtualAddress() const = 0;
- virtual PDB_RegisterId getLocalBasePointerRegisterId() const = 0;
+ virtual codeview::RegisterId getLocalBasePointerRegisterId() const = 0;
virtual uint32_t getLowerBoundId() const = 0;
virtual uint32_t getMemorySpaceKind() const = 0;
virtual std::string getName() const = 0;
@@ -81,7 +83,7 @@ public:
virtual uint32_t getOffsetInUdt() const = 0;
virtual PDB_Cpu getPlatform() const = 0;
virtual uint32_t getRank() const = 0;
- virtual PDB_RegisterId getRegisterId() const = 0;
+ virtual codeview::RegisterId getRegisterId() const = 0;
virtual uint32_t getRegisterType() const = 0;
virtual uint32_t getRelativeVirtualAddress() const = 0;
virtual uint32_t getSamplerSlot() const = 0;
@@ -117,7 +119,7 @@ public:
virtual int32_t getVirtualBasePointerOffset() const = 0;
virtual PDB_LocType getLocationType() const = 0;
virtual PDB_Machine getMachineType() const = 0;
- virtual PDB_ThunkOrdinal getThunkOrdinal() const = 0;
+ virtual codeview::ThunkOrdinal getThunkOrdinal() const = 0;
virtual uint64_t getLength() const = 0;
virtual uint64_t getLiveRangeLength() const = 0;
virtual uint64_t getVirtualAddress() const = 0;
@@ -206,6 +208,7 @@ public:
virtual std::string getUnused() const = 0;
};
+} // namespace pdb
} // namespace llvm
#endif
diff --git a/include/llvm/DebugInfo/PDB/IPDBSession.h b/include/llvm/DebugInfo/PDB/IPDBSession.h
index a130a38a6538..3d2c37eff2e3 100644
--- a/include/llvm/DebugInfo/PDB/IPDBSession.h
+++ b/include/llvm/DebugInfo/PDB/IPDBSession.h
@@ -11,11 +11,12 @@
#define LLVM_DEBUGINFO_PDB_IPDBSESSION_H
#include "PDBTypes.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include <memory>
namespace llvm {
-
+namespace pdb {
class PDBSymbolCompiland;
class PDBSymbolExe;
@@ -45,9 +46,27 @@ public:
virtual std::unique_ptr<PDBSymbol>
findSymbolByAddress(uint64_t Address, PDB_SymType Type) const = 0;
+
+ virtual std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbers(const PDBSymbolCompiland &Compiland,
+ const IPDBSourceFile &File) const = 0;
virtual std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbersByAddress(uint64_t Address, uint32_t Length) const = 0;
+ virtual std::unique_ptr<IPDBEnumSourceFiles>
+ findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const = 0;
+ virtual std::unique_ptr<IPDBSourceFile>
+ findOneSourceFile(const PDBSymbolCompiland *Compiland,
+ llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const = 0;
+ virtual std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+ findCompilandsForSourceFile(llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const = 0;
+ virtual std::unique_ptr<PDBSymbolCompiland>
+ findOneCompilandForSourceFile(llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const = 0;
+
virtual std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const = 0;
virtual std::unique_ptr<IPDBEnumSourceFiles>
getSourceFilesForCompiland(const PDBSymbolCompiland &Compiland) const = 0;
@@ -57,5 +76,6 @@ public:
virtual std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const = 0;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/IPDBSourceFile.h b/include/llvm/DebugInfo/PDB/IPDBSourceFile.h
index 55000eff02f0..3676c4030b13 100644
--- a/include/llvm/DebugInfo/PDB/IPDBSourceFile.h
+++ b/include/llvm/DebugInfo/PDB/IPDBSourceFile.h
@@ -15,9 +15,10 @@
#include <string>
namespace llvm {
-
class raw_ostream;
+namespace pdb {
+
/// IPDBSourceFile defines an interface used to represent source files whose
/// information are stored in the PDB.
class IPDBSourceFile {
@@ -30,8 +31,10 @@ public:
virtual uint32_t getUniqueId() const = 0;
virtual std::string getChecksum() const = 0;
virtual PDB_Checksum getChecksumType() const = 0;
- virtual std::unique_ptr<IPDBEnumSymbols> getCompilands() const = 0;
+ virtual std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+ getCompilands() const = 0;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/PDB.h b/include/llvm/DebugInfo/PDB/PDB.h
index 5df3be85e381..1f5a066b9a1b 100644
--- a/include/llvm/DebugInfo/PDB/PDB.h
+++ b/include/llvm/DebugInfo/PDB/PDB.h
@@ -11,16 +11,20 @@
#define LLVM_DEBUGINFO_PDB_PDB_H
#include "PDBTypes.h"
+#include "llvm/Support/Error.h"
#include <memory>
+#include <system_error>
namespace llvm {
class StringRef;
-PDB_ErrorCode loadDataForPDB(PDB_ReaderType Type, StringRef Path,
- std::unique_ptr<IPDBSession> &Session);
+namespace pdb {
-PDB_ErrorCode loadDataForEXE(PDB_ReaderType Type, StringRef Path,
- std::unique_ptr<IPDBSession> &Session);
-}
+Error loadDataForPDB(PDB_ReaderType Type, StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
+Error loadDataForEXE(PDB_ReaderType Type, StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
+}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/PDBContext.h b/include/llvm/DebugInfo/PDB/PDBContext.h
index 9404a5922449..836e39248438 100644
--- a/include/llvm/DebugInfo/PDB/PDBContext.h
+++ b/include/llvm/DebugInfo/PDB/PDBContext.h
@@ -17,43 +17,46 @@ namespace llvm {
namespace object {
class COFFObjectFile;
-}
-
-/// PDBContext
-/// This data structure is the top level entity that deals with PDB debug
-/// information parsing. This data structure exists only when there is a
-/// need for a transparent interface to different debug information formats
-/// (e.g. PDB and DWARF). More control and power over the debug information
-/// access can be had by using the PDB interfaces directly.
-class PDBContext : public DIContext {
-
- PDBContext(PDBContext &) = delete;
- PDBContext &operator=(PDBContext &) = delete;
-
-public:
- PDBContext(const object::COFFObjectFile &Object,
- std::unique_ptr<IPDBSession> PDBSession);
-
- static bool classof(const DIContext *DICtx) {
- return DICtx->getKind() == CK_PDB;
}
- void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
-
- DILineInfo getLineInfoForAddress(
- uint64_t Address,
- DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
- DILineInfoTable getLineInfoForAddressRange(
- uint64_t Address, uint64_t Size,
- DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
- DIInliningInfo getInliningInfoForAddress(
- uint64_t Address,
- DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
-
-private:
- std::string getFunctionName(uint64_t Address, DINameKind NameKind) const;
- std::unique_ptr<IPDBSession> Session;
-};
+ namespace pdb {
+ /// PDBContext
+ /// This data structure is the top level entity that deals with PDB debug
+ /// information parsing. This data structure exists only when there is a
+ /// need for a transparent interface to different debug information formats
+ /// (e.g. PDB and DWARF). More control and power over the debug information
+ /// access can be had by using the PDB interfaces directly.
+ class PDBContext : public DIContext {
+
+ PDBContext(PDBContext &) = delete;
+ PDBContext &operator=(PDBContext &) = delete;
+
+ public:
+ PDBContext(const object::COFFObjectFile &Object,
+ std::unique_ptr<IPDBSession> PDBSession);
+
+ static bool classof(const DIContext *DICtx) {
+ return DICtx->getKind() == CK_PDB;
+ }
+
+ void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
+ bool DumpEH = false) override;
+
+ DILineInfo getLineInfoForAddress(
+ uint64_t Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ DILineInfoTable getLineInfoForAddressRange(
+ uint64_t Address, uint64_t Size,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ DIInliningInfo getInliningInfoForAddress(
+ uint64_t Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+
+ private:
+ std::string getFunctionName(uint64_t Address, DINameKind NameKind) const;
+ std::unique_ptr<IPDBSession> Session;
+ };
+ }
}
#endif
diff --git a/include/llvm/DebugInfo/PDB/PDBExtras.h b/include/llvm/DebugInfo/PDB/PDBExtras.h
index 48ce1c127196..5a7422d9e9e4 100644
--- a/include/llvm/DebugInfo/PDB/PDBExtras.h
+++ b/include/llvm/DebugInfo/PDB/PDBExtras.h
@@ -11,28 +11,33 @@
#define LLVM_DEBUGINFO_PDB_PDBEXTRAS_H
#include "PDBTypes.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/Support/raw_ostream.h"
#include <unordered_map>
namespace llvm {
+
+namespace pdb {
typedef std::unordered_map<PDB_SymType, int> TagStats;
raw_ostream &operator<<(raw_ostream &OS, const PDB_VariantType &Value);
raw_ostream &operator<<(raw_ostream &OS, const PDB_CallingConv &Conv);
raw_ostream &operator<<(raw_ostream &OS, const PDB_DataKind &Data);
-raw_ostream &operator<<(raw_ostream &OS, const PDB_RegisterId &Reg);
+raw_ostream &operator<<(raw_ostream &OS, const codeview::RegisterId &Reg);
raw_ostream &operator<<(raw_ostream &OS, const PDB_LocType &Loc);
-raw_ostream &operator<<(raw_ostream &OS, const PDB_ThunkOrdinal &Thunk);
+raw_ostream &operator<<(raw_ostream &OS, const codeview::ThunkOrdinal &Thunk);
raw_ostream &operator<<(raw_ostream &OS, const PDB_Checksum &Checksum);
raw_ostream &operator<<(raw_ostream &OS, const PDB_Lang &Lang);
raw_ostream &operator<<(raw_ostream &OS, const PDB_SymType &Tag);
raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access);
raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type);
raw_ostream &operator<<(raw_ostream &OS, const PDB_UniqueId &Id);
+raw_ostream &operator<<(raw_ostream &OS, const PDB_Machine &Machine);
raw_ostream &operator<<(raw_ostream &OS, const Variant &Value);
raw_ostream &operator<<(raw_ostream &OS, const VersionInfo &Version);
raw_ostream &operator<<(raw_ostream &OS, const TagStats &Stats);
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/PDBSymDumper.h b/include/llvm/DebugInfo/PDB/PDBSymDumper.h
index 65110f39366f..095c33cfe8b5 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymDumper.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymDumper.h
@@ -15,6 +15,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymDumper {
public:
@@ -57,5 +58,6 @@ private:
bool RequireImpl;
};
}
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbol.h
index 4360c5431e69..bf5118806540 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbol.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbol.h
@@ -15,9 +15,7 @@
#include "PDBExtras.h"
#include "PDBTypes.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
-#include <unordered_map>
#define FORWARD_SYMBOL_METHOD(MethodName) \
auto MethodName() const->decltype(RawSymbol->MethodName()) { \
@@ -26,9 +24,12 @@
namespace llvm {
-class IPDBRawSymbol;
+class StringRef;
class raw_ostream;
+namespace pdb {
+class IPDBRawSymbol;
+
#define DECLARE_PDB_SYMBOL_CONCRETE_TYPE(TagValue) \
static const PDB_SymType Tag = TagValue; \
static bool classof(const PDBSymbol *S) { return S->getSymTag() == Tag; }
@@ -41,7 +42,8 @@ class raw_ostream;
/// https://msdn.microsoft.com/en-us/library/370hs6k4.aspx
class PDBSymbol {
protected:
- PDBSymbol(const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol);
+ PDBSymbol(const IPDBSession &PDBSession,
+ std::unique_ptr<IPDBRawSymbol> Symbol);
public:
static std::unique_ptr<PDBSymbol>
@@ -57,6 +59,7 @@ public:
void defaultDump(raw_ostream &OS, int Indent) const;
PDB_SymType getSymTag() const;
+ uint32_t getSymIndexId() const;
template <typename T> std::unique_ptr<T> findOneChild() const {
auto Enumerator(findAllChildren<T>());
@@ -93,5 +96,6 @@ protected:
};
} // namespace llvm
+}
#endif
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h b/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h
index c055dd7f3d49..3169146e5b12 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h
@@ -11,11 +11,11 @@
#include "PDBSymbol.h"
#include "PDBTypes.h"
-#include <string>
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolAnnotation : public PDBSymbol {
public:
@@ -30,10 +30,10 @@ public:
FORWARD_SYMBOL_METHOD(getAddressSection)
FORWARD_SYMBOL_METHOD(getDataKind)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
// FORWARD_SYMBOL_METHOD(getValue)
FORWARD_SYMBOL_METHOD(getVirtualAddress)
};
}
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLANNOTATION_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h
index 2ca12501d9f6..d0ff62ca7c3f 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h
@@ -11,12 +11,13 @@
#include "PDBSymbol.h"
#include "PDBTypes.h"
-#include <string>
namespace llvm {
class raw_ostream;
+namespace pdb {
+
class PDBSymbolBlock : public PDBSymbol {
public:
PDBSymbolBlock(const IPDBSession &PDBSession,
@@ -33,9 +34,9 @@ public:
FORWARD_SYMBOL_METHOD(getLocationType)
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getVirtualAddress)
};
}
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLBLOCK_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h
index f8c796ae5bdc..f1983b3f7bf5 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h
@@ -17,6 +17,8 @@ namespace llvm {
class raw_ostream;
+namespace pdb {
+
class PDBSymbolCompiland : public PDBSymbol {
public:
PDBSymbolCompiland(const IPDBSession &PDBSession,
@@ -30,9 +32,10 @@ public:
FORWARD_SYMBOL_METHOD(getLexicalParentId)
FORWARD_SYMBOL_METHOD(getLibraryName)
FORWARD_SYMBOL_METHOD(getName)
- FORWARD_SYMBOL_METHOD(getSourceFileName)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
+
+ std::string getSourceFileName() const;
};
}
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLCOMPILAND_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h
index 7f29d6bde990..bb4a78f68e2f 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolCompilandDetails : public PDBSymbol {
public:
@@ -47,9 +48,10 @@ public:
FORWARD_SYMBOL_METHOD(getLanguage)
FORWARD_SYMBOL_METHOD(getLexicalParentId)
FORWARD_SYMBOL_METHOD(getPlatform)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
+ FORWARD_SYMBOL_METHOD(getSourceFileName)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBFUNCTION_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h
index 7e2ea9018edb..a71a0ba2df58 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h
@@ -16,7 +16,7 @@
namespace llvm {
class raw_ostream;
-
+namespace pdb {
class PDBSymbolCompilandEnv : public PDBSymbol {
public:
PDBSymbolCompilandEnv(const IPDBSession &PDBSession,
@@ -28,10 +28,10 @@ public:
FORWARD_SYMBOL_METHOD(getLexicalParentId)
FORWARD_SYMBOL_METHOD(getName)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
std::string getValue() const;
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLCOMPILANDENV_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h b/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h
index 86bfd5707a31..54f089404262 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h
@@ -18,6 +18,7 @@ namespace llvm {
class raw_ostream;
+namespace pdb {
/// PDBSymbolCustom represents symbols that are compiler-specific and do not
/// fit anywhere else in the lexical hierarchy.
/// https://msdn.microsoft.com/en-us/library/d88sf09h.aspx
@@ -31,9 +32,9 @@ public:
void dump(PDBSymDumper &Dumper) const override;
void getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes);
- FORWARD_SYMBOL_METHOD(getSymIndexId)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLCUSTOM_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolData.h b/include/llvm/DebugInfo/PDB/PDBSymbolData.h
index 79cbbf0e1683..36f32ab51c11 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolData.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolData.h
@@ -17,6 +17,8 @@ namespace llvm {
class raw_ostream;
+namespace pdb {
+
class PDBSymbolData : public PDBSymbol {
public:
PDBSymbolData(const IPDBSession &PDBSession,
@@ -47,7 +49,6 @@ public:
FORWARD_SYMBOL_METHOD(getRegisterId)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
FORWARD_SYMBOL_METHOD(getSlot)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getToken)
FORWARD_SYMBOL_METHOD(getTypeId)
FORWARD_SYMBOL_METHOD(isUnalignedType)
@@ -57,5 +58,6 @@ public:
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLDATA_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolExe.h b/include/llvm/DebugInfo/PDB/PDBSymbolExe.h
index 7c5f302ad634..5b3f50d153eb 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolExe.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolExe.h
@@ -12,12 +12,13 @@
#include "PDBSymbol.h"
#include "PDBTypes.h"
-#include <string>
namespace llvm {
class raw_ostream;
+namespace pdb {
+
class PDBSymbolExe : public PDBSymbol {
public:
PDBSymbolExe(const IPDBSession &PDBSession,
@@ -35,12 +36,12 @@ public:
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(getSignature)
FORWARD_SYMBOL_METHOD(getSymbolsFileName)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
private:
void dumpChildren(raw_ostream &OS, StringRef Label, PDB_SymType ChildType,
int Indent) const;
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLEXE_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
index 9db41d53532a..7170bcbe846c 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
@@ -17,6 +17,8 @@ namespace llvm {
class raw_ostream;
+namespace pdb {
+
class PDBSymbolFunc : public PDBSymbol {
public:
PDBSymbolFunc(const IPDBSession &PDBSession,
@@ -64,7 +66,6 @@ public:
FORWARD_SYMBOL_METHOD(hasOptimizedCodeDebugInfo)
FORWARD_SYMBOL_METHOD(isPureVirtual)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getToken)
FORWARD_SYMBOL_METHOD(getTypeId)
FORWARD_SYMBOL_METHOD(isUnalignedType)
@@ -76,5 +77,6 @@ public:
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLFUNC_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h
index 34d551cda74c..464389503bef 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h
@@ -17,6 +17,8 @@ namespace llvm {
class raw_ostream;
+namespace pdb {
+
class PDBSymbolFuncDebugEnd : public PDBSymbol {
public:
PDBSymbolFuncDebugEnd(const IPDBSession &PDBSession,
@@ -40,10 +42,10 @@ public:
FORWARD_SYMBOL_METHOD(getOffset)
FORWARD_SYMBOL_METHOD(hasOptimizedCodeDebugInfo)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getVirtualAddress)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLFUNCDEBUGEND_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h
index 7671be480dac..c2e3dd39be6c 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolFuncDebugStart : public PDBSymbol {
public:
@@ -40,10 +41,10 @@ public:
FORWARD_SYMBOL_METHOD(getOffset)
FORWARD_SYMBOL_METHOD(hasOptimizedCodeDebugInfo)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getVirtualAddress)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLFUNCDEBUGSTART_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h b/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h
index 9d9903a11b0c..3aeae10b47bc 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolLabel : public PDBSymbol {
public:
@@ -40,10 +41,10 @@ public:
FORWARD_SYMBOL_METHOD(getOffset)
FORWARD_SYMBOL_METHOD(hasOptimizedCodeDebugInfo)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getVirtualAddress)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLLABEL_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h
index 70dfcb5ddf4c..be0734445973 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolPublicSymbol : public PDBSymbol {
public:
@@ -36,12 +37,12 @@ public:
FORWARD_SYMBOL_METHOD(isManagedCode)
FORWARD_SYMBOL_METHOD(isMSILCode)
FORWARD_SYMBOL_METHOD(getName)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
FORWARD_SYMBOL_METHOD(getVirtualAddress)
FORWARD_SYMBOL_METHOD(getUndecoratedName)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLPUBLICSYMBOL_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h b/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h
index bd5a9b2aa8b3..63f7a09fc881 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h
@@ -12,11 +12,11 @@
#include "PDBSymbol.h"
#include "PDBTypes.h"
-#include <string>
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolThunk : public PDBSymbol {
public:
@@ -39,7 +39,6 @@ public:
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(isPureVirtual)
FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getTargetOffset)
FORWARD_SYMBOL_METHOD(getTargetRelativeVirtualAddress)
FORWARD_SYMBOL_METHOD(getTargetVirtualAddress)
@@ -53,5 +52,6 @@ public:
FORWARD_SYMBOL_METHOD(isVolatileType)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTHUNK_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
index 513a9ec05ff8..57db03661fb7 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeArray : public PDBSymbol {
public:
@@ -34,12 +35,12 @@ public:
FORWARD_SYMBOL_METHOD(getLength)
FORWARD_SYMBOL_METHOD(getLexicalParentId)
FORWARD_SYMBOL_METHOD(getRank)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getTypeId)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEARRAY_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h
index 2a9a8a0788a8..aaa3ab7988d7 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeBaseClass : public PDBSymbol {
public:
@@ -42,7 +43,6 @@ public:
FORWARD_SYMBOL_METHOD(hasOverloadedOperator)
FORWARD_SYMBOL_METHOD(isPacked)
FORWARD_SYMBOL_METHOD(isScoped)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getTypeId)
FORWARD_SYMBOL_METHOD(getUdtKind)
FORWARD_SYMBOL_METHOD(isUnalignedType)
@@ -56,5 +56,6 @@ public:
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEBASECLASS_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
index 69a2028a1b1d..c8f59f1f140a 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeBuiltin : public PDBSymbol {
public:
@@ -30,11 +31,11 @@ public:
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getLength)
FORWARD_SYMBOL_METHOD(getLexicalParentId)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEBUILTIN_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h
index c41c48933e0d..199b3f8b304e 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeCustom : public PDBSymbol {
public:
@@ -28,9 +29,9 @@ public:
FORWARD_SYMBOL_METHOD(getOemId)
FORWARD_SYMBOL_METHOD(getOemSymbolId)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPECUSTOM_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h
index 3f22ed8d731e..e635eb5bbf6f 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeDimension : public PDBSymbol {
public:
@@ -28,9 +29,9 @@ public:
FORWARD_SYMBOL_METHOD(getLowerBoundId)
FORWARD_SYMBOL_METHOD(getUpperBoundId)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEDIMENSION_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
index 3188c711915c..ade2887bac14 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeEnum : public PDBSymbol {
public:
@@ -44,12 +45,12 @@ public:
FORWARD_SYMBOL_METHOD(hasOverloadedOperator)
FORWARD_SYMBOL_METHOD(isPacked)
FORWARD_SYMBOL_METHOD(isScoped)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getTypeId)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEENUM_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h
index 4d393d7b6c5c..196d149ed2a2 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeFriend : public PDBSymbol {
public:
@@ -28,10 +29,10 @@ public:
FORWARD_SYMBOL_METHOD(getClassParentId)
FORWARD_SYMBOL_METHOD(getName)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getTypeId)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEFRIEND_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h
index 14f79d99b6f8..5561341d7e77 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeFunctionArg : public PDBSymbol {
public:
@@ -28,10 +29,10 @@ public:
FORWARD_SYMBOL_METHOD(getClassParentId)
FORWARD_SYMBOL_METHOD(getLexicalParentId)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getTypeId)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEFUNCTIONARG_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
index 4bb4265a22f6..516011ff8b3d 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeFunctionSig : public PDBSymbol {
public:
@@ -38,7 +39,6 @@ public:
FORWARD_SYMBOL_METHOD(getCount)
FORWARD_SYMBOL_METHOD(getLexicalParentId)
// FORWARD_SYMBOL_METHOD(getObjectPointerType)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getThisAdjust)
FORWARD_SYMBOL_METHOD(getTypeId)
FORWARD_SYMBOL_METHOD(isUnalignedType)
@@ -46,5 +46,6 @@ public:
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEFUNCTIONSIG_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h
index cbfcec82a637..31cf5363dde1 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeManaged : public PDBSymbol {
public:
@@ -27,9 +28,9 @@ public:
void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getName)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEMANAGED_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
index 33578bad0245..7a57272adb79 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypePointer : public PDBSymbol {
public:
@@ -32,12 +33,12 @@ public:
FORWARD_SYMBOL_METHOD(getLength)
FORWARD_SYMBOL_METHOD(getLexicalParentId)
FORWARD_SYMBOL_METHOD(isReference)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getTypeId)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEPOINTER_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h
index 5ad83bb1ec26..5ed4f8d21d90 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeTypedef : public PDBSymbol {
public:
@@ -41,7 +42,6 @@ public:
FORWARD_SYMBOL_METHOD(isPacked)
FORWARD_SYMBOL_METHOD(isReference)
FORWARD_SYMBOL_METHOD(isScoped)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getTypeId)
FORWARD_SYMBOL_METHOD(getUdtKind)
FORWARD_SYMBOL_METHOD(isUnalignedType)
@@ -50,5 +50,6 @@ public:
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPETYPEDEF_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
index 99cc307a83e3..1874dfef34f7 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
@@ -17,6 +17,7 @@ namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeUDT : public PDBSymbol {
public:
PDBSymbolTypeUDT(const IPDBSession &PDBSession,
@@ -40,13 +41,12 @@ public:
FORWARD_SYMBOL_METHOD(hasOverloadedOperator)
FORWARD_SYMBOL_METHOD(isPacked)
FORWARD_SYMBOL_METHOD(isScoped)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getUdtKind)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(getVirtualTableShapeId)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
-
+}
} // namespace llvm
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEUDT_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h
index 6efc549f0cb7..baf7ab79d60e 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeVTable : public PDBSymbol {
public:
@@ -29,12 +30,12 @@ public:
FORWARD_SYMBOL_METHOD(getClassParentId)
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getLexicalParentId)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(getTypeId)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEVTABLE_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h
index f407595a4cc8..431fc1ac8625 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolTypeVTableShape : public PDBSymbol {
public:
@@ -29,11 +30,11 @@ public:
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getCount)
FORWARD_SYMBOL_METHOD(getLexicalParentId)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
FORWARD_SYMBOL_METHOD(isUnalignedType)
FORWARD_SYMBOL_METHOD(isVolatileType)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEVTABLESHAPE_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h b/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h
index 94bd2c14079f..de43e47badbd 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h
@@ -15,6 +15,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolUnknown : public PDBSymbol {
public:
@@ -30,5 +31,6 @@ public:
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLUNKNOWN_H
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h b/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h
index 7072f342bef3..a273fe159c12 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h
@@ -16,6 +16,7 @@
namespace llvm {
class raw_ostream;
+namespace pdb {
class PDBSymbolUsingNamespace : public PDBSymbol {
public:
@@ -28,9 +29,9 @@ public:
FORWARD_SYMBOL_METHOD(getLexicalParentId)
FORWARD_SYMBOL_METHOD(getName)
- FORWARD_SYMBOL_METHOD(getSymIndexId)
};
} // namespace llvm
+}
#endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLUSINGNAMESPACE_H
diff --git a/include/llvm/DebugInfo/PDB/PDBTypes.h b/include/llvm/DebugInfo/PDB/PDBTypes.h
index a932a56bb953..a9325a434366 100644
--- a/include/llvm/DebugInfo/PDB/PDBTypes.h
+++ b/include/llvm/DebugInfo/PDB/PDBTypes.h
@@ -11,11 +11,13 @@
#define LLVM_DEBUGINFO_PDB_PDBTYPES_H
#include "llvm/Config/llvm-config.h"
-#include "llvm/Support/Endian.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include <functional>
-#include <stdint.h>
+#include <cstdint>
+#include <cstring>
namespace llvm {
+namespace pdb {
class PDBSymDumper;
class PDBSymbol;
@@ -68,14 +70,14 @@ class PDBSymbolUnknown;
/// of PDB_ReaderType::DIA is supported.
enum class PDB_ReaderType {
DIA = 0,
+ Raw = 1,
};
/// Defines a 128-bit unique identifier. This maps to a GUID on Windows, but
/// is abstracted here for the purposes of non-Windows platforms that don't have
/// the GUID structure defined.
struct PDB_UniqueId {
- uint64_t HighPart;
- uint64_t LowPart;
+ char Guid[16];
};
/// An enumeration indicating the type of data contained in this table.
@@ -108,67 +110,7 @@ enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2 };
/// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
-enum class PDB_Cpu {
- Intel8080 = 0x0,
- Intel8086 = 0x1,
- Intel80286 = 0x2,
- Intel80386 = 0x3,
- Intel80486 = 0x4,
- Pentium = 0x5,
- PentiumPro = 0x6,
- Pentium3 = 0x7,
- MIPS = 0x10,
- MIPS16 = 0x11,
- MIPS32 = 0x12,
- MIPS64 = 0x13,
- MIPSI = 0x14,
- MIPSII = 0x15,
- MIPSIII = 0x16,
- MIPSIV = 0x17,
- MIPSV = 0x18,
- M68000 = 0x20,
- M68010 = 0x21,
- M68020 = 0x22,
- M68030 = 0x23,
- M68040 = 0x24,
- Alpha = 0x30,
- Alpha21164 = 0x31,
- Alpha21164A = 0x32,
- Alpha21264 = 0x33,
- Alpha21364 = 0x34,
- PPC601 = 0x40,
- PPC603 = 0x41,
- PPC604 = 0x42,
- PPC620 = 0x43,
- PPCFP = 0x44,
- PPCBE = 0x45,
- SH3 = 0x50,
- SH3E = 0x51,
- SH3DSP = 0x52,
- SH4 = 0x53,
- SHMedia = 0x54,
- ARM3 = 0x60,
- ARM4 = 0x61,
- ARM4T = 0x62,
- ARM5 = 0x63,
- ARM5T = 0x64,
- ARM6 = 0x65,
- ARM_XMAC = 0x66,
- ARM_WMMX = 0x67,
- ARM7 = 0x68,
- Omni = 0x70,
- Ia64 = 0x80,
- Ia64_2 = 0x81,
- CEE = 0x90,
- AM33 = 0xa0,
- M32R = 0xb0,
- TriCore = 0xc0,
- X64 = 0xd0,
- EBC = 0xe0,
- Thumb = 0xf0,
- ARMNT = 0xf4,
- D3D11_Shader = 0x100,
-};
+typedef codeview::CPUType PDB_Cpu;
enum class PDB_Machine {
Invalid = 0xffff,
@@ -200,56 +142,11 @@ enum class PDB_Machine {
/// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx
///
-enum class PDB_CallingConv {
- NearCdecl = 0x00,
- FarCdecl = 0x01,
- NearPascal = 0x02,
- FarPascal = 0x03,
- NearFastcall = 0x04,
- FarFastcall = 0x05,
- Skipped = 0x06,
- NearStdcall = 0x07,
- FarStdcall = 0x08,
- NearSyscall = 0x09,
- FarSyscall = 0x0a,
- Thiscall = 0x0b,
- MipsCall = 0x0c,
- Generic = 0x0d,
- Alphacall = 0x0e,
- Ppccall = 0x0f,
- SuperHCall = 0x10,
- Armcall = 0x11,
- AM33call = 0x12,
- Tricall = 0x13,
- Sh5call = 0x14,
- M32R = 0x15,
- Clrcall = 0x16,
- Inline = 0x17,
- NearVectorcall = 0x18,
- Reserved = 0x19,
-};
+typedef codeview::CallingConvention PDB_CallingConv;
/// These values correspond to the CV_CFL_LANG enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx
-enum class PDB_Lang {
- C = 0x00,
- Cpp = 0x01,
- Fortran = 0x02,
- Masm = 0x03,
- Pascal = 0x04,
- Basic = 0x05,
- Cobol = 0x06,
- Link = 0x07,
- Cvtres = 0x08,
- Cvtpgd = 0x09,
- CSharp = 0x0a,
- VB = 0x0b,
- ILAsm = 0x0c,
- Java = 0x0d,
- JScript = 0x0e,
- MSIL = 0x0f,
- HLSL = 0x10
-};
+typedef codeview::SourceLanguage PDB_Lang;
/// These values correspond to the DataKind enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/b2x2t313.aspx
@@ -320,18 +217,6 @@ enum class PDB_LocType {
Max
};
-/// These values correspond to the THUNK_ORDINAL enumeration, and are documented
-/// here: https://msdn.microsoft.com/en-us/library/dh0k8hft.aspx
-enum class PDB_ThunkOrdinal {
- Standard,
- ThisAdjustor,
- Vcall,
- Pcode,
- UnknownLoad,
- TrampIncremental,
- BranchIsland
-};
-
/// These values correspond to the UdtKind enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/wcstk66t.aspx
enum class PDB_UdtType { Struct, Class, Union, Interface };
@@ -367,72 +252,8 @@ enum class PDB_BuiltinType {
HResult = 31
};
-enum class PDB_RegisterId {
- Unknown = 0,
- VFrame = 30006,
- AL = 1,
- CL = 2,
- DL = 3,
- BL = 4,
- AH = 5,
- CH = 6,
- DH = 7,
- BH = 8,
- AX = 9,
- CX = 10,
- DX = 11,
- BX = 12,
- SP = 13,
- BP = 14,
- SI = 15,
- DI = 16,
- EAX = 17,
- ECX = 18,
- EDX = 19,
- EBX = 20,
- ESP = 21,
- EBP = 22,
- ESI = 23,
- EDI = 24,
- ES = 25,
- CS = 26,
- SS = 27,
- DS = 28,
- FS = 29,
- GS = 30,
- IP = 31,
- RAX = 328,
- RBX = 329,
- RCX = 330,
- RDX = 331,
- RSI = 332,
- RDI = 333,
- RBP = 334,
- RSP = 335,
- R8 = 336,
- R9 = 337,
- R10 = 338,
- R11 = 339,
- R12 = 340,
- R13 = 341,
- R14 = 342,
- R15 = 343,
-};
-
enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 };
-enum class PDB_ErrorCode {
- Success,
- NoPdbImpl,
- InvalidPath,
- InvalidFileFormat,
- InvalidParameter,
- AlreadyLoaded,
- UnknownError,
- NoMemory,
- DebugInfoMismatch
-};
-
struct VersionInfo {
uint32_t Major;
uint32_t Minor;
@@ -454,11 +275,19 @@ enum PDB_VariantType {
UInt32,
UInt64,
Bool,
+ String
};
struct Variant {
- Variant()
- : Type(PDB_VariantType::Empty) {
+ Variant() : Type(PDB_VariantType::Empty) {}
+
+ Variant(const Variant &Other) : Type(PDB_VariantType::Empty) {
+ *this = Other;
+ }
+
+ ~Variant() {
+ if (Type == PDB_VariantType::String)
+ delete[] Value.String;
}
PDB_VariantType Type;
@@ -474,10 +303,13 @@ struct Variant {
uint16_t UInt16;
uint32_t UInt32;
uint64_t UInt64;
- };
+ char *String;
+ } Value;
+
#define VARIANT_EQUAL_CASE(Enum) \
case PDB_VariantType::Enum: \
- return Enum == Other.Enum;
+ return Value.Enum == Other.Value.Enum;
+
bool operator==(const Variant &Other) const {
if (Type != Other.Type)
return false;
@@ -493,55 +325,43 @@ struct Variant {
VARIANT_EQUAL_CASE(UInt16)
VARIANT_EQUAL_CASE(UInt32)
VARIANT_EQUAL_CASE(UInt64)
+ VARIANT_EQUAL_CASE(String)
default:
return true;
}
}
+
#undef VARIANT_EQUAL_CASE
+
bool operator!=(const Variant &Other) const { return !(*this == Other); }
+ Variant &operator=(const Variant &Other) {
+ if (this == &Other)
+ return *this;
+ if (Type == PDB_VariantType::String)
+ delete[] Value.String;
+ Type = Other.Type;
+ Value = Other.Value;
+ if (Other.Type == PDB_VariantType::String &&
+ Other.Value.String != nullptr) {
+ Value.String = new char[strlen(Other.Value.String) + 1];
+ ::strcpy(Value.String, Other.Value.String);
+ }
+ return *this;
+ }
};
-namespace PDB {
-static const char Magic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f',
- 't', ' ', 'C', '/', 'C', '+', '+', ' ',
- 'M', 'S', 'F', ' ', '7', '.', '0', '0',
- '\r', '\n', '\x1a', 'D', 'S', '\0', '\0', '\0'};
-
-// The superblock is overlaid at the beginning of the file (offset 0).
-// It starts with a magic header and is followed by information which describes
-// the layout of the file system.
-struct SuperBlock {
- char MagicBytes[sizeof(Magic)];
- // The file system is split into a variable number of fixed size elements.
- // These elements are referred to as blocks. The size of a block may vary
- // from system to system.
- support::ulittle32_t BlockSize;
- // This field's purpose is not yet known.
- support::ulittle32_t Unknown0;
- // This contains the number of blocks resident in the file system. In
- // practice, NumBlocks * BlockSize is equivalent to the size of the PDB file.
- support::ulittle32_t NumBlocks;
- // This contains the number of bytes which make up the directory.
- support::ulittle32_t NumDirectoryBytes;
- // This field's purpose is not yet known.
- support::ulittle32_t Unknown1;
- // This contains the block # of the block map.
- support::ulittle32_t BlockMapAddr;
-};
+} // end namespace llvm
}
-} // namespace llvm
-
namespace std {
-template <> struct hash<llvm::PDB_SymType> {
- typedef llvm::PDB_SymType argument_type;
+template <> struct hash<llvm::pdb::PDB_SymType> {
+ typedef llvm::pdb::PDB_SymType argument_type;
typedef std::size_t result_type;
result_type operator()(const argument_type &Arg) const {
return std::hash<int>()(static_cast<int>(Arg));
}
};
-}
-
+} // end namespace std
-#endif
+#endif // LLVM_DEBUGINFO_PDB_PDBTYPES_H
diff --git a/include/llvm/DebugInfo/PDB/Raw/DbiStream.h b/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
new file mode 100644
index 000000000000..6ab3c8067558
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
@@ -0,0 +1,149 @@
+//===- DbiStream.h - PDB Dbi Stream (Stream 3) Access -----------*- 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_RAW_PDBDBISTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
+
+#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamRef.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
+#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace object {
+struct FpoData;
+struct coff_section;
+}
+
+namespace pdb {
+class DbiStreamBuilder;
+class PDBFile;
+class ISectionContribVisitor;
+
+class DbiStream {
+ friend class DbiStreamBuilder;
+
+ struct HeaderInfo {
+ support::little32_t VersionSignature;
+ support::ulittle32_t VersionHeader;
+ support::ulittle32_t Age; // Should match InfoStream.
+ support::ulittle16_t GlobalSymbolStreamIndex; // Global symbol stream #
+ support::ulittle16_t BuildNumber; // See DbiBuildNo structure.
+ support::ulittle16_t PublicSymbolStreamIndex; // Public symbols stream #
+ support::ulittle16_t PdbDllVersion; // version of mspdbNNN.dll
+ support::ulittle16_t SymRecordStreamIndex; // Symbol records stream #
+ support::ulittle16_t PdbDllRbld; // rbld number of mspdbNNN.dll
+ support::little32_t ModiSubstreamSize; // Size of module info stream
+ support::little32_t SecContrSubstreamSize; // Size of sec. contrib stream
+ support::little32_t SectionMapSize; // Size of sec. map substream
+ support::little32_t FileInfoSize; // Size of file info substream
+ support::little32_t TypeServerSize; // Size of type server map
+ support::ulittle32_t MFCTypeServerIndex; // Index of MFC Type Server
+ support::little32_t OptionalDbgHdrSize; // Size of DbgHeader info
+ support::little32_t ECSubstreamSize; // Size of EC stream (what is EC?)
+ support::ulittle16_t Flags; // See DbiFlags enum.
+ support::ulittle16_t MachineType; // See PDB_MachineType enum.
+
+ support::ulittle32_t Reserved; // Pad to 64 bytes
+ };
+
+public:
+ DbiStream(PDBFile &File, std::unique_ptr<MappedBlockStream> Stream);
+ ~DbiStream();
+ Error reload();
+
+ PdbRaw_DbiVer getDbiVersion() const;
+ uint32_t getAge() const;
+ uint16_t getPublicSymbolStreamIndex() const;
+ uint16_t getGlobalSymbolStreamIndex() const;
+
+ uint16_t getFlags() const;
+ bool isIncrementallyLinked() const;
+ bool hasCTypes() const;
+ bool isStripped() const;
+
+ uint16_t getBuildNumber() const;
+ uint16_t getBuildMajorVersion() const;
+ uint16_t getBuildMinorVersion() const;
+
+ uint16_t getPdbDllRbld() const;
+ uint32_t getPdbDllVersion() const;
+
+ uint32_t getSymRecordStreamIndex() const;
+
+ PDB_Machine getMachineType() const;
+
+ enum { InvalidStreamIndex = 0xffff };
+
+ /// If the given stream type is present, returns its stream index. If it is
+ /// not present, returns InvalidStreamIndex.
+ uint32_t getDebugStreamIndex(DbgHeaderType Type) const;
+
+ ArrayRef<ModuleInfoEx> modules() const;
+
+ Expected<StringRef> getFileNameForIndex(uint32_t Index) const;
+
+ codeview::FixedStreamArray<object::coff_section> getSectionHeaders();
+
+ codeview::FixedStreamArray<object::FpoData> getFpoRecords();
+
+ codeview::FixedStreamArray<SecMapEntry> getSectionMap() const;
+ void visitSectionContributions(ISectionContribVisitor &Visitor) const;
+
+ Error commit();
+
+private:
+ Error initializeSectionContributionData();
+ Error initializeSectionHeadersData();
+ Error initializeSectionMapData();
+ Error initializeFileInfo();
+ Error initializeFpoRecords();
+
+ PDBFile &Pdb;
+ std::unique_ptr<MappedBlockStream> Stream;
+
+ std::vector<ModuleInfoEx> ModuleInfos;
+ NameHashTable ECNames;
+
+ codeview::StreamRef ModInfoSubstream;
+ codeview::StreamRef SecContrSubstream;
+ codeview::StreamRef SecMapSubstream;
+ codeview::StreamRef FileInfoSubstream;
+ codeview::StreamRef TypeServerMapSubstream;
+ codeview::StreamRef ECSubstream;
+
+ codeview::StreamRef NamesBuffer;
+
+ codeview::FixedStreamArray<support::ulittle16_t> DbgStreams;
+
+ PdbRaw_DbiSecContribVer SectionContribVersion;
+ codeview::FixedStreamArray<SectionContrib> SectionContribs;
+ codeview::FixedStreamArray<SectionContrib2> SectionContribs2;
+ codeview::FixedStreamArray<SecMapEntry> SectionMap;
+ codeview::FixedStreamArray<support::little32_t> FileNameOffsets;
+
+ std::unique_ptr<MappedBlockStream> SectionHeaderStream;
+ codeview::FixedStreamArray<object::coff_section> SectionHeaders;
+
+ std::unique_ptr<MappedBlockStream> FpoStream;
+ codeview::FixedStreamArray<object::FpoData> FpoRecords;
+
+ const HeaderInfo *Header;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
new file mode 100644
index 000000000000..2c7350f3c3e7
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
@@ -0,0 +1,56 @@
+//===- DbiStreamBuilder.h - PDB Dbi Stream Creation -------------*- 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_RAW_PDBDBISTREAMBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAMBUILDER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Error.h"
+
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+
+namespace llvm {
+namespace pdb {
+class DbiStream;
+class PDBFile;
+
+class DbiStreamBuilder {
+public:
+ DbiStreamBuilder();
+
+ DbiStreamBuilder(const DbiStreamBuilder &) = delete;
+ DbiStreamBuilder &operator=(const DbiStreamBuilder &) = delete;
+
+ void setVersionHeader(PdbRaw_DbiVer V);
+ void setAge(uint32_t A);
+ void setBuildNumber(uint16_t B);
+ void setPdbDllVersion(uint16_t V);
+ void setPdbDllRbld(uint16_t R);
+ void setFlags(uint16_t F);
+ void setMachineType(PDB_Machine M);
+
+ uint32_t calculateSerializedLength() const;
+
+ Expected<std::unique_ptr<DbiStream>> build(PDBFile &File);
+
+private:
+ Optional<PdbRaw_DbiVer> VerHeader;
+ uint32_t Age;
+ uint16_t BuildNumber;
+ uint16_t PdbDllVersion;
+ uint16_t PdbDllRbld;
+ uint16_t Flags;
+ PDB_Machine MachineType;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/DirectoryStreamData.h b/include/llvm/DebugInfo/PDB/Raw/DirectoryStreamData.h
new file mode 100644
index 000000000000..0f354315122c
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/DirectoryStreamData.h
@@ -0,0 +1,37 @@
+//===- DirectoryStreamData.h ---------------------------------- *- 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_RAW_DIRECTORYSTREAMDATA_H
+#define LLVM_DEBUGINFO_PDB_RAW_DIRECTORYSTREAMDATA_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace pdb {
+class IPDBFile;
+
+class DirectoryStreamData : public IPDBStreamData {
+public:
+ DirectoryStreamData(const PDBFile &File) : File(File) {}
+
+ virtual uint32_t getLength() { return File.getNumDirectoryBytes(); }
+ virtual llvm::ArrayRef<llvm::support::ulittle32_t> getStreamBlocks() {
+ return File.getDirectoryBlockArray();
+ }
+
+private:
+ const PDBFile &File;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/EnumTables.h b/include/llvm/DebugInfo/PDB/Raw/EnumTables.h
new file mode 100644
index 000000000000..c018445630fe
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/EnumTables.h
@@ -0,0 +1,22 @@
+//===- EnumTables.h - Enum to string conversion tables ----------*- 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_RAW_ENUMTABLES_H
+#define LLVM_DEBUGINFO_PDB_RAW_ENUMTABLES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+namespace llvm {
+namespace pdb {
+ArrayRef<EnumEntry<uint16_t>> getOMFSegMapDescFlagNames();
+}
+}
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_ENUMTABLES_H
diff --git a/include/llvm/DebugInfo/PDB/Raw/Hash.h b/include/llvm/DebugInfo/PDB/Raw/Hash.h
new file mode 100644
index 000000000000..0340554d7b0b
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/Hash.h
@@ -0,0 +1,25 @@
+//===- Hash.h - PDB hash functions ------------------------------*- 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_RAW_HASH_H
+#define LLVM_DEBUGINFO_PDB_RAW_HASH_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include <stdint.h>
+
+namespace llvm {
+namespace pdb {
+uint32_t hashStringV1(StringRef Str);
+uint32_t hashStringV2(StringRef Str);
+uint32_t hashBufferV8(ArrayRef<uint8_t> Data);
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h b/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h
new file mode 100644
index 000000000000..fccea2ac2470
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h
@@ -0,0 +1,44 @@
+//===- IPDBFile.h - Abstract base class for a PDB file ----------*- 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_RAW_IPDBFILE_H
+#define LLVM_DEBUGINFO_PDB_RAW_IPDBFILE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+#include <stdint.h>
+
+namespace llvm {
+namespace pdb {
+
+class IPDBFile {
+public:
+ virtual ~IPDBFile() {}
+
+ virtual uint32_t getBlockSize() const = 0;
+ virtual uint32_t getBlockCount() const = 0;
+
+ virtual uint32_t getNumStreams() const = 0;
+ virtual uint32_t getStreamByteSize(uint32_t StreamIndex) const = 0;
+ virtual ArrayRef<support::ulittle32_t>
+ getStreamBlockList(uint32_t StreamIndex) const = 0;
+
+ virtual Expected<ArrayRef<uint8_t>> getBlockData(uint32_t BlockIndex,
+ uint32_t NumBytes) const = 0;
+ virtual Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
+ ArrayRef<uint8_t> Data) const = 0;
+};
+}
+}
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_IPDBFILE_H
diff --git a/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h b/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h
new file mode 100644
index 000000000000..ab3c9f770755
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h
@@ -0,0 +1,38 @@
+//===- IPDBStreamData.h - Base interface for PDB Stream Data ----*- 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_RAW_IPDBSTREAMDATA_H
+#define LLVM_DEBUGINFO_PDB_RAW_IPDBSTREAMDATA_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace pdb {
+/// IPDBStream abstracts the notion of PDB stream data. Although we already
+/// have another stream abstraction (namely in the form of StreamInterface
+/// and MappedBlockStream), they assume that the stream data is referenced
+/// the same way. Namely, by looking in the directory to get the list of
+/// stream blocks, and by looking in the array of stream lengths to get the
+/// length. This breaks down for the directory itself, however, since its
+/// length and list of blocks are stored elsewhere. By abstracting the
+/// notion of stream data further, we can use a MappedBlockStream to read
+/// from the directory itself, or from an indexed stream which references
+/// the directory.
+class IPDBStreamData {
+public:
+ virtual ~IPDBStreamData() {}
+
+ virtual uint32_t getLength() = 0;
+ virtual ArrayRef<support::ulittle32_t> getStreamBlocks() = 0;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h b/include/llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h
new file mode 100644
index 000000000000..355a25a38ef8
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h
@@ -0,0 +1,28 @@
+//===- ISectionContribVisitor.h ---------------------------------*- 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_RAW_ISECTIONCONTRIBVISITOR_H
+#define LLVM_DEBUGINFO_PDB_RAW_ISECTIONCONTRIBVISITOR_H
+
+namespace llvm {
+namespace pdb {
+struct SectionContrib;
+struct SectionContrib2;
+
+class ISectionContribVisitor {
+public:
+ virtual ~ISectionContribVisitor() {}
+
+ virtual void visit(const SectionContrib &C) = 0;
+ virtual void visit(const SectionContrib2 &C) = 0;
+};
+} // namespace pdb
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_ISECTIONCONTRIBVISITOR_H
diff --git a/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h b/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h
new file mode 100644
index 000000000000..30563bc5b898
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h
@@ -0,0 +1,34 @@
+//===- IndexedStreamData.h - Standard PDB Stream Data -----------*- 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_RAW_INDEXEDSTREAMDATA_H
+#define LLVM_DEBUGINFO_PDB_RAW_INDEXEDSTREAMDATA_H
+
+#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
+
+namespace llvm {
+namespace pdb {
+class IPDBFile;
+
+class IndexedStreamData : public IPDBStreamData {
+public:
+ IndexedStreamData(uint32_t StreamIdx, const IPDBFile &File);
+ virtual ~IndexedStreamData() {}
+
+ uint32_t getLength() override;
+ ArrayRef<support::ulittle32_t> getStreamBlocks() override;
+
+private:
+ uint32_t StreamIdx;
+ const IPDBFile &File;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/InfoStream.h b/include/llvm/DebugInfo/PDB/Raw/InfoStream.h
new file mode 100644
index 000000000000..1980bec7153e
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/InfoStream.h
@@ -0,0 +1,77 @@
+//===- InfoStream.h - PDB Info Stream (Stream 1) Access ---------*- 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_RAW_PDBINFOSTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAM_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Raw/NameMap.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace pdb {
+class InfoStreamBuilder;
+class PDBFile;
+
+class InfoStream {
+ friend class InfoStreamBuilder;
+
+ struct HeaderInfo {
+ support::ulittle32_t Version;
+ support::ulittle32_t Signature;
+ support::ulittle32_t Age;
+ PDB_UniqueId Guid;
+ };
+
+public:
+ InfoStream(std::unique_ptr<MappedBlockStream> Stream);
+
+ Error reload();
+ Error commit();
+
+ PdbRaw_ImplVer getVersion() const;
+ uint32_t getSignature() const;
+ uint32_t getAge() const;
+ PDB_UniqueId getGuid() const;
+
+ uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
+ iterator_range<StringMapConstIterator<uint32_t>> named_streams() const;
+
+private:
+ std::unique_ptr<MappedBlockStream> Stream;
+
+ // PDB file format version. We only support VC70. See the enumeration
+ // `PdbRaw_ImplVer` for the other possible values.
+ uint32_t Version;
+
+ // A 32-bit signature unique across all PDBs. This is generated with
+ // a call to time() when the PDB is written, but obviously this is not
+ // universally unique.
+ uint32_t Signature;
+
+ // The number of times the PDB has been written. Might also be used to
+ // ensure that the PDB matches the executable.
+ uint32_t Age;
+
+ // Due to the aforementioned limitations with `Signature`, this is a new
+ // signature present on VC70 and higher PDBs which is guaranteed to be
+ // universally unique.
+ PDB_UniqueId Guid;
+
+ NameMap NamedStreams;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h b/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h
new file mode 100644
index 000000000000..e9869bb27863
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h
@@ -0,0 +1,53 @@
+//===- InfoStreamBuilder.h - PDB Info Stream Creation -----------*- 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_RAW_PDBINFOSTREAMBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAMBUILDER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Error.h"
+
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/DebugInfo/PDB/Raw/NameMapBuilder.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+
+namespace llvm {
+namespace pdb {
+class PDBFile;
+
+class InfoStreamBuilder {
+public:
+ InfoStreamBuilder();
+ InfoStreamBuilder(const InfoStreamBuilder &) = delete;
+ InfoStreamBuilder &operator=(const InfoStreamBuilder &) = delete;
+
+ void setVersion(PdbRaw_ImplVer V);
+ void setSignature(uint32_t S);
+ void setAge(uint32_t A);
+ void setGuid(PDB_UniqueId G);
+
+ NameMapBuilder &getNamedStreamsBuilder();
+
+ uint32_t calculateSerializedLength() const;
+
+ Expected<std::unique_ptr<InfoStream>> build(PDBFile &File);
+
+private:
+ Optional<PdbRaw_ImplVer> Ver;
+ Optional<uint32_t> Sig;
+ Optional<uint32_t> Age;
+ Optional<PDB_UniqueId> Guid;
+
+ NameMapBuilder NamedStreams;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h b/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
new file mode 100644
index 000000000000..36424c0d16ab
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
@@ -0,0 +1,68 @@
+//===- MappedBlockStream.h - Reads stream data from a PDBFile ---*- 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_RAW_MAPPEDBLOCKSTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_MAPPEDBLOCKSTREAM_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/StreamInterface.h"
+#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace pdb {
+
+class IPDBFile;
+class PDBFile;
+
+class MappedBlockStream : public codeview::StreamInterface {
+public:
+ Error readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) const override;
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) const override;
+ Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
+
+ uint32_t getLength() const override;
+ Error commit() const override;
+
+ uint32_t getNumBytesCopied() const;
+
+ static Expected<std::unique_ptr<MappedBlockStream>>
+ createIndexedStream(uint32_t StreamIdx, const IPDBFile &File);
+ static Expected<std::unique_ptr<MappedBlockStream>>
+ createDirectoryStream(const PDBFile &File);
+
+ llvm::BumpPtrAllocator &getAllocator() { return Pool; }
+
+protected:
+ MappedBlockStream(std::unique_ptr<IPDBStreamData> Data, const IPDBFile &File);
+
+ Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer) const;
+ bool tryReadContiguously(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) const;
+
+ const IPDBFile &Pdb;
+ std::unique_ptr<IPDBStreamData> Data;
+
+ typedef MutableArrayRef<uint8_t> CacheEntry;
+ mutable llvm::BumpPtrAllocator Pool;
+ mutable DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_MAPPEDBLOCKSTREAM_H
diff --git a/include/llvm/DebugInfo/PDB/Raw/ModInfo.h b/include/llvm/DebugInfo/PDB/Raw/ModInfo.h
new file mode 100644
index 000000000000..b8da0bfabf38
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/ModInfo.h
@@ -0,0 +1,79 @@
+//===- ModInfo.h - PDB module information -----------------------*- 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_RAW_MODINFO_H
+#define LLVM_DEBUGINFO_PDB_RAW_MODINFO_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamRef.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace pdb {
+
+class ModInfo {
+private:
+ struct FileLayout;
+
+public:
+ ModInfo();
+ ModInfo(const ModInfo &Info);
+ ~ModInfo();
+
+ static Error initialize(codeview::StreamRef Stream, ModInfo &Info);
+
+ bool hasECInfo() const;
+ uint16_t getTypeServerIndex() const;
+ uint16_t getModuleStreamIndex() const;
+ uint32_t getSymbolDebugInfoByteSize() const;
+ uint32_t getLineInfoByteSize() const;
+ uint32_t getC13LineInfoByteSize() const;
+ uint32_t getNumberOfFiles() const;
+ uint32_t getSourceFileNameIndex() const;
+ uint32_t getPdbFilePathNameIndex() const;
+
+ StringRef getModuleName() const;
+ StringRef getObjFileName() const;
+
+ uint32_t getRecordLength() const;
+
+private:
+ StringRef ModuleName;
+ StringRef ObjFileName;
+ const FileLayout *Layout;
+};
+
+struct ModuleInfoEx {
+ ModuleInfoEx(const ModInfo &Info) : Info(Info) {}
+ ModuleInfoEx(const ModuleInfoEx &Ex)
+ : Info(Ex.Info), SourceFiles(Ex.SourceFiles) {}
+
+ ModInfo Info;
+ std::vector<StringRef> SourceFiles;
+};
+
+} // end namespace pdb
+
+namespace codeview {
+template <> struct VarStreamArrayExtractor<pdb::ModInfo> {
+ Error operator()(StreamRef Stream, uint32_t &Length,
+ pdb::ModInfo &Info) const {
+ if (auto EC = pdb::ModInfo::initialize(Stream, Info))
+ return EC;
+ Length = Info.getRecordLength();
+ return Error::success();
+ }
+};
+}
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_MODINFO_H
diff --git a/include/llvm/DebugInfo/PDB/Raw/ModStream.h b/include/llvm/DebugInfo/PDB/Raw/ModStream.h
new file mode 100644
index 000000000000..d22962cc1e28
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/ModStream.h
@@ -0,0 +1,57 @@
+//===- ModStream.h - PDB Module Info Stream Access ------------------------===//
+//
+// 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_RAW_MODSTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_MODSTREAM_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamRef.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace pdb {
+class PDBFile;
+class ModInfo;
+
+class ModStream {
+public:
+ ModStream(const ModInfo &Module, std::unique_ptr<MappedBlockStream> Stream);
+ ~ModStream();
+
+ Error reload();
+
+ iterator_range<codeview::CVSymbolArray::Iterator>
+ symbols(bool *HadError) const;
+
+ iterator_range<codeview::ModuleSubstreamArray::Iterator>
+ lines(bool *HadError) const;
+
+ Error commit();
+
+private:
+ const ModInfo &Mod;
+
+ std::unique_ptr<MappedBlockStream> Stream;
+
+ codeview::CVSymbolArray SymbolsSubstream;
+ codeview::StreamRef LinesSubstream;
+ codeview::StreamRef C13LinesSubstream;
+ codeview::StreamRef GlobalRefsSubstream;
+
+ codeview::ModuleSubstreamArray LineInfo;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/MsfBuilder.h b/include/llvm/DebugInfo/PDB/Raw/MsfBuilder.h
new file mode 100644
index 000000000000..92d9bc042cce
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/MsfBuilder.h
@@ -0,0 +1,141 @@
+//===- MSFBuilder.h - MSF Directory & Metadata Builder ----------*- 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_RAW_MSFBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_MSFBUILDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+
+#include "llvm/DebugInfo/PDB/Raw/MsfCommon.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+#include <utility>
+#include <vector>
+
+namespace llvm {
+namespace pdb {
+class MsfBuilder {
+public:
+ /// \brief Create a new `MsfBuilder`.
+ ///
+ /// \param BlockSize The internal block size used by the PDB file. See
+ /// isValidBlockSize() for a list of valid block sizes.
+ ///
+ /// \param MinBlockCount Causes the builder to reserve up front space for
+ /// at least `MinBlockCount` blocks. This is useful when using `MsfBuilder`
+ /// to read an existing PDB that you want to write back out later. The
+ /// original PDB file's SuperBlock contains the exact number of blocks used
+ /// by the file, so is a good hint as to how many blocks the new PDB file
+ /// will contain. Furthermore, it is actually necessary in this case. To
+ /// preserve stability of the file's layout, it is helpful to try to keep
+ /// all streams mapped to their original block numbers. To ensure that this
+ /// is possible, space for all blocks must be allocated beforehand so that
+ /// streams can be assigned to them.
+ ///
+ /// \param CanGrow If true, any operation which results in an attempt to
+ /// locate a free block when all available blocks have been exhausted will
+ /// allocate a new block, thereby growing the size of the final PDB file.
+ /// When false, any such attempt will result in an error. This is especially
+ /// useful in testing scenarios when you know your test isn't going to do
+ /// anything to increase the size of the file, so having an Error returned if
+ /// it were to happen would catch a programming error
+ ///
+ /// \returns an llvm::Error representing whether the operation succeeded or
+ /// failed. Currently the only way this can fail is if an invalid block size
+ /// is specified, or `MinBlockCount` does not leave enough room for the
+ /// mandatory reserved blocks required by an MSF file.
+ static Expected<MsfBuilder> create(BumpPtrAllocator &Allocator,
+ uint32_t BlockSize,
+ uint32_t MinBlockCount = 0,
+ bool CanGrow = true);
+
+ /// Request the block map to be at a specific block address. This is useful
+ /// when editing a PDB and you want the layout to be as stable as possible.
+ Error setBlockMapAddr(uint32_t Addr);
+ Error setDirectoryBlocksHint(ArrayRef<uint32_t> DirBlocks);
+ void setFreePageMap(uint32_t Fpm);
+ void setUnknown1(uint32_t Unk1);
+
+ /// Add a stream to the MSF file with the given size, occupying the given
+ /// list of blocks. This is useful when reading a PDB file and you want a
+ /// particular stream to occupy the original set of blocks. If the given
+ /// blocks are already allocated, or if the number of blocks specified is
+ /// incorrect for the given stream size, this function will return an Error.
+ Error addStream(uint32_t Size, ArrayRef<uint32_t> Blocks);
+
+ /// Add a stream to the MSF file with the given size, occupying any available
+ /// blocks that the builder decides to use. This is useful when building a
+ /// new PDB file from scratch and you don't care what blocks a stream occupies
+ /// but you just want it to work.
+ Error addStream(uint32_t Size);
+
+ /// Update the size of an existing stream. This will allocate or deallocate
+ /// blocks as needed to match the requested size. This can fail if `CanGrow`
+ /// was set to false when initializing the `MsfBuilder`.
+ Error setStreamSize(uint32_t Idx, uint32_t Size);
+
+ /// Get the total number of streams in the MSF layout. This should return 1
+ /// for every call to `addStream`.
+ uint32_t getNumStreams() const;
+
+ /// Get the size of a stream by index.
+ uint32_t getStreamSize(uint32_t StreamIdx) const;
+
+ /// Get the list of blocks allocated to a particular stream.
+ ArrayRef<uint32_t> getStreamBlocks(uint32_t StreamIdx) const;
+
+ /// Get the total number of blocks that will be allocated to actual data in
+ /// this MSF file.
+ uint32_t getNumUsedBlocks() const;
+
+ /// Get the total number of blocks that exist in the MSF file but are not
+ /// allocated to any valid data.
+ uint32_t getNumFreeBlocks() const;
+
+ /// Get the total number of blocks in the MSF file. In practice this is equal
+ /// to `getNumUsedBlocks() + getNumFreeBlocks()`.
+ uint32_t getTotalBlockCount() const;
+
+ /// Check whether a particular block is allocated or free.
+ bool isBlockFree(uint32_t Idx) const;
+
+ /// Finalize the layout and build the headers and structures that describe the
+ /// MSF layout and can be written directly to the MSF file.
+ Expected<msf::Layout> build();
+
+private:
+ MsfBuilder(uint32_t BlockSize, uint32_t MinBlockCount, bool CanGrow,
+ BumpPtrAllocator &Allocator);
+
+ Error allocateBlocks(uint32_t NumBlocks, MutableArrayRef<uint32_t> Blocks);
+ uint32_t computeDirectoryByteSize() const;
+
+ typedef std::vector<uint32_t> BlockList;
+
+ BumpPtrAllocator &Allocator;
+
+ bool IsGrowable;
+ uint32_t FreePageMap;
+ uint32_t Unknown1;
+ uint32_t BlockSize;
+ uint32_t MininumBlocks;
+ uint32_t BlockMapAddr;
+ BitVector FreeBlocks;
+ std::vector<uint32_t> DirectoryBlocks;
+ std::vector<std::pair<uint32_t, BlockList>> StreamData;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/MsfCommon.h b/include/llvm/DebugInfo/PDB/Raw/MsfCommon.h
new file mode 100644
index 000000000000..2f6a6986eba9
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/MsfCommon.h
@@ -0,0 +1,90 @@
+//===- MsfCommon.h - Common types and functions for MSF files ---*- 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_RAW_MSFCOMMON_H
+#define LLVM_DEBUGINFO_PDB_RAW_MSFCOMMON_H
+
+#include "llvm/ADT/ArrayRef.h"
+
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+
+#include <vector>
+
+namespace llvm {
+namespace pdb {
+namespace msf {
+static const char Magic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f',
+ 't', ' ', 'C', '/', 'C', '+', '+', ' ',
+ 'M', 'S', 'F', ' ', '7', '.', '0', '0',
+ '\r', '\n', '\x1a', 'D', 'S', '\0', '\0', '\0'};
+
+// The superblock is overlaid at the beginning of the file (offset 0).
+// It starts with a magic header and is followed by information which
+// describes the layout of the file system.
+struct SuperBlock {
+ char MagicBytes[sizeof(Magic)];
+ // The file system is split into a variable number of fixed size elements.
+ // These elements are referred to as blocks. The size of a block may vary
+ // from system to system.
+ support::ulittle32_t BlockSize;
+ // The index of the free block map.
+ support::ulittle32_t FreeBlockMapBlock;
+ // This contains the number of blocks resident in the file system. In
+ // practice, NumBlocks * BlockSize is equivalent to the size of the PDB
+ // file.
+ support::ulittle32_t NumBlocks;
+ // This contains the number of bytes which make up the directory.
+ support::ulittle32_t NumDirectoryBytes;
+ // This field's purpose is not yet known.
+ support::ulittle32_t Unknown1;
+ // This contains the block # of the block map.
+ support::ulittle32_t BlockMapAddr;
+};
+
+struct Layout {
+ SuperBlock *SB;
+ ArrayRef<support::ulittle32_t> DirectoryBlocks;
+ ArrayRef<support::ulittle32_t> StreamSizes;
+ std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
+};
+
+inline bool isValidBlockSize(uint32_t Size) {
+ switch (Size) {
+ case 512:
+ case 1024:
+ case 2048:
+ case 4096:
+ return true;
+ }
+ return false;
+}
+
+// Super Block, Fpm0, Fpm1, and Block Map
+inline uint32_t getMinimumBlockCount() { return 4; }
+
+// Super Block, Fpm0, and Fpm1 are reserved. The Block Map, although required
+// need not be at block 3.
+inline uint32_t getFirstUnreservedBlock() { return 3; }
+
+inline uint64_t bytesToBlocks(uint64_t NumBytes, uint64_t BlockSize) {
+ return alignTo(NumBytes, BlockSize) / BlockSize;
+}
+
+inline uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize) {
+ return BlockNumber * BlockSize;
+}
+
+Error validateSuperBlock(const SuperBlock &SB);
+}
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h b/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h
new file mode 100644
index 000000000000..c9e060a3a70f
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h
@@ -0,0 +1,54 @@
+//===- NameHashTable.h - PDB Name Hash Table --------------------*- 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_RAW_NAMEHASHTABLE_H
+#define LLVM_DEBUGINFO_PDB_RAW_NAMEHASHTABLE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+class StreamReader;
+}
+namespace pdb {
+
+class NameHashTable {
+public:
+ NameHashTable();
+
+ Error load(codeview::StreamReader &Stream);
+
+ uint32_t getNameCount() const { return NameCount; }
+ uint32_t getHashVersion() const { return HashVersion; }
+ uint32_t getSignature() const { return Signature; }
+
+ StringRef getStringForID(uint32_t ID) const;
+ uint32_t getIDForString(StringRef Str) const;
+
+ codeview::FixedStreamArray<support::ulittle32_t> name_ids() const;
+
+private:
+ codeview::StreamRef NamesBuffer;
+ codeview::FixedStreamArray<support::ulittle32_t> IDs;
+ uint32_t Signature;
+ uint32_t HashVersion;
+ uint32_t NameCount;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_NAMEHASHTABLE_H
diff --git a/include/llvm/DebugInfo/PDB/Raw/NameMap.h b/include/llvm/DebugInfo/PDB/Raw/NameMap.h
new file mode 100644
index 000000000000..8a9b0d187ace
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/NameMap.h
@@ -0,0 +1,45 @@
+//===- NameMap.h - PDB Name Map ---------------------------------*- 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_RAW_PDBNAMEMAP_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAP_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+
+namespace llvm {
+namespace codeview {
+class StreamReader;
+class StreamWriter;
+}
+namespace pdb {
+class NameMapBuilder;
+class NameMap {
+ friend NameMapBuilder;
+
+public:
+ NameMap();
+
+ Error load(codeview::StreamReader &Stream);
+ Error commit(codeview::StreamWriter &Writer);
+
+ bool tryGetValue(StringRef Name, uint32_t &Value) const;
+
+ iterator_range<StringMapConstIterator<uint32_t>> entries() const;
+
+private:
+ StringMap<uint32_t> Mapping;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAP_H
diff --git a/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h b/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h
new file mode 100644
index 000000000000..bf49bfd9bf2e
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h
@@ -0,0 +1,41 @@
+//===- NameMapBuilder.h - PDB Name Map Builder ------------------*- 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_RAW_PDBNAMEMAPBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAPBUILDER_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Error.h"
+
+#include <cstdint>
+#include <memory>
+
+namespace llvm {
+namespace pdb {
+class NameMap;
+
+class NameMapBuilder {
+public:
+ NameMapBuilder();
+
+ void addMapping(StringRef Name, uint32_t Mapping);
+
+ Expected<std::unique_ptr<NameMap>> build();
+
+ uint32_t calculateSerializedLength() const;
+
+private:
+ StringMap<uint32_t> Map;
+ uint32_t StringDataBytes = 0;
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAPBUILDER_H
diff --git a/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
new file mode 100644
index 000000000000..f4d7eb47d3b9
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
@@ -0,0 +1,113 @@
+//===- PDBFile.h - Low level interface to a PDB file ------------*- 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_RAW_PDBFILE_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBFILE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamInterface.h"
+#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
+#include "llvm/DebugInfo/PDB/Raw/MsfCommon.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+
+#include <memory>
+
+namespace llvm {
+
+namespace codeview {
+class StreamInterface;
+}
+
+namespace pdb {
+class DbiStream;
+class InfoStream;
+class MappedBlockStream;
+class NameHashTable;
+class PDBFileBuilder;
+class PublicsStream;
+class SymbolStream;
+class TpiStream;
+
+class PDBFile : public IPDBFile {
+ friend PDBFileBuilder;
+
+public:
+ explicit PDBFile(std::unique_ptr<codeview::StreamInterface> PdbFileBuffer);
+ ~PDBFile() override;
+
+ uint32_t getFreeBlockMapBlock() const;
+ uint32_t getUnknown1() const;
+
+ uint32_t getBlockSize() const override;
+ uint32_t getBlockCount() const override;
+ uint32_t getNumDirectoryBytes() const;
+ uint32_t getBlockMapIndex() const;
+ uint32_t getNumDirectoryBlocks() const;
+ uint64_t getBlockMapOffset() const;
+
+ uint32_t getNumStreams() const override;
+ uint32_t getStreamByteSize(uint32_t StreamIndex) const override;
+ ArrayRef<support::ulittle32_t>
+ getStreamBlockList(uint32_t StreamIndex) const override;
+ uint32_t getFileSize() const;
+
+ Expected<ArrayRef<uint8_t>> getBlockData(uint32_t BlockIndex,
+ uint32_t NumBytes) const override;
+ Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
+ ArrayRef<uint8_t> Data) const override;
+
+ ArrayRef<support::ulittle32_t> getStreamSizes() const { return StreamSizes; }
+ ArrayRef<ArrayRef<support::ulittle32_t>> getStreamMap() const {
+ return StreamMap;
+ }
+
+ ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
+
+ Error parseFileHeaders();
+ Error parseStreamData();
+
+ Expected<InfoStream &> getPDBInfoStream();
+ Expected<DbiStream &> getPDBDbiStream();
+ Expected<TpiStream &> getPDBTpiStream();
+ Expected<TpiStream &> getPDBIpiStream();
+ Expected<PublicsStream &> getPDBPublicsStream();
+ Expected<SymbolStream &> getPDBSymbolStream();
+ Expected<NameHashTable &> getStringTable();
+
+ Error commit();
+
+private:
+ Error setSuperBlock(const msf::SuperBlock *Block);
+
+ BumpPtrAllocator Allocator;
+
+ std::unique_ptr<codeview::StreamInterface> Buffer;
+ const msf::SuperBlock *SB;
+ ArrayRef<support::ulittle32_t> StreamSizes;
+ ArrayRef<support::ulittle32_t> DirectoryBlocks;
+ std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
+
+ std::unique_ptr<InfoStream> Info;
+ std::unique_ptr<DbiStream> Dbi;
+ std::unique_ptr<TpiStream> Tpi;
+ std::unique_ptr<TpiStream> Ipi;
+ std::unique_ptr<PublicsStream> Publics;
+ std::unique_ptr<SymbolStream> Symbols;
+ std::unique_ptr<MappedBlockStream> DirectoryStream;
+ std::unique_ptr<MappedBlockStream> StringTableStream;
+ std::unique_ptr<NameHashTable> StringTable;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h b/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h
new file mode 100644
index 000000000000..47c755b43269
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h
@@ -0,0 +1,59 @@
+//===- PDBFileBuilder.h - PDB File Creation ---------------------*- 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_RAW_PDBFILEBUILDER_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBFILEBUILDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+#include "llvm/DebugInfo/PDB/Raw/MsfBuilder.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+
+#include <memory>
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+class StreamInterface;
+}
+namespace pdb {
+class DbiStreamBuilder;
+class InfoStreamBuilder;
+class PDBFile;
+
+class PDBFileBuilder {
+public:
+ explicit PDBFileBuilder(
+ std::unique_ptr<codeview::StreamInterface> FileBuffer);
+ PDBFileBuilder(const PDBFileBuilder &) = delete;
+ PDBFileBuilder &operator=(const PDBFileBuilder &) = delete;
+
+ Error initialize(const msf::SuperBlock &Super);
+
+ MsfBuilder &getMsfBuilder();
+ InfoStreamBuilder &getInfoBuilder();
+ DbiStreamBuilder &getDbiBuilder();
+
+ Expected<std::unique_ptr<PDBFile>> build();
+
+private:
+ std::unique_ptr<InfoStreamBuilder> Info;
+ std::unique_ptr<DbiStreamBuilder> Dbi;
+
+ std::unique_ptr<PDBFile> File;
+ std::unique_ptr<MsfBuilder> Msf;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h b/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h
new file mode 100644
index 000000000000..f5bfb0ed60a9
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h
@@ -0,0 +1,74 @@
+//===- PublicsStream.h - PDB Public Symbol Stream -------- ------*- 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_RAW_PUBLICSSTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_PUBLICSSTREAM_H
+
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
+
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace pdb {
+class DbiStream;
+class PDBFile;
+
+class PublicsStream {
+ struct GSIHashHeader;
+ struct HeaderInfo;
+
+public:
+ PublicsStream(PDBFile &File, std::unique_ptr<MappedBlockStream> Stream);
+ ~PublicsStream();
+ Error reload();
+
+ uint32_t getSymHash() const;
+ uint32_t getAddrMap() const;
+ uint32_t getNumBuckets() const { return NumBuckets; }
+ iterator_range<codeview::CVSymbolArray::Iterator>
+ getSymbols(bool *HadError) const;
+ codeview::FixedStreamArray<support::ulittle32_t> getHashBuckets() const {
+ return HashBuckets;
+ }
+ codeview::FixedStreamArray<support::ulittle32_t> getAddressMap() const {
+ return AddressMap;
+ }
+ codeview::FixedStreamArray<support::ulittle32_t> getThunkMap() const {
+ return ThunkMap;
+ }
+ codeview::FixedStreamArray<SectionOffset> getSectionOffsets() const {
+ return SectionOffsets;
+ }
+
+ Error commit();
+
+private:
+ PDBFile &Pdb;
+
+ std::unique_ptr<MappedBlockStream> Stream;
+ uint32_t NumBuckets = 0;
+ ArrayRef<uint8_t> Bitmap;
+ codeview::FixedStreamArray<PSHashRecord> HashRecords;
+ codeview::FixedStreamArray<support::ulittle32_t> HashBuckets;
+ codeview::FixedStreamArray<support::ulittle32_t> AddressMap;
+ codeview::FixedStreamArray<support::ulittle32_t> ThunkMap;
+ codeview::FixedStreamArray<SectionOffset> SectionOffsets;
+
+ const HeaderInfo *Header;
+ const GSIHashHeader *HashHdr;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/RawConstants.h b/include/llvm/DebugInfo/PDB/Raw/RawConstants.h
new file mode 100644
index 000000000000..8daaf47882d8
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/RawConstants.h
@@ -0,0 +1,94 @@
+//===- RawConstants.h -------------------------------------------*- 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_RAW_PDBRAWCONSTANTS_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+
+#include <cstdint>
+
+namespace llvm {
+namespace pdb {
+
+enum PdbRaw_ImplVer : uint32_t {
+ PdbImplVC2 = 19941610,
+ PdbImplVC4 = 19950623,
+ PdbImplVC41 = 19950814,
+ PdbImplVC50 = 19960307,
+ PdbImplVC98 = 19970604,
+ PdbImplVC70Dep = 19990604, // deprecated
+ PdbImplVC70 = 20000404,
+ PdbImplVC80 = 20030901,
+ PdbImplVC110 = 20091201,
+ PdbImplVC140 = 20140508,
+};
+
+enum PdbRaw_DbiVer : uint32_t {
+ PdbDbiVC41 = 930803,
+ PdbDbiV50 = 19960307,
+ PdbDbiV60 = 19970606,
+ PdbDbiV70 = 19990903,
+ PdbDbiV110 = 20091201
+};
+
+enum PdbRaw_TpiVer : uint32_t {
+ PdbTpiV40 = 19950410,
+ PdbTpiV41 = 19951122,
+ PdbTpiV50 = 19961031,
+ PdbTpiV70 = 19990903,
+ PdbTpiV80 = 20040203,
+};
+
+enum PdbRaw_DbiSecContribVer : uint32_t {
+ DbiSecContribVer60 = 0xeffe0000 + 19970605,
+ DbiSecContribV2 = 0xeffe0000 + 20140516
+};
+
+enum SpecialStream : uint32_t {
+ // Stream 0 contains the copy of previous version of the MSF directory.
+ // We are not currently using it, but technically if we find the main
+ // MSF is corrupted, we could fallback to it.
+ OldMSFDirectory = 0,
+
+ StreamPDB = 1,
+ StreamTPI = 2,
+ StreamDBI = 3,
+ StreamIPI = 4,
+};
+
+enum class DbgHeaderType : uint16_t {
+ FPO,
+ Exception,
+ Fixup,
+ OmapToSrc,
+ OmapFromSrc,
+ SectionHdr,
+ TokenRidMap,
+ Xdata,
+ Pdata,
+ NewFPO,
+ SectionHdrOrig,
+ Max
+};
+
+enum class OMFSegDescFlags : uint16_t {
+ Read = 1 << 0, // Segment is readable.
+ Write = 1 << 1, // Segment is writable.
+ Execute = 1 << 2, // Segment is executable.
+ AddressIs32Bit = 1 << 3, // Descriptor describes a 32-bit linear address.
+ IsSelector = 1 << 8, // Frame represents a selector.
+ IsAbsoluteAddress = 1 << 9, // Frame represents an absolute address.
+ IsGroup = 1 << 10 // If set, descriptor represents a group.
+};
+
+} // end namespace pdb
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H
diff --git a/include/llvm/DebugInfo/PDB/Raw/RawError.h b/include/llvm/DebugInfo/PDB/Raw/RawError.h
new file mode 100644
index 000000000000..b0687cddbf48
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/RawError.h
@@ -0,0 +1,49 @@
+//===- RawError.h - Error extensions for raw PDB implementation -*- 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_RAW_RAWERROR_H
+#define LLVM_DEBUGINFO_PDB_RAW_RAWERROR_H
+
+#include "llvm/Support/Error.h"
+
+#include <string>
+
+namespace llvm {
+namespace pdb {
+enum class raw_error_code {
+ unspecified = 1,
+ feature_unsupported,
+ corrupt_file,
+ insufficient_buffer,
+ no_stream,
+ index_out_of_bounds,
+ invalid_block_address,
+ not_writable,
+ invalid_tpi_hash,
+};
+
+/// Base class for errors originating when parsing raw PDB files
+class RawError : public ErrorInfo<RawError> {
+public:
+ static char ID;
+ RawError(raw_error_code C);
+ RawError(const std::string &Context);
+ RawError(raw_error_code C, const std::string &Context);
+
+ void log(raw_ostream &OS) const override;
+ const std::string &getErrorMessage() const;
+ std::error_code convertToErrorCode() const override;
+
+private:
+ std::string ErrMsg;
+ raw_error_code Code;
+};
+}
+}
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/RawSession.h b/include/llvm/DebugInfo/PDB/Raw/RawSession.h
new file mode 100644
index 000000000000..73d281eab1a7
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/RawSession.h
@@ -0,0 +1,75 @@
+//===- RawSession.h - Native implementation of IPDBSession ------*- 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_RAW_RAWSESSION_H
+#define LLVM_DEBUGINFO_PDB_RAW_RAWSESSION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace pdb {
+class PDBFile;
+
+class RawSession : public IPDBSession {
+public:
+ explicit RawSession(std::unique_ptr<PDBFile> PdbFile);
+ ~RawSession() override;
+
+ static Error createFromPdb(StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
+ static Error createFromExe(StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
+
+ uint64_t getLoadAddress() const override;
+ void setLoadAddress(uint64_t Address) override;
+ std::unique_ptr<PDBSymbolExe> getGlobalScope() const override;
+ std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override;
+
+ std::unique_ptr<PDBSymbol>
+ findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override;
+
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbers(const PDBSymbolCompiland &Compiland,
+ const IPDBSourceFile &File) const override;
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override;
+
+ std::unique_ptr<IPDBEnumSourceFiles>
+ findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<IPDBSourceFile>
+ findOneSourceFile(const PDBSymbolCompiland *Compiland,
+ llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+ findCompilandsForSourceFile(llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<PDBSymbolCompiland>
+ findOneCompilandForSourceFile(llvm::StringRef Pattern,
+ PDB_NameSearchFlags Flags) const override;
+ std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const override;
+ std::unique_ptr<IPDBEnumSourceFiles> getSourceFilesForCompiland(
+ const PDBSymbolCompiland &Compiland) const override;
+ std::unique_ptr<IPDBSourceFile>
+ getSourceFileById(uint32_t FileId) const override;
+
+ std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const override;
+
+ PDBFile &getPDBFile() { return *Pdb; }
+ const PDBFile &getPDBFile() const { return *Pdb; }
+
+private:
+ std::unique_ptr<PDBFile> Pdb;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/RawTypes.h b/include/llvm/DebugInfo/PDB/Raw/RawTypes.h
new file mode 100644
index 000000000000..afcfe9405c0f
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/RawTypes.h
@@ -0,0 +1,86 @@
+//===- RawTypes.h -----------------------------------------------*- 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_RAW_RAWTYPES_H
+#define LLVM_DEBUGINFO_PDB_RAW_RAWTYPES_H
+
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace pdb {
+// This struct is defined as "SO" in langapi/include/pdb.h.
+struct SectionOffset {
+ support::ulittle32_t Off;
+ support::ulittle16_t Isect;
+ char Padding[2];
+};
+
+// This is HRFile.
+struct PSHashRecord {
+ support::ulittle32_t Off; // Offset in the symbol record stream
+ support::ulittle32_t CRef;
+};
+
+// This struct is defined as `SC` in include/dbicommon.h
+struct SectionContrib {
+ support::ulittle16_t ISect;
+ char Padding[2];
+ support::little32_t Off;
+ support::little32_t Size;
+ support::ulittle32_t Characteristics;
+ support::ulittle16_t Imod;
+ char Padding2[2];
+ support::ulittle32_t DataCrc;
+ support::ulittle32_t RelocCrc;
+};
+
+// This struct is defined as `SC2` in include/dbicommon.h
+struct SectionContrib2 {
+ // To guarantee SectionContrib2 is standard layout, we cannot use inheritance.
+ SectionContrib Base;
+ support::ulittle32_t ISectCoff;
+};
+
+// This corresponds to the `OMFSegMap` structure.
+struct SecMapHeader {
+ support::ulittle16_t SecCount; // Number of segment descriptors in table
+ support::ulittle16_t SecCountLog; // Number of logical segment descriptors
+};
+
+// This corresponds to the `OMFSegMapDesc` structure. The definition is not
+// present in the reference implementation, but the layout is derived from
+// code that accesses the fields.
+struct SecMapEntry {
+ support::ulittle16_t Flags; // Descriptor flags. See OMFSegDescFlags
+ support::ulittle16_t Ovl; // Logical overlay number.
+ support::ulittle16_t Group; // Group index into descriptor array.
+ support::ulittle16_t Frame;
+ support::ulittle16_t SecName; // Byte index of the segment or group name
+ // in the sstSegName table, or 0xFFFF.
+ support::ulittle16_t ClassName; // Byte index of the class name in the
+ // sstSegName table, or 0xFFFF.
+ support::ulittle32_t Offset; // Byte offset of the logical segment
+ // within the specified physical segment.
+ // If group is set in flags, offset is the
+ // offset of the group.
+ support::ulittle32_t SecByteLength; // Byte count of the segment or group.
+};
+
+// Used for serialized hash table in TPI stream.
+// In the reference, it is an array of TI and cbOff pair.
+struct TypeIndexOffset {
+ codeview::TypeIndex Type;
+ support::ulittle32_t Offset;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h b/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h
new file mode 100644
index 000000000000..685a23411a3b
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h
@@ -0,0 +1,41 @@
+//===- SymbolStream.cpp - PDB Symbol Stream Access --------------*- 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_RAW_PDBSYMBOLSTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBSYMBOLSTREAM_H
+
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace pdb {
+class PDBFile;
+
+class SymbolStream {
+public:
+ SymbolStream(std::unique_ptr<MappedBlockStream> Stream);
+ ~SymbolStream();
+ Error reload();
+
+ iterator_range<codeview::CVSymbolArray::Iterator>
+ getSymbols(bool *HadError) const;
+
+ Error commit();
+
+private:
+ codeview::CVSymbolArray SymbolRecords;
+ std::unique_ptr<MappedBlockStream> Stream;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/PDB/Raw/TpiStream.h b/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
new file mode 100644
index 000000000000..4f36d70aabed
--- /dev/null
+++ b/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
@@ -0,0 +1,72 @@
+//===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 Access ------*- 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_RAW_PDBTPISTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H
+
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamRef.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace pdb {
+class PDBFile;
+
+class TpiStream {
+ struct HeaderInfo;
+
+public:
+ TpiStream(const PDBFile &File, std::unique_ptr<MappedBlockStream> Stream);
+ ~TpiStream();
+ Error reload();
+
+ PdbRaw_TpiVer getTpiVersion() const;
+
+ uint32_t TypeIndexBegin() const;
+ uint32_t TypeIndexEnd() const;
+ uint32_t NumTypeRecords() const;
+ uint16_t getTypeHashStreamIndex() const;
+ uint16_t getTypeHashStreamAuxIndex() const;
+
+ uint32_t getHashKeySize() const;
+ uint32_t NumHashBuckets() const;
+ codeview::FixedStreamArray<support::ulittle32_t> getHashValues() const;
+ codeview::FixedStreamArray<TypeIndexOffset> getTypeIndexOffsets() const;
+ codeview::FixedStreamArray<TypeIndexOffset> getHashAdjustments() const;
+
+ iterator_range<codeview::CVTypeArray::Iterator> types(bool *HadError) const;
+
+ Error commit();
+
+private:
+ Error verifyHashValues();
+
+ const PDBFile &Pdb;
+ std::unique_ptr<MappedBlockStream> Stream;
+
+ codeview::CVTypeArray TypeRecords;
+
+ std::unique_ptr<MappedBlockStream> HashStream;
+ codeview::FixedStreamArray<support::ulittle32_t> HashValues;
+ codeview::FixedStreamArray<TypeIndexOffset> TypeIndexOffsets;
+ codeview::FixedStreamArray<TypeIndexOffset> HashAdjustments;
+
+ const HeaderInfo *Header;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/Symbolize/DIPrinter.h b/include/llvm/DebugInfo/Symbolize/DIPrinter.h
index 3098199bb4da..49f86eae01cf 100644
--- a/include/llvm/DebugInfo/Symbolize/DIPrinter.h
+++ b/include/llvm/DebugInfo/Symbolize/DIPrinter.h
@@ -31,7 +31,7 @@ class DIPrinter {
int PrintSourceContext;
void print(const DILineInfo &Info, bool Inlined);
- void printContext(std::string FileName, int64_t Line);
+ void printContext(const std::string &FileName, int64_t Line);
public:
DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true,
diff --git a/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h b/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
index ff9cc808875d..e0bec6f6cf85 100644
--- a/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
+++ b/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
@@ -14,8 +14,6 @@
#define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEMODULE_H
#include "llvm/DebugInfo/DIContext.h"
-#include <memory>
-#include <string>
namespace llvm {
namespace object {
diff --git a/include/llvm/DebugInfo/Symbolize/Symbolize.h b/include/llvm/DebugInfo/Symbolize/Symbolize.h
index ec3ae002659c..9253adf7eedd 100644
--- a/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ b/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -19,6 +19,7 @@
#include <map>
#include <memory>
#include <string>
+#include <utility>
namespace llvm {
namespace symbolize {
@@ -40,7 +41,7 @@ public:
bool RelativeAddresses = false, std::string DefaultArch = "")
: PrintFunctions(PrintFunctions), UseSymbolTable(UseSymbolTable),
Demangle(Demangle), RelativeAddresses(RelativeAddresses),
- DefaultArch(DefaultArch) {}
+ DefaultArch(std::move(DefaultArch)) {}
};
LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {}
@@ -48,12 +49,12 @@ public:
flush();
}
- ErrorOr<DILineInfo> symbolizeCode(const std::string &ModuleName,
- uint64_t ModuleOffset);
- ErrorOr<DIInliningInfo> symbolizeInlinedCode(const std::string &ModuleName,
- uint64_t ModuleOffset);
- ErrorOr<DIGlobal> symbolizeData(const std::string &ModuleName,
- uint64_t ModuleOffset);
+ Expected<DILineInfo> symbolizeCode(const std::string &ModuleName,
+ uint64_t ModuleOffset);
+ Expected<DIInliningInfo> symbolizeInlinedCode(const std::string &ModuleName,
+ uint64_t ModuleOffset);
+ Expected<DIGlobal> symbolizeData(const std::string &ModuleName,
+ uint64_t ModuleOffset);
void flush();
static std::string DemangleName(const std::string &Name,
const SymbolizableModule *ModInfo);
@@ -63,8 +64,13 @@ private:
// corresponding debug info. These objects can be the same.
typedef std::pair<ObjectFile*, ObjectFile*> ObjectPair;
- ErrorOr<SymbolizableModule *>
+ /// Returns a SymbolizableModule or an error if loading debug info failed.
+ /// Only one attempt is made to load a module, and errors during loading are
+ /// only reported once. Subsequent calls to get module info for a module that
+ /// failed to load will return nullptr.
+ Expected<SymbolizableModule *>
getOrCreateModuleInfo(const std::string &ModuleName);
+
ObjectFile *lookUpDsymFile(const std::string &Path,
const MachOObjectFile *ExeObj,
const std::string &ArchName);
@@ -73,27 +79,27 @@ private:
const std::string &ArchName);
/// \brief Returns pair of pointers to object and debug object.
- ErrorOr<ObjectPair> getOrCreateObjectPair(const std::string &Path,
+ Expected<ObjectPair> getOrCreateObjectPair(const std::string &Path,
const std::string &ArchName);
/// \brief Return a pointer to object file at specified path, for a specified
/// architecture (e.g. if path refers to a Mach-O universal binary, only one
/// object file from it will be returned).
- ErrorOr<ObjectFile *> getOrCreateObject(const std::string &Path,
+ Expected<ObjectFile *> getOrCreateObject(const std::string &Path,
const std::string &ArchName);
- std::map<std::string, ErrorOr<std::unique_ptr<SymbolizableModule>>> Modules;
+ std::map<std::string, std::unique_ptr<SymbolizableModule>> Modules;
/// \brief Contains cached results of getOrCreateObjectPair().
- std::map<std::pair<std::string, std::string>, ErrorOr<ObjectPair>>
+ std::map<std::pair<std::string, std::string>, ObjectPair>
ObjectPairForPathArch;
/// \brief Contains parsed binary for each path, or parsing error.
- std::map<std::string, ErrorOr<OwningBinary<Binary>>> BinaryForPath;
+ std::map<std::string, OwningBinary<Binary>> BinaryForPath;
/// \brief Parsed object file for path/architecture pair, where "path" refers
/// to Mach-O universal binary.
- std::map<std::pair<std::string, std::string>, ErrorOr<std::unique_ptr<ObjectFile>>>
+ std::map<std::pair<std::string, std::string>, std::unique_ptr<ObjectFile>>
ObjectForUBPathAndArch;
Options Opts;