aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
commit145449b1e420787bb99721a429341fa6be3adfb6 (patch)
tree1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/DebugInfo
parentecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff)
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp9
-rw-r--r--llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp75
-rw-r--r--llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp5
-rw-r--r--llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp33
-rw-r--r--llvm/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp8
-rw-r--r--llvm/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp1
-rw-r--r--llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp2
-rw-r--r--llvm/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp1
-rw-r--r--llvm/lib/DebugInfo/CodeView/DebugSubsection.cpp4
-rw-r--r--llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp1
-rw-r--r--llvm/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp3
-rw-r--r--llvm/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp1
-rw-r--r--llvm/lib/DebugInfo/CodeView/Formatters.cpp4
-rw-r--r--llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp10
-rw-r--r--llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp5
-rw-r--r--llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp11
-rw-r--r--llvm/lib/DebugInfo/CodeView/RecordName.cpp6
-rw-r--r--llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp2
-rw-r--r--llvm/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp5
-rw-r--r--llvm/lib/DebugInfo/CodeView/StringsAndChecksums.cpp1
-rw-r--r--llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp4
-rw-r--r--llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp2
-rw-r--r--llvm/lib/DebugInfo/CodeView/SymbolSerializer.cpp6
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp5
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeHashing.cpp3
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeIndex.cpp1
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp38
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp6
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp5
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp1
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp3
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp127
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp4
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp1
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp15
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp13
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp3
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp14
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp12
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp7
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp648
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp5
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp608
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp119
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp1
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp70
-rw-r--r--llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp29
-rw-r--r--llvm/lib/DebugInfo/GSYM/ExtractRanges.cpp79
-rw-r--r--llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp14
-rw-r--r--llvm/lib/DebugInfo/GSYM/GsymCreator.cpp6
-rw-r--r--llvm/lib/DebugInfo/GSYM/GsymReader.cpp2
-rw-r--r--llvm/lib/DebugInfo/GSYM/InlineInfo.cpp16
-rw-r--r--llvm/lib/DebugInfo/GSYM/LookupResult.cpp3
-rw-r--r--llvm/lib/DebugInfo/GSYM/Range.cpp123
-rw-r--r--llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp1
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp12
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/DbiModuleList.cpp1
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp13
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp1
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/FormatUtil.cpp207
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp9
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/HashTable.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/InputFile.cpp587
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/LinePrinter.cpp340
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp7
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp8
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp5
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp9
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp6
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp10
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp68
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp1
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp5
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp1
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp26
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp9
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp20
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp5
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp5
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp13
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp5
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp1
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp21
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp1
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp7
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/PublicsStream.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp15
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/SymbolStream.cpp5
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp6
-rw-r--r--llvm/lib/DebugInfo/PDB/PDB.cpp1
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBContext.cpp9
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBExtras.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbol.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolBlock.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolCustom.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolLabel.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolThunk.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp10
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp3
-rw-r--r--llvm/lib/DebugInfo/PDB/UDTLayout.cpp3
-rw-r--r--llvm/lib/DebugInfo/Symbolize/DIFetcher.cpp57
-rw-r--r--llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp6
-rw-r--r--llvm/lib/DebugInfo/Symbolize/Markup.cpp202
-rw-r--r--llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp143
-rw-r--r--llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp10
-rw-r--r--llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h103
-rw-r--r--llvm/lib/DebugInfo/Symbolize/Symbolize.cpp316
149 files changed, 3278 insertions, 1340 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp
index 4d8b15530b9e..3ab7f722eaee 100644
--- a/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp
+++ b/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp
@@ -8,18 +8,11 @@
#include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
+#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstdint>
#include <cstring>
diff --git a/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp b/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
index 48b9b0496ffe..2154aa2b8d00 100644
--- a/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
@@ -8,8 +8,12 @@
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -80,3 +84,72 @@ Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
}
return Error::success();
}
+
+Error CVSymbolVisitor::visitSymbolStreamFiltered(const CVSymbolArray &Symbols,
+ const FilterOptions &Filter) {
+ if (!Filter.SymbolOffset)
+ return visitSymbolStream(Symbols);
+ uint32_t SymbolOffset = *Filter.SymbolOffset;
+ uint32_t ParentRecurseDepth = Filter.ParentRecursiveDepth.value_or(0);
+ uint32_t ChildrenRecurseDepth = Filter.ChildRecursiveDepth.value_or(0);
+ if (!Symbols.isOffsetValid(SymbolOffset))
+ return createStringError(inconvertibleErrorCode(), "Invalid symbol offset");
+ CVSymbol Sym = *Symbols.at(SymbolOffset);
+ uint32_t SymEndOffset =
+ symbolOpensScope(Sym.kind()) ? getScopeEndOffset(Sym) : 0;
+
+ std::vector<uint32_t> ParentOffsets;
+ std::vector<uint32_t> ParentEndOffsets;
+ uint32_t ChildrenDepth = 0;
+ for (auto Begin = Symbols.begin(), End = Symbols.end(); Begin != End;
+ ++Begin) {
+ uint32_t BeginOffset = Begin.offset();
+ CVSymbol BeginSym = *Begin;
+ if (BeginOffset < SymbolOffset) {
+ if (symbolOpensScope(Begin->kind())) {
+ uint32_t EndOffset = getScopeEndOffset(BeginSym);
+ if (SymbolOffset < EndOffset) {
+ ParentOffsets.push_back(BeginOffset);
+ ParentEndOffsets.push_back(EndOffset);
+ }
+ }
+ } else if (BeginOffset == SymbolOffset) {
+ // Found symbol at offset. Visit its parent up to ParentRecurseDepth.
+ if (ParentRecurseDepth >= ParentOffsets.size())
+ ParentRecurseDepth = ParentOffsets.size();
+ uint32_t StartIndex = ParentOffsets.size() - ParentRecurseDepth;
+ while (StartIndex < ParentOffsets.size()) {
+ if (!Symbols.isOffsetValid(ParentOffsets[StartIndex]))
+ break;
+ CVSymbol Parent = *Symbols.at(ParentOffsets[StartIndex]);
+ if (auto EC = visitSymbolRecord(Parent, ParentOffsets[StartIndex]))
+ return EC;
+ ++StartIndex;
+ }
+ if (auto EC = visitSymbolRecord(Sym, SymbolOffset))
+ return EC;
+ } else if (BeginOffset <= SymEndOffset) {
+ if (ChildrenRecurseDepth) {
+ // Visit children.
+ if (symbolEndsScope(Begin->kind()))
+ --ChildrenDepth;
+ if (ChildrenDepth < ChildrenRecurseDepth ||
+ BeginOffset == SymEndOffset) {
+ if (auto EC = visitSymbolRecord(BeginSym, BeginOffset))
+ return EC;
+ }
+ if (symbolOpensScope(Begin->kind()))
+ ++ChildrenDepth;
+ }
+ } else {
+ // Visit parents' ends.
+ if (ParentRecurseDepth && BeginOffset == ParentEndOffsets.back()) {
+ if (auto EC = visitSymbolRecord(BeginSym, BeginOffset))
+ return EC;
+ ParentEndOffsets.pop_back();
+ --ParentRecurseDepth;
+ }
+ }
+ }
+ return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
index dd6f75f97a4a..5da300f710d5 100644
--- a/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
@@ -8,11 +8,12 @@
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/TypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamReader.h"
diff --git a/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
index 1af59ff679dd..a66f9af98835 100644
--- a/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
@@ -8,7 +8,9 @@
#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/GUID.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"
@@ -68,10 +70,10 @@ uint32_t CodeViewRecordIO::maxFieldLength() const {
Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset);
for (auto X : makeArrayRef(Limits).drop_front()) {
Optional<uint32_t> ThisMin = X.bytesRemaining(Offset);
- if (ThisMin.hasValue())
- Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin;
+ if (ThisMin)
+ Min = Min ? std::min(*Min, *ThisMin) : *ThisMin;
}
- assert(Min.hasValue() && "Every field must have a maximum length!");
+ assert(Min && "Every field must have a maximum length!");
return *Min;
}
@@ -279,17 +281,24 @@ void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value,
// FIXME: There are no test cases covering this function.
// This may be because we always consider enumerators to be unsigned.
// See FIXME at CodeViewDebug.cpp : CodeViewDebug::lowerTypeEnum.
- if (Value >= std::numeric_limits<int8_t>::min()) {
+ if (Value < LF_NUMERIC && Value >= 0) {
+ emitComment(Comment);
+ Streamer->emitIntValue(Value, 2);
+ incrStreamedLen(2);
+ } else if (Value >= std::numeric_limits<int8_t>::min() &&
+ Value <= std::numeric_limits<int8_t>::max()) {
Streamer->emitIntValue(LF_CHAR, 2);
emitComment(Comment);
Streamer->emitIntValue(Value, 1);
incrStreamedLen(3);
- } else if (Value >= std::numeric_limits<int16_t>::min()) {
+ } else if (Value >= std::numeric_limits<int16_t>::min() &&
+ Value <= std::numeric_limits<int16_t>::max()) {
Streamer->emitIntValue(LF_SHORT, 2);
emitComment(Comment);
Streamer->emitIntValue(Value, 2);
incrStreamedLen(4);
- } else if (Value >= std::numeric_limits<int32_t>::min()) {
+ } else if (Value >= std::numeric_limits<int32_t>::min() &&
+ Value <= std::numeric_limits<int32_t>::max()) {
Streamer->emitIntValue(LF_LONG, 2);
emitComment(Comment);
Streamer->emitIntValue(Value, 4);
@@ -328,17 +337,23 @@ void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value,
}
Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
- if (Value >= std::numeric_limits<int8_t>::min()) {
+ if (Value < LF_NUMERIC && Value >= 0) {
+ if (auto EC = Writer->writeInteger<int16_t>(Value))
+ return EC;
+ } else if (Value >= std::numeric_limits<int8_t>::min() &&
+ Value <= std::numeric_limits<int8_t>::max()) {
if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
return EC;
if (auto EC = Writer->writeInteger<int8_t>(Value))
return EC;
- } else if (Value >= std::numeric_limits<int16_t>::min()) {
+ } else if (Value >= std::numeric_limits<int16_t>::min() &&
+ Value <= std::numeric_limits<int16_t>::max()) {
if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT))
return EC;
if (auto EC = Writer->writeInteger<int16_t>(Value))
return EC;
- } else if (Value >= std::numeric_limits<int32_t>::min()) {
+ } else if (Value >= std::numeric_limits<int32_t>::min() &&
+ Value <= std::numeric_limits<int32_t>::max()) {
if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG))
return EC;
if (auto EC = Writer->writeInteger<int32_t>(Value))
diff --git a/llvm/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp b/llvm/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp
index c7b1c65f2f9a..a3dbb3954d5c 100644
--- a/llvm/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp
+++ b/llvm/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp
@@ -46,10 +46,10 @@ static inline TypeLeafKind getTypeLeafKind(ContinuationRecordKind CK) {
ContinuationRecordBuilder::ContinuationRecordBuilder()
: SegmentWriter(Buffer), Mapping(SegmentWriter) {}
-ContinuationRecordBuilder::~ContinuationRecordBuilder() {}
+ContinuationRecordBuilder::~ContinuationRecordBuilder() = default;
void ContinuationRecordBuilder::begin(ContinuationRecordKind RecordKind) {
- assert(!Kind.hasValue());
+ assert(!Kind);
Kind = RecordKind;
Buffer.clear();
SegmentWriter.setOffset(0);
@@ -76,7 +76,7 @@ void ContinuationRecordBuilder::begin(ContinuationRecordKind RecordKind) {
template <typename RecordType>
void ContinuationRecordBuilder::writeMemberType(RecordType &Record) {
- assert(Kind.hasValue());
+ assert(Kind);
uint32_t OriginalOffset = SegmentWriter.getOffset();
CVMemberRecord CVMR;
@@ -158,7 +158,7 @@ CVType ContinuationRecordBuilder::createSegmentRecord(
RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(Data.data());
Prefix->RecordLen = Data.size() - sizeof(RecordPrefix::RecordLen);
- if (RefersTo.hasValue()) {
+ if (RefersTo) {
auto Continuation = Data.take_back(ContinuationLength);
ContinuationRecord *CR =
reinterpret_cast<ContinuationRecord *>(Continuation.data());
diff --git a/llvm/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp b/llvm/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp
index b23410409f88..b48f57955db1 100644
--- a/llvm/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp
+++ b/llvm/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp
@@ -8,6 +8,7 @@
#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Error.h"
#include <cstdint>
diff --git a/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp b/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
index 9bc69abea102..c083c61d1595 100644
--- a/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
+++ b/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
@@ -8,6 +8,8 @@
#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
using namespace llvm;
using namespace llvm::codeview;
diff --git a/llvm/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp b/llvm/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp
index 48ec7e4ecdd6..665511c592f9 100644
--- a/llvm/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp
+++ b/llvm/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp
@@ -10,6 +10,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Endian.h"
diff --git a/llvm/lib/DebugInfo/CodeView/DebugSubsection.cpp b/llvm/lib/DebugInfo/CodeView/DebugSubsection.cpp
index 3f93463fe6d6..01581181dfe0 100644
--- a/llvm/lib/DebugInfo/CodeView/DebugSubsection.cpp
+++ b/llvm/lib/DebugInfo/CodeView/DebugSubsection.cpp
@@ -10,6 +10,6 @@
using namespace llvm::codeview;
-DebugSubsectionRef::~DebugSubsectionRef() {}
+DebugSubsectionRef::~DebugSubsectionRef() = default;
-DebugSubsection::~DebugSubsection() {}
+DebugSubsection::~DebugSubsection() = default;
diff --git a/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp b/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
index 3c8a30101450..adc6cabd7da1 100644
--- a/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
+++ b/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
@@ -13,7 +13,6 @@
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
-#include <algorithm>
#include <cassert>
#include <cstdint>
diff --git a/llvm/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp b/llvm/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp
index 7968b6a2d757..50f6fb93dec1 100644
--- a/llvm/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp
+++ b/llvm/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp
@@ -8,6 +8,7 @@
#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
@@ -20,7 +21,7 @@
#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/SwapByteOrder.h"
using namespace llvm;
using namespace llvm::codeview;
diff --git a/llvm/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp b/llvm/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp
index c833103663e4..2b20b3e95db6 100644
--- a/llvm/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp
+++ b/llvm/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
+#include "llvm/Support/BinaryStreamWriter.h"
using namespace llvm;
using namespace llvm::codeview;
diff --git a/llvm/lib/DebugInfo/CodeView/Formatters.cpp b/llvm/lib/DebugInfo/CodeView/Formatters.cpp
index f1f51bcb39cc..73a589212227 100644
--- a/llvm/lib/DebugInfo/CodeView/Formatters.cpp
+++ b/llvm/lib/DebugInfo/CodeView/Formatters.cpp
@@ -9,8 +9,10 @@
#include "llvm/DebugInfo/CodeView/Formatters.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/CodeView/GUID.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
#include <cassert>
using namespace llvm;
diff --git a/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
index 7cd9ca7498f5..142af382efba 100644
--- a/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
+++ b/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
@@ -8,18 +8,12 @@
#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/None.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
+#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstdint>
#include <cstring>
diff --git a/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp b/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
index c0fc3e0ef65a..1d49a1ed4712 100644
--- a/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
+++ b/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
@@ -9,11 +9,12 @@
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/RecordName.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
diff --git a/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp
index 13ce3ae82c26..62d228599eae 100644
--- a/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp
+++ b/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp
@@ -8,18 +8,13 @@
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/None.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/TypeHashing.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
+#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstdint>
#include <cstring>
diff --git a/llvm/lib/DebugInfo/CodeView/RecordName.cpp b/llvm/lib/DebugInfo/CodeView/RecordName.cpp
index 1ca899789bef..5fbbc4a5d497 100644
--- a/llvm/lib/DebugInfo/CodeView/RecordName.cpp
+++ b/llvm/lib/DebugInfo/CodeView/RecordName.cpp
@@ -10,9 +10,13 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
+#include "llvm/DebugInfo/CodeView/TypeCollection.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
#include "llvm/Support/FormatVariadic.h"
diff --git a/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp b/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp
index 63ce302a4e09..d76905df8681 100644
--- a/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp
+++ b/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp
@@ -13,9 +13,9 @@
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/BinaryByteStream.h"
using namespace llvm;
diff --git a/llvm/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp b/llvm/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp
index d963e34628db..cf0c877fdbf8 100644
--- a/llvm/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp
@@ -7,7 +7,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/SimpleTypeSerializer.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
#include "llvm/Support/BinaryStreamWriter.h"
@@ -29,7 +30,7 @@ static void addPadding(BinaryStreamWriter &Writer) {
SimpleTypeSerializer::SimpleTypeSerializer() : ScratchBuffer(MaxRecordLength) {}
-SimpleTypeSerializer::~SimpleTypeSerializer() {}
+SimpleTypeSerializer::~SimpleTypeSerializer() = default;
template <typename T>
ArrayRef<uint8_t> SimpleTypeSerializer::serialize(T &Record) {
diff --git a/llvm/lib/DebugInfo/CodeView/StringsAndChecksums.cpp b/llvm/lib/DebugInfo/CodeView/StringsAndChecksums.cpp
index 9e204eec8604..81aa44fb2086 100644
--- a/llvm/lib/DebugInfo/CodeView/StringsAndChecksums.cpp
+++ b/llvm/lib/DebugInfo/CodeView/StringsAndChecksums.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
diff --git a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
index 45b63983beb4..cfb12dbae845 100644
--- a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
-#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
@@ -20,8 +20,6 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/ScopedPrinter.h"
-#include <system_error>
-
using namespace llvm;
using namespace llvm::codeview;
diff --git a/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp b/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp
index 2562c633bb99..d8b350bf26ba 100644
--- a/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp
@@ -8,7 +8,7 @@
#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
using namespace llvm;
diff --git a/llvm/lib/DebugInfo/CodeView/SymbolSerializer.cpp b/llvm/lib/DebugInfo/CodeView/SymbolSerializer.cpp
index de9bb42b1798..5fb8d497b957 100644
--- a/llvm/lib/DebugInfo/CodeView/SymbolSerializer.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SymbolSerializer.cpp
@@ -8,9 +8,9 @@
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstdint>
#include <cstring>
@@ -24,7 +24,7 @@ SymbolSerializer::SymbolSerializer(BumpPtrAllocator &Allocator,
Mapping(Writer, Container) {}
Error SymbolSerializer::visitSymbolBegin(CVSymbol &Record) {
- assert(!CurrentSymbol.hasValue() && "Already in a symbol mapping!");
+ assert(!CurrentSymbol && "Already in a symbol mapping!");
Writer.setOffset(0);
@@ -39,7 +39,7 @@ Error SymbolSerializer::visitSymbolBegin(CVSymbol &Record) {
}
Error SymbolSerializer::visitSymbolEnd(CVSymbol &Record) {
- assert(CurrentSymbol.hasValue() && "Not in a symbol mapping!");
+ assert(CurrentSymbol && "Not in a symbol mapping!");
if (auto EC = Mapping.visitSymbolEnd(Record))
return EC;
diff --git a/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp b/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
index d5fea5ee5e29..5d27c9f29984 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
@@ -8,14 +8,15 @@
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
-#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/Formatters.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/TypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::codeview;
diff --git a/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp b/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
index 2dbc11a84f0b..fc85d8186eaa 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
@@ -76,5 +76,6 @@ GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData,
auto TrailingBytes = RecordData.drop_front(Off);
S.update(TrailingBytes);
- return {S.final().take_back(8)};
+ std::array<uint8_t, 20> Hash = S.final();
+ return {ArrayRef<uint8_t>(Hash).take_back(8)};
}
diff --git a/llvm/lib/DebugInfo/CodeView/TypeIndex.cpp b/llvm/lib/DebugInfo/CodeView/TypeIndex.cpp
index 604d342448d3..3aead9d50041 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeIndex.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeIndex.cpp
@@ -33,6 +33,7 @@ static const SimpleTypeEntry SimpleTypeNames[] = {
{"wchar_t*", SimpleTypeKind::WideCharacter},
{"char16_t*", SimpleTypeKind::Character16},
{"char32_t*", SimpleTypeKind::Character32},
+ {"char8_t*", SimpleTypeKind::Character8},
{"__int8*", SimpleTypeKind::SByte},
{"unsigned __int8*", SimpleTypeKind::Byte},
{"short*", SimpleTypeKind::Int16Short},
diff --git a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
index d272999bdab8..27f63b9edcd0 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
@@ -7,10 +7,28 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/Twine.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MD5.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <vector>
using namespace llvm;
using namespace llvm::codeview;
@@ -210,8 +228,8 @@ static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name,
}
Error TypeRecordMapping::visitTypeBegin(CVType &CVR) {
- assert(!TypeKind.hasValue() && "Already in a type mapping!");
- assert(!MemberKind.hasValue() && "Already in a member mapping!");
+ assert(!TypeKind && "Already in a type mapping!");
+ assert(!MemberKind && "Already in a member mapping!");
// FieldList and MethodList records can be any length because they can be
// split with continuation records. All other record types cannot be
@@ -242,8 +260,8 @@ Error TypeRecordMapping::visitTypeBegin(CVType &CVR, TypeIndex Index) {
}
Error TypeRecordMapping::visitTypeEnd(CVType &Record) {
- assert(TypeKind.hasValue() && "Not in a type mapping!");
- assert(!MemberKind.hasValue() && "Still in a member mapping!");
+ assert(TypeKind && "Not in a type mapping!");
+ assert(!MemberKind && "Still in a member mapping!");
error(IO.endRecord());
@@ -252,8 +270,8 @@ Error TypeRecordMapping::visitTypeEnd(CVType &Record) {
}
Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) {
- assert(TypeKind.hasValue() && "Not in a type mapping!");
- assert(!MemberKind.hasValue() && "Already in a member mapping!");
+ assert(TypeKind && "Not in a type mapping!");
+ assert(!MemberKind && "Already in a member mapping!");
// The largest possible subrecord is one in which there is a record prefix,
// followed by the subrecord, followed by a continuation, and that entire
@@ -278,8 +296,8 @@ Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) {
}
Error TypeRecordMapping::visitMemberEnd(CVMemberRecord &Record) {
- assert(TypeKind.hasValue() && "Not in a type mapping!");
- assert(MemberKind.hasValue() && "Not in a member mapping!");
+ assert(TypeKind && "Not in a type mapping!");
+ assert(MemberKind && "Not in a member mapping!");
if (IO.isReading()) {
if (auto EC = IO.skipPadding())
diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index 587a68142a4a..7ddfb7ab2f8d 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
@@ -487,7 +487,7 @@ Expected<bool> TypeStreamMerger::shouldRemapType(const CVType &Type) {
if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type),
EP))
return joinErrors(std::move(EC), errorCorruptRecord());
- if (PCHSignature.hasValue())
+ if (PCHSignature)
return errorCorruptRecord();
PCHSignature.emplace(EP.getSignature());
return false;
diff --git a/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp b/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp
index e517e8846d69..910a32730e39 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp
@@ -8,9 +8,10 @@
#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/RecordName.h"
-#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
using namespace llvm::codeview;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
index 1be5a752453a..e2ea5910932d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -11,10 +11,10 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include <cstddef>
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index c77d4d4d989c..5727b3bdb05c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -10,7 +10,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DJB.h"
#include "llvm/Support/Errc.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
index 25d2e852a7fe..2d6c145f9237 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
+#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index d68ecd4f8a42..6461f2ac031d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
@@ -7,8 +7,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index ef50ad53650a..c785026f8461 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@@ -15,6 +16,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
@@ -29,7 +31,11 @@
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
+#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
+#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
#include "llvm/MC/MCRegisterInfo.h"
@@ -115,7 +121,7 @@ collectContributionData(DWARFContext::unit_iterator_range Units) {
const Optional<StrOffsetsContributionDescriptor> &R) {
if (L && R)
return L->Base < R->Base;
- return R.hasValue();
+ return R.has_value();
});
// Uniquify contributions, as it is possible that units (specifically
@@ -383,7 +389,7 @@ void DWARFContext::dump(
OS << '\n' << Name << " contents:\n";
if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
for (const auto &U : Units)
- U->getDIEForOffset(DumpOffset.getValue())
+ U->getDIEForOffset(*DumpOffset)
.dump(OS, 0, DumpOpts.noImplicitRecursion());
else
for (const auto &U : Units)
@@ -763,6 +769,10 @@ bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
DWARFVerifier verifier(OS, *this, DumpOpts);
Success &= verifier.handleDebugAbbrev();
+ if (DumpOpts.DumpType & DIDT_DebugCUIndex)
+ Success &= verifier.handleDebugCUIndex();
+ if (DumpOpts.DumpType & DIDT_DebugTUIndex)
+ Success &= verifier.handleDebugTUIndex();
if (DumpOpts.DumpType & DIDT_DebugInfo)
Success &= verifier.handleDebugInfo();
if (DumpOpts.DumpType & DIDT_DebugLine)
@@ -993,6 +1003,22 @@ Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
RecoverableErrorHandler);
}
+void DWARFContext::clearLineTableForUnit(DWARFUnit *U) {
+ if (!Line)
+ return;
+
+ auto UnitDIE = U->getUnitDIE();
+ if (!UnitDIE)
+ return;
+
+ auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
+ if (!Offset)
+ return;
+
+ uint64_t stmtOffset = *Offset + U->getLineTableOffset();
+ Line->clearLineTable(stmtOffset);
+}
+
void DWARFContext::parseNormalUnits() {
if (!NormalUnits.empty())
return;
@@ -1027,7 +1053,25 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
// First, get the offset of the compile unit.
uint64_t CUOffset = getDebugAranges()->findAddress(Address);
// Retrieve the compile unit.
- return getCompileUnitForOffset(CUOffset);
+ if (DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset))
+ return OffsetCU;
+
+ // Global variables are often not found by the above search, for one of two
+ // reasons:
+ // 1. .debug_aranges may not include global variables. On clang, it seems we
+ // put the globals in the aranges, but this isn't true for gcc.
+ // 2. Even if the global variable is in a .debug_arange, global variables
+ // may not be captured in the [start, end) addresses described by the
+ // parent compile unit.
+ //
+ // So, we walk the CU's and their child DI's manually, looking for the
+ // specific global variable.
+ for (std::unique_ptr<DWARFUnit> &CU : compile_units()) {
+ if (DWARFDie Die = CU->getVariableForAddress(Address)) {
+ return static_cast<DWARFCompileUnit *>(CU.get());
+ }
+ }
+ return nullptr;
}
DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
@@ -1097,64 +1141,6 @@ static bool getFunctionNameAndStartLineForAddress(
return FoundResult;
}
-static Optional<uint64_t> getTypeSize(DWARFDie Type, uint64_t PointerSize) {
- if (auto SizeAttr = Type.find(DW_AT_byte_size))
- if (Optional<uint64_t> Size = SizeAttr->getAsUnsignedConstant())
- return Size;
-
- switch (Type.getTag()) {
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- return PointerSize;
- case DW_TAG_ptr_to_member_type: {
- if (DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type))
- if (BaseType.getTag() == DW_TAG_subroutine_type)
- return 2 * PointerSize;
- return PointerSize;
- }
- case DW_TAG_const_type:
- case DW_TAG_immutable_type:
- case DW_TAG_volatile_type:
- case DW_TAG_restrict_type:
- case DW_TAG_typedef: {
- if (DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type))
- return getTypeSize(BaseType, PointerSize);
- break;
- }
- case DW_TAG_array_type: {
- DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type);
- if (!BaseType)
- return Optional<uint64_t>();
- Optional<uint64_t> BaseSize = getTypeSize(BaseType, PointerSize);
- if (!BaseSize)
- return Optional<uint64_t>();
- uint64_t Size = *BaseSize;
- for (DWARFDie Child : Type) {
- if (Child.getTag() != DW_TAG_subrange_type)
- continue;
-
- if (auto ElemCountAttr = Child.find(DW_AT_count))
- if (Optional<uint64_t> ElemCount =
- ElemCountAttr->getAsUnsignedConstant())
- Size *= *ElemCount;
- if (auto UpperBoundAttr = Child.find(DW_AT_upper_bound))
- if (Optional<int64_t> UpperBound =
- UpperBoundAttr->getAsSignedConstant()) {
- int64_t LowerBound = 0;
- if (auto LowerBoundAttr = Child.find(DW_AT_lower_bound))
- LowerBound = LowerBoundAttr->getAsSignedConstant().getValueOr(0);
- Size *= *UpperBound - LowerBound + 1;
- }
- }
- return Size;
- }
- default:
- break;
- }
- return Optional<uint64_t>();
-}
-
static Optional<int64_t>
getExpressionFrameOffset(ArrayRef<uint8_t> Expr,
Optional<unsigned> FrameBaseReg) {
@@ -1215,7 +1201,7 @@ void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
if (Optional<const char *> Name = dwarf::toString(*NameAttr))
Local.Name = *Name;
if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type))
- Local.Size = getTypeSize(Type, getCUAddrSize());
+ Local.Size = Type.getTypeSize(getCUAddrSize());
if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) {
if (const auto *LT = CU->getContext().getLineTableForUnit(CU))
LT->getFileNameByIndex(
@@ -1256,7 +1242,6 @@ DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
DILineInfoSpecifier Spec) {
DILineInfo Result;
-
DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
if (!CU)
return Result;
@@ -1271,6 +1256,22 @@ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
Spec.FLIKind, Result);
}
}
+
+ return Result;
+}
+
+DILineInfo
+DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+ DILineInfo Result;
+ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Result;
+
+ if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {
+ Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);
+ Result.Line = Die.getDeclLine();
+ }
+
return Result;
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index da6f6ad903f4..b18b64382b41 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -7,7 +7,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFObject.h"
+#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+#include "llvm/Support/Errc.h"
using namespace llvm;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
index 5b1c62e6a259..81fac4763ec1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
@@ -9,6 +9,7 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Support/Errc.h"
using namespace llvm;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
index 1a1b8ea0976f..49ee27db6d54 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
@@ -7,10 +7,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
-#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
-#include "llvm/Support/DataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFObject.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -20,15 +22,15 @@ using namespace llvm;
void DWARFDebugAranges::extract(
DWARFDataExtractor DebugArangesData,
- function_ref<void(Error)> RecoverableErrorHandler) {
+ function_ref<void(Error)> RecoverableErrorHandler,
+ function_ref<void(Error)> WarningHandler) {
if (!DebugArangesData.isValidOffset(0))
return;
uint64_t Offset = 0;
DWARFDebugArangeSet Set;
while (DebugArangesData.isValidOffset(Offset)) {
- if (Error E =
- Set.extract(DebugArangesData, &Offset, RecoverableErrorHandler)) {
+ if (Error E = Set.extract(DebugArangesData, &Offset, WarningHandler)) {
RecoverableErrorHandler(std::move(E));
return;
}
@@ -50,7 +52,8 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) {
// Extract aranges from .debug_aranges section.
DWARFDataExtractor ArangesData(CTX->getDWARFObj().getArangesSection(),
CTX->isLittleEndian(), 0);
- extract(ArangesData, CTX->getRecoverableErrorHandler());
+ extract(ArangesData, CTX->getRecoverableErrorHandler(),
+ CTX->getWarningHandler());
// Generate aranges from DIEs: even if .debug_aranges section is present,
// it may describe only a small subset of compilation units, so we need to
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index 92a461dbd941..cf9057c99dbd 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -12,8 +12,9 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Errc.h"
@@ -1100,8 +1101,8 @@ Error DWARFDebugFrame::parse(DWARFDataExtractor Data) {
default:
return createStringError(
errc::invalid_argument,
- "unknown augmentation character in entry at 0x%" PRIx64,
- StartOffset);
+ "unknown augmentation character %c in entry at 0x%" PRIx64,
+ AugmentationString[i], StartOffset);
case 'L':
LSDAPointerEncoding = Data.getU8(&Offset);
break;
@@ -1137,10 +1138,14 @@ Error DWARFDebugFrame::parse(DWARFDataExtractor Data) {
// B-Key is used for signing functions associated with this
// augmentation string
break;
+ // This stack frame contains MTE tagged data, so needs to be
+ // untagged on unwind.
+ case 'G':
+ break;
}
}
- if (AugmentationLength.hasValue()) {
+ if (AugmentationLength) {
if (Offset != EndAugmentationOffset)
return createStringError(errc::invalid_argument,
"parsing augmentation data at 0x%" PRIx64
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
index 385bde51e2e7..7dbeebc2770f 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
@@ -9,10 +9,11 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Errc.h"
#include <cstddef>
#include <cstdint>
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index f36d3f87257a..2e0780e249aa 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -12,12 +12,12 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
@@ -29,6 +29,10 @@
using namespace llvm;
using namespace dwarf;
+namespace llvm {
+class DwarfContext;
+}
+
using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
namespace {
@@ -337,7 +341,7 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
errc::invalid_argument,
"failed to parse file entry because the MD5 hash is invalid");
std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16,
- FileEntry.Checksum.Bytes.begin());
+ FileEntry.Checksum.begin());
break;
default:
break;
@@ -597,6 +601,10 @@ Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
return LT;
}
+void DWARFDebugLine::clearLineTable(uint64_t Offset) {
+ LineTableMap.erase(Offset);
+}
+
static StringRef getOpcodeName(uint8_t Opcode, uint8_t OpcodeBase) {
assert(Opcode != 0);
if (Opcode < OpcodeBase)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index f39c7871d603..b68af4cfafef 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -9,13 +9,13 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
-#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cinttypes>
@@ -24,6 +24,10 @@
using namespace llvm;
using object::SectionedAddress;
+namespace llvm {
+class DWARFObject;
+}
+
namespace {
class DWARFLocationInterpreter {
Optional<object::SectionedAddress> Base;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
index 7a81d7ff064b..80daea64814a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
@@ -7,9 +7,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdint>
@@ -112,7 +115,7 @@ Error DWARFDebugMacro::parseImpl(
if (IsMacro && Data.isValidOffset(Offset)) {
// Keep a mapping from Macro contribution to CUs, this will
// be needed while retrieving macro from DW_MACRO_define_strx form.
- for (const auto &U : Units.getValue())
+ for (const auto &U : *Units)
if (auto CUDIE = U->getUnitDIE())
// Skip units which does not contibutes to macro section.
if (auto MacroOffset = toSectionOffset(CUDIE.find(DW_AT_macros)))
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index ec7889a3728a..96c546250974 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -14,19 +14,20 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
#include <cassert>
#include <cinttypes>
#include <cstdint>
@@ -106,586 +107,10 @@ static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue,
.print(OS, DumpOpts, MRI, U);
}
-static DWARFDie resolveReferencedType(DWARFDie D,
- dwarf::Attribute Attr = DW_AT_type) {
- return D.getAttributeValueAsReferencedDie(Attr).resolveTypeUnitReference();
-}
static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference();
}
-namespace {
-
-// FIXME: We should have pretty printers per language. Currently we print
-// everything as if it was C++ and fall back to the TAG type name.
-struct DWARFTypePrinter {
- raw_ostream &OS;
- bool Word = true;
- bool EndedWithTemplate = false;
-
- DWARFTypePrinter(raw_ostream &OS) : OS(OS) {}
-
- /// Dump the name encoded in the type tag.
- void appendTypeTagName(dwarf::Tag T) {
- StringRef TagStr = TagString(T);
- static constexpr StringRef Prefix = "DW_TAG_";
- static constexpr StringRef Suffix = "_type";
- if (!TagStr.startswith(Prefix) || !TagStr.endswith(Suffix))
- return;
- OS << TagStr.substr(Prefix.size(),
- TagStr.size() - (Prefix.size() + Suffix.size()))
- << " ";
- }
-
- void appendArrayType(const DWARFDie &D) {
- for (const DWARFDie &C : D.children()) {
- if (C.getTag() != DW_TAG_subrange_type)
- continue;
- Optional<uint64_t> LB;
- Optional<uint64_t> Count;
- Optional<uint64_t> UB;
- Optional<unsigned> DefaultLB;
- if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
- LB = L->getAsUnsignedConstant();
- if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
- Count = CountV->getAsUnsignedConstant();
- if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
- UB = UpperV->getAsUnsignedConstant();
- if (Optional<DWARFFormValue> LV =
- D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
- if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
- if ((DefaultLB =
- LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
- if (LB && *LB == *DefaultLB)
- LB = None;
- if (!LB && !Count && !UB)
- OS << "[]";
- else if (!LB && (Count || UB) && DefaultLB)
- OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
- else {
- OS << "[[";
- if (LB)
- OS << *LB;
- else
- OS << '?';
- OS << ", ";
- if (Count)
- if (LB)
- OS << *LB + *Count;
- else
- OS << "? + " << *Count;
- else if (UB)
- OS << *UB + 1;
- else
- OS << '?';
- OS << ")]";
- }
- }
- EndedWithTemplate = false;
- }
-
- DWARFDie skipQualifiers(DWARFDie D) {
- while (D && (D.getTag() == DW_TAG_const_type ||
- D.getTag() == DW_TAG_volatile_type))
- D = resolveReferencedType(D);
- return D;
- }
-
- bool needsParens(DWARFDie D) {
- D = skipQualifiers(D);
- return D && (D.getTag() == DW_TAG_subroutine_type || D.getTag() == DW_TAG_array_type);
- }
-
- void appendPointerLikeTypeBefore(DWARFDie D, DWARFDie Inner, StringRef Ptr) {
- appendQualifiedNameBefore(Inner);
- if (Word)
- OS << ' ';
- if (needsParens(Inner))
- OS << '(';
- OS << Ptr;
- Word = false;
- EndedWithTemplate = false;
- }
-
- DWARFDie
- appendUnqualifiedNameBefore(DWARFDie D,
- std::string *OriginalFullName = nullptr) {
- Word = true;
- if (!D) {
- OS << "void";
- return DWARFDie();
- }
- DWARFDie InnerDIE;
- auto Inner = [&] { return InnerDIE = resolveReferencedType(D); };
- const dwarf::Tag T = D.getTag();
- switch (T) {
- case DW_TAG_pointer_type: {
- appendPointerLikeTypeBefore(D, Inner(), "*");
- break;
- }
- case DW_TAG_subroutine_type: {
- appendQualifiedNameBefore(Inner());
- if (Word) {
- OS << ' ';
- }
- Word = false;
- break;
- }
- case DW_TAG_array_type: {
- appendQualifiedNameBefore(Inner());
- break;
- }
- case DW_TAG_reference_type:
- appendPointerLikeTypeBefore(D, Inner(), "&");
- break;
- case DW_TAG_rvalue_reference_type:
- appendPointerLikeTypeBefore(D, Inner(), "&&");
- break;
- case DW_TAG_ptr_to_member_type: {
- appendQualifiedNameBefore(Inner());
- if (needsParens(InnerDIE))
- OS << '(';
- else if (Word)
- OS << ' ';
- if (DWARFDie Cont = resolveReferencedType(D, DW_AT_containing_type)) {
- appendQualifiedName(Cont);
- OS << "::";
- }
- OS << "*";
- Word = false;
- break;
- }
- case DW_TAG_const_type:
- case DW_TAG_volatile_type:
- appendConstVolatileQualifierBefore(D);
- break;
- case DW_TAG_namespace: {
- if (const char *Name = dwarf::toString(D.find(DW_AT_name), nullptr))
- OS << Name;
- else
- OS << "(anonymous namespace)";
- break;
- }
- case DW_TAG_unspecified_type: {
- StringRef TypeName = D.getShortName();
- if (TypeName == "decltype(nullptr)")
- TypeName = "std::nullptr_t";
- Word = true;
- OS << TypeName;
- EndedWithTemplate = false;
- break;
- }
- /*
- case DW_TAG_structure_type:
- case DW_TAG_class_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_base_type:
- */
- default: {
- const char *NamePtr = dwarf::toString(D.find(DW_AT_name), nullptr);
- if (!NamePtr) {
- appendTypeTagName(D.getTag());
- return DWARFDie();
- }
- Word = true;
- StringRef Name = NamePtr;
- static constexpr StringRef MangledPrefix = "_STN";
- if (Name.startswith(MangledPrefix)) {
- Name = Name.drop_front(MangledPrefix.size());
- auto Separator = Name.find('|');
- assert(Separator != StringRef::npos);
- StringRef BaseName = Name.substr(0, Separator);
- StringRef TemplateArgs = Name.substr(Separator + 1);
- if (OriginalFullName)
- *OriginalFullName = (BaseName + TemplateArgs).str();
- Name = BaseName;
- } else
- EndedWithTemplate = Name.endswith(">");
- OS << Name;
- // This check would be insufficient for operator overloads like
- // "operator>>" - but for now Clang doesn't try to simplify them, so this
- // is OK. Add more nuanced operator overload handling here if/when needed.
- if (Name.endswith(">"))
- break;
- if (!appendTemplateParameters(D))
- break;
-
- if (EndedWithTemplate)
- OS << ' ';
- OS << '>';
- EndedWithTemplate = true;
- Word = true;
- break;
- }
- }
- return InnerDIE;
- }
-
- void appendUnqualifiedNameAfter(DWARFDie D, DWARFDie Inner,
- bool SkipFirstParamIfArtificial = false) {
- if (!D)
- return;
- switch (D.getTag()) {
- case DW_TAG_subroutine_type: {
- appendSubroutineNameAfter(D, Inner, SkipFirstParamIfArtificial, false,
- false);
- break;
- }
- case DW_TAG_array_type: {
- appendArrayType(D);
- break;
- }
- case DW_TAG_const_type:
- case DW_TAG_volatile_type:
- appendConstVolatileQualifierAfter(D);
- break;
- case DW_TAG_ptr_to_member_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_pointer_type: {
- if (needsParens(Inner))
- OS << ')';
- appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner),
- /*SkipFirstParamIfArtificial=*/D.getTag() ==
- DW_TAG_ptr_to_member_type);
- break;
- }
- /*
- case DW_TAG_structure_type:
- case DW_TAG_class_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_base_type:
- case DW_TAG_namespace:
- */
- default:
- break;
- }
- }
-
- void appendQualifiedName(DWARFDie D) {
- if (D)
- appendScopes(D.getParent());
- appendUnqualifiedName(D);
- }
- DWARFDie appendQualifiedNameBefore(DWARFDie D) {
- if (D)
- appendScopes(D.getParent());
- return appendUnqualifiedNameBefore(D);
- }
- bool appendTemplateParameters(DWARFDie D, bool *FirstParameter = nullptr) {
- bool FirstParameterValue = true;
- bool IsTemplate = false;
- if (!FirstParameter)
- FirstParameter = &FirstParameterValue;
- for (const DWARFDie &C : D) {
- auto Sep = [&] {
- if (*FirstParameter)
- OS << '<';
- else
- OS << ", ";
- IsTemplate = true;
- EndedWithTemplate = false;
- *FirstParameter = false;
- };
- if (C.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
- IsTemplate = true;
- appendTemplateParameters(C, FirstParameter);
- }
- if (C.getTag() == dwarf::DW_TAG_template_value_parameter) {
- DWARFDie T = resolveReferencedType(C);
- Sep();
- if (T.getTag() == DW_TAG_enumeration_type) {
- auto V = C.find(DW_AT_const_value);
- bool FoundEnumerator = false;
- for (const DWARFDie &Enumerator : T) {
- auto EV = Enumerator.find(DW_AT_const_value);
- if (V && EV &&
- V->getAsSignedConstant() == EV->getAsSignedConstant()) {
- if (T.find(DW_AT_enum_class)) {
- appendQualifiedName(T);
- OS << "::";
- } else
- appendScopes(T.getParent());
- OS << Enumerator.getShortName();
- FoundEnumerator = true;
- break;
- }
- }
- if (FoundEnumerator)
- continue;
- OS << '(';
- appendQualifiedName(T);
- OS << ')';
- OS << to_string(*V->getAsSignedConstant());
- continue;
- }
- // /Maybe/ we could do pointer type parameters, looking for the
- // symbol in the ELF symbol table to get back to the variable...
- // but probably not worth it.
- if (T.getTag() == DW_TAG_pointer_type)
- continue;
- const char *RawName = dwarf::toString(T.find(DW_AT_name), nullptr);
- assert(RawName);
- StringRef Name = RawName;
- auto V = C.find(DW_AT_const_value);
- bool IsQualifiedChar = false;
- if (Name == "bool") {
- OS << (*V->getAsUnsignedConstant() ? "true" : "false");
- } else if (Name == "short") {
- OS << "(short)";
- OS << to_string(*V->getAsSignedConstant());
- } else if (Name == "unsigned short") {
- OS << "(unsigned short)";
- OS << to_string(*V->getAsSignedConstant());
- } else if (Name == "int")
- OS << to_string(*V->getAsSignedConstant());
- else if (Name == "long") {
- OS << to_string(*V->getAsSignedConstant());
- OS << "L";
- } else if (Name == "long long") {
- OS << to_string(*V->getAsSignedConstant());
- OS << "LL";
- } else if (Name == "unsigned int") {
- OS << to_string(*V->getAsUnsignedConstant());
- OS << "U";
- } else if (Name == "unsigned long") {
- OS << to_string(*V->getAsUnsignedConstant());
- OS << "UL";
- } else if (Name == "unsigned long long") {
- OS << to_string(*V->getAsUnsignedConstant());
- OS << "ULL";
- } else if (Name == "char" ||
- (IsQualifiedChar =
- (Name == "unsigned char" || Name == "signed char"))) {
- // FIXME: check T's DW_AT_type to see if it's signed or not (since
- // char signedness is implementation defined).
- auto Val = *V->getAsSignedConstant();
- // Copied/hacked up from Clang's CharacterLiteral::print - incomplete
- // (doesn't actually support different character types/widths, sign
- // handling's not done, and doesn't correctly test if a character is
- // printable or needs to use a numeric escape sequence instead)
- if (IsQualifiedChar) {
- OS << '(';
- OS << Name;
- OS << ')';
- }
- switch (Val) {
- case '\\':
- OS << "'\\\\'";
- break;
- case '\'':
- OS << "'\\''";
- break;
- case '\a':
- // TODO: K&R: the meaning of '\\a' is different in traditional C
- OS << "'\\a'";
- break;
- case '\b':
- OS << "'\\b'";
- break;
- case '\f':
- OS << "'\\f'";
- break;
- case '\n':
- OS << "'\\n'";
- break;
- case '\r':
- OS << "'\\r'";
- break;
- case '\t':
- OS << "'\\t'";
- break;
- case '\v':
- OS << "'\\v'";
- break;
- default:
- if ((Val & ~0xFFu) == ~0xFFu)
- Val &= 0xFFu;
- if (Val < 127 && Val >= 32) {
- OS << "'";
- OS << (char)Val;
- OS << "'";
- } else if (Val < 256)
- OS << to_string(llvm::format("'\\x%02x'", Val));
- else if (Val <= 0xFFFF)
- OS << to_string(llvm::format("'\\u%04x'", Val));
- else
- OS << to_string(llvm::format("'\\U%08x'", Val));
- }
- }
- continue;
- }
- if (C.getTag() == dwarf::DW_TAG_GNU_template_template_param) {
- const char *RawName =
- dwarf::toString(C.find(DW_AT_GNU_template_name), nullptr);
- assert(RawName);
- StringRef Name = RawName;
- Sep();
- OS << Name;
- continue;
- }
- if (C.getTag() != dwarf::DW_TAG_template_type_parameter)
- continue;
- auto TypeAttr = C.find(DW_AT_type);
- Sep();
- appendQualifiedName(TypeAttr ? resolveReferencedType(C, *TypeAttr)
- : DWARFDie());
- }
- if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue)
- OS << '<';
- return IsTemplate;
- }
- void decomposeConstVolatile(DWARFDie &N, DWARFDie &T, DWARFDie &C,
- DWARFDie &V) {
- (N.getTag() == DW_TAG_const_type ? C : V) = N;
- T = resolveReferencedType(N);
- if (T) {
- auto Tag = T.getTag();
- if (Tag == DW_TAG_const_type) {
- C = T;
- T = resolveReferencedType(T);
- } else if (Tag == DW_TAG_volatile_type) {
- V = T;
- T = resolveReferencedType(T);
- }
- }
- }
- void appendConstVolatileQualifierAfter(DWARFDie N) {
- DWARFDie C;
- DWARFDie V;
- DWARFDie T;
- decomposeConstVolatile(N, T, C, V);
- if (T && T.getTag() == DW_TAG_subroutine_type)
- appendSubroutineNameAfter(T, resolveReferencedType(T), false, C.isValid(),
- V.isValid());
- else
- appendUnqualifiedNameAfter(T, resolveReferencedType(T));
- }
- void appendConstVolatileQualifierBefore(DWARFDie N) {
- DWARFDie C;
- DWARFDie V;
- DWARFDie T;
- decomposeConstVolatile(N, T, C, V);
- bool Subroutine = T && T.getTag() == DW_TAG_subroutine_type;
- DWARFDie A = T;
- while (A && A.getTag() == DW_TAG_array_type)
- A = resolveReferencedType(A);
- bool Leading =
- (!A || (A.getTag() != DW_TAG_pointer_type &&
- A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) &&
- !Subroutine;
- if (Leading) {
- if (C)
- OS << "const ";
- if (V)
- OS << "volatile ";
- }
- appendQualifiedNameBefore(T);
- if (!Leading && !Subroutine) {
- Word = true;
- if (C)
- OS << "const";
- if (V) {
- if (C)
- OS << ' ';
- OS << "volatile";
- }
- }
- }
-
- /// Recursively append the DIE type name when applicable.
- void appendUnqualifiedName(DWARFDie D,
- std::string *OriginalFullName = nullptr) {
- // FIXME: We should have pretty printers per language. Currently we print
- // everything as if it was C++ and fall back to the TAG type name.
- DWARFDie Inner = appendUnqualifiedNameBefore(D, OriginalFullName);
- appendUnqualifiedNameAfter(D, Inner);
- }
-
- void appendSubroutineNameAfter(DWARFDie D, DWARFDie Inner,
- bool SkipFirstParamIfArtificial, bool Const,
- bool Volatile) {
- DWARFDie FirstParamIfArtificial;
- OS << '(';
- EndedWithTemplate = false;
- bool First = true;
- bool RealFirst = true;
- for (DWARFDie P : D) {
- if (P.getTag() != DW_TAG_formal_parameter &&
- P.getTag() != DW_TAG_unspecified_parameters)
- return;
- DWARFDie T = resolveReferencedType(P);
- if (SkipFirstParamIfArtificial && RealFirst && P.find(DW_AT_artificial)) {
- FirstParamIfArtificial = T;
- RealFirst = false;
- continue;
- }
- if (!First) {
- OS << ", ";
- }
- First = false;
- if (P.getTag() == DW_TAG_unspecified_parameters)
- OS << "...";
- else
- appendQualifiedName(T);
- }
- EndedWithTemplate = false;
- OS << ')';
- if (FirstParamIfArtificial) {
- if (DWARFDie P = FirstParamIfArtificial) {
- if (P.getTag() == DW_TAG_pointer_type) {
- DWARFDie C;
- DWARFDie V;
- auto CVStep = [&](DWARFDie CV) {
- if (DWARFDie U = resolveReferencedType(CV)) {
- if (U.getTag() == DW_TAG_const_type)
- return C = U;
- if (U.getTag() == DW_TAG_volatile_type)
- return V = U;
- }
- return DWARFDie();
- };
- if (DWARFDie CV = CVStep(P)) {
- CVStep(CV);
- }
- if (C)
- OS << " const";
- if (V)
- OS << " volatile";
- }
- }
- } else {
- if (Const)
- OS << " const";
- if (Volatile)
- OS << " volatile";
- }
- if (D.find(DW_AT_reference))
- OS << " &";
- if (D.find(DW_AT_rvalue_reference))
- OS << " &&";
- appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner));
- }
- void appendScopes(DWARFDie D) {
- if (D.getTag() == DW_TAG_compile_unit)
- return;
- if (D.getTag() == DW_TAG_type_unit)
- return;
- if (D.getTag() == DW_TAG_skeleton_unit)
- return;
- if (D.getTag() == DW_TAG_subprogram)
- return;
- if (D.getTag() == DW_TAG_lexical_block)
- return;
- D = D.resolveTypeUnitReference();
- if (DWARFDie P = D.getParent())
- appendScopes(P);
- appendUnqualifiedName(D);
- OS << "::";
- }
-};
-} // anonymous namespace
-
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
const DWARFAttribute &AttrValue, unsigned Indent,
DIDumpOptions DumpOpts) {
@@ -713,8 +138,7 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
Color = HighlightColor::String;
if (const auto *LT = U->getContext().getLineTableForUnit(U))
if (LT->getFileNameByIndex(
- FormValue.getAsUnsignedConstant().getValue(),
- U->getCompilationDir(),
+ *FormValue.getAsUnsignedConstant(), U->getCompilationDir(),
DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
File = '"' + File + '"';
Name = File;
@@ -768,7 +192,7 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
Die.getAttributeValueAsReferencedDie(FormValue).getName(
DINameKind::LinkageName))
OS << Space << "\"" << Name << '\"';
- } else if (Attr == DW_AT_type) {
+ } else if (Attr == DW_AT_type || Attr == DW_AT_containing_type) {
DWARFDie D = resolveReferencedType(Die, FormValue);
if (D && !D.isNULL()) {
OS << Space << "\"";
@@ -1061,6 +485,66 @@ void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0);
}
+Optional<uint64_t> DWARFDie::getTypeSize(uint64_t PointerSize) {
+ if (auto SizeAttr = find(DW_AT_byte_size))
+ if (Optional<uint64_t> Size = SizeAttr->getAsUnsignedConstant())
+ return Size;
+
+ switch (getTag()) {
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ return PointerSize;
+ case DW_TAG_ptr_to_member_type: {
+ if (DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type))
+ if (BaseType.getTag() == DW_TAG_subroutine_type)
+ return 2 * PointerSize;
+ return PointerSize;
+ }
+ case DW_TAG_const_type:
+ case DW_TAG_immutable_type:
+ case DW_TAG_volatile_type:
+ case DW_TAG_restrict_type:
+ case DW_TAG_typedef: {
+ if (DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type))
+ return BaseType.getTypeSize(PointerSize);
+ break;
+ }
+ case DW_TAG_array_type: {
+ DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type);
+ if (!BaseType)
+ return None;
+ Optional<uint64_t> BaseSize = BaseType.getTypeSize(PointerSize);
+ if (!BaseSize)
+ return None;
+ uint64_t Size = *BaseSize;
+ for (DWARFDie Child : *this) {
+ if (Child.getTag() != DW_TAG_subrange_type)
+ continue;
+
+ if (auto ElemCountAttr = Child.find(DW_AT_count))
+ if (Optional<uint64_t> ElemCount =
+ ElemCountAttr->getAsUnsignedConstant())
+ Size *= *ElemCount;
+ if (auto UpperBoundAttr = Child.find(DW_AT_upper_bound))
+ if (Optional<int64_t> UpperBound =
+ UpperBoundAttr->getAsSignedConstant()) {
+ int64_t LowerBound = 0;
+ if (auto LowerBoundAttr = Child.find(DW_AT_lower_bound))
+ LowerBound = LowerBoundAttr->getAsSignedConstant().value_or(0);
+ Size *= *UpperBound - LowerBound + 1;
+ }
+ }
+ return Size;
+ }
+ default:
+ if (DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type))
+ return BaseType.getTypeSize(PointerSize);
+ break;
+ }
+ return None;
+}
+
/// Helper to dump a DIE with all of its parents, but no siblings.
static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent,
DIDumpOptions DumpOpts, unsigned Depth = 0) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 86991a3949dd..1fecd5ee6902 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -13,7 +13,10 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include "llvm/DebugInfo/DWARF/DWARFObject.h"
+#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
index ace7000f07b2..3f140d21c53c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
@@ -9,10 +9,10 @@
#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
#include <cassert>
#include <cinttypes>
#include <cstdint>
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp
new file mode 100644
index 000000000000..86cc07b0d0f2
--- /dev/null
+++ b/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp
@@ -0,0 +1,608 @@
+#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Support/ScopedPrinter.h"
+namespace llvm {
+using namespace dwarf;
+void DWARFTypePrinter::appendTypeTagName(dwarf::Tag T) {
+ StringRef TagStr = TagString(T);
+ static constexpr StringRef Prefix = "DW_TAG_";
+ static constexpr StringRef Suffix = "_type";
+ if (!TagStr.startswith(Prefix) || !TagStr.endswith(Suffix))
+ return;
+ OS << TagStr.substr(Prefix.size(),
+ TagStr.size() - (Prefix.size() + Suffix.size()))
+ << " ";
+}
+
+void DWARFTypePrinter::appendArrayType(const DWARFDie &D) {
+ for (const DWARFDie &C : D.children()) {
+ if (C.getTag() != DW_TAG_subrange_type)
+ continue;
+ Optional<uint64_t> LB;
+ Optional<uint64_t> Count;
+ Optional<uint64_t> UB;
+ Optional<unsigned> DefaultLB;
+ if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
+ LB = L->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
+ Count = CountV->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
+ UB = UpperV->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> LV =
+ D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
+ if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
+ if ((DefaultLB =
+ LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
+ if (LB && *LB == *DefaultLB)
+ LB = None;
+ if (!LB && !Count && !UB)
+ OS << "[]";
+ else if (!LB && (Count || UB) && DefaultLB)
+ OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
+ else {
+ OS << "[[";
+ if (LB)
+ OS << *LB;
+ else
+ OS << '?';
+ OS << ", ";
+ if (Count)
+ if (LB)
+ OS << *LB + *Count;
+ else
+ OS << "? + " << *Count;
+ else if (UB)
+ OS << *UB + 1;
+ else
+ OS << '?';
+ OS << ")]";
+ }
+ }
+ EndedWithTemplate = false;
+}
+
+static DWARFDie resolveReferencedType(DWARFDie D,
+ dwarf::Attribute Attr = DW_AT_type) {
+ return D.getAttributeValueAsReferencedDie(Attr).resolveTypeUnitReference();
+}
+static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
+ return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference();
+}
+DWARFDie DWARFTypePrinter::skipQualifiers(DWARFDie D) {
+ while (D && (D.getTag() == DW_TAG_const_type ||
+ D.getTag() == DW_TAG_volatile_type))
+ D = resolveReferencedType(D);
+ return D;
+}
+
+bool DWARFTypePrinter::needsParens(DWARFDie D) {
+ D = skipQualifiers(D);
+ return D && (D.getTag() == DW_TAG_subroutine_type ||
+ D.getTag() == DW_TAG_array_type);
+}
+
+void DWARFTypePrinter::appendPointerLikeTypeBefore(DWARFDie D, DWARFDie Inner,
+ StringRef Ptr) {
+ appendQualifiedNameBefore(Inner);
+ if (Word)
+ OS << ' ';
+ if (needsParens(Inner))
+ OS << '(';
+ OS << Ptr;
+ Word = false;
+ EndedWithTemplate = false;
+}
+
+DWARFDie
+DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D,
+ std::string *OriginalFullName) {
+ Word = true;
+ if (!D) {
+ OS << "void";
+ return DWARFDie();
+ }
+ DWARFDie InnerDIE;
+ auto Inner = [&] { return InnerDIE = resolveReferencedType(D); };
+ const dwarf::Tag T = D.getTag();
+ switch (T) {
+ case DW_TAG_pointer_type: {
+ appendPointerLikeTypeBefore(D, Inner(), "*");
+ break;
+ }
+ case DW_TAG_subroutine_type: {
+ appendQualifiedNameBefore(Inner());
+ if (Word) {
+ OS << ' ';
+ }
+ Word = false;
+ break;
+ }
+ case DW_TAG_array_type: {
+ appendQualifiedNameBefore(Inner());
+ break;
+ }
+ case DW_TAG_reference_type:
+ appendPointerLikeTypeBefore(D, Inner(), "&");
+ break;
+ case DW_TAG_rvalue_reference_type:
+ appendPointerLikeTypeBefore(D, Inner(), "&&");
+ break;
+ case DW_TAG_ptr_to_member_type: {
+ appendQualifiedNameBefore(Inner());
+ if (needsParens(InnerDIE))
+ OS << '(';
+ else if (Word)
+ OS << ' ';
+ if (DWARFDie Cont = resolveReferencedType(D, DW_AT_containing_type)) {
+ appendQualifiedName(Cont);
+ EndedWithTemplate = false;
+ OS << "::";
+ }
+ OS << "*";
+ Word = false;
+ break;
+ }
+ case DW_TAG_const_type:
+ case DW_TAG_volatile_type:
+ appendConstVolatileQualifierBefore(D);
+ break;
+ case DW_TAG_namespace: {
+ if (const char *Name = dwarf::toString(D.find(DW_AT_name), nullptr))
+ OS << Name;
+ else
+ OS << "(anonymous namespace)";
+ break;
+ }
+ case DW_TAG_unspecified_type: {
+ StringRef TypeName = D.getShortName();
+ if (TypeName == "decltype(nullptr)")
+ TypeName = "std::nullptr_t";
+ Word = true;
+ OS << TypeName;
+ EndedWithTemplate = false;
+ break;
+ }
+ /*
+ case DW_TAG_structure_type:
+ case DW_TAG_class_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_base_type:
+ */
+ default: {
+ const char *NamePtr = dwarf::toString(D.find(DW_AT_name), nullptr);
+ if (!NamePtr) {
+ appendTypeTagName(D.getTag());
+ return DWARFDie();
+ }
+ Word = true;
+ StringRef Name = NamePtr;
+ static constexpr StringRef MangledPrefix = "_STN|";
+ if (Name.startswith(MangledPrefix)) {
+ Name = Name.drop_front(MangledPrefix.size());
+ auto Separator = Name.find('|');
+ assert(Separator != StringRef::npos);
+ StringRef BaseName = Name.substr(0, Separator);
+ StringRef TemplateArgs = Name.substr(Separator + 1);
+ if (OriginalFullName)
+ *OriginalFullName = (BaseName + TemplateArgs).str();
+ Name = BaseName;
+ } else
+ EndedWithTemplate = Name.endswith(">");
+ OS << Name;
+ // This check would be insufficient for operator overloads like
+ // "operator>>" - but for now Clang doesn't try to simplify them, so this
+ // is OK. Add more nuanced operator overload handling here if/when needed.
+ if (Name.endswith(">"))
+ break;
+ if (!appendTemplateParameters(D))
+ break;
+
+ if (EndedWithTemplate)
+ OS << ' ';
+ OS << '>';
+ EndedWithTemplate = true;
+ Word = true;
+ break;
+ }
+ }
+ return InnerDIE;
+}
+
+void DWARFTypePrinter::appendUnqualifiedNameAfter(
+ DWARFDie D, DWARFDie Inner, bool SkipFirstParamIfArtificial) {
+ if (!D)
+ return;
+ switch (D.getTag()) {
+ case DW_TAG_subroutine_type: {
+ appendSubroutineNameAfter(D, Inner, SkipFirstParamIfArtificial, false,
+ false);
+ break;
+ }
+ case DW_TAG_array_type: {
+ appendArrayType(D);
+ break;
+ }
+ case DW_TAG_const_type:
+ case DW_TAG_volatile_type:
+ appendConstVolatileQualifierAfter(D);
+ break;
+ case DW_TAG_ptr_to_member_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_pointer_type: {
+ if (needsParens(Inner))
+ OS << ')';
+ appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner),
+ /*SkipFirstParamIfArtificial=*/D.getTag() ==
+ DW_TAG_ptr_to_member_type);
+ break;
+ }
+ /*
+ case DW_TAG_structure_type:
+ case DW_TAG_class_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_base_type:
+ case DW_TAG_namespace:
+ */
+ default:
+ break;
+ }
+}
+
+void DWARFTypePrinter::appendQualifiedName(DWARFDie D) {
+ if (D)
+ appendScopes(D.getParent());
+ appendUnqualifiedName(D);
+}
+DWARFDie DWARFTypePrinter::appendQualifiedNameBefore(DWARFDie D) {
+ if (D)
+ appendScopes(D.getParent());
+ return appendUnqualifiedNameBefore(D);
+}
+bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D,
+ bool *FirstParameter) {
+ bool FirstParameterValue = true;
+ bool IsTemplate = false;
+ if (!FirstParameter)
+ FirstParameter = &FirstParameterValue;
+ for (const DWARFDie &C : D) {
+ auto Sep = [&] {
+ if (*FirstParameter)
+ OS << '<';
+ else
+ OS << ", ";
+ IsTemplate = true;
+ EndedWithTemplate = false;
+ *FirstParameter = false;
+ };
+ if (C.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
+ IsTemplate = true;
+ appendTemplateParameters(C, FirstParameter);
+ }
+ if (C.getTag() == dwarf::DW_TAG_template_value_parameter) {
+ DWARFDie T = resolveReferencedType(C);
+ Sep();
+ if (T.getTag() == DW_TAG_enumeration_type) {
+ OS << '(';
+ appendQualifiedName(T);
+ OS << ')';
+ auto V = C.find(DW_AT_const_value);
+ OS << std::to_string(*V->getAsSignedConstant());
+ continue;
+ }
+ // /Maybe/ we could do pointer type parameters, looking for the
+ // symbol in the ELF symbol table to get back to the variable...
+ // but probably not worth it.
+ if (T.getTag() == DW_TAG_pointer_type)
+ continue;
+ const char *RawName = dwarf::toString(T.find(DW_AT_name), nullptr);
+ assert(RawName);
+ StringRef Name = RawName;
+ auto V = C.find(DW_AT_const_value);
+ bool IsQualifiedChar = false;
+ if (Name == "bool") {
+ OS << (*V->getAsUnsignedConstant() ? "true" : "false");
+ } else if (Name == "short") {
+ OS << "(short)";
+ OS << std::to_string(*V->getAsSignedConstant());
+ } else if (Name == "unsigned short") {
+ OS << "(unsigned short)";
+ OS << std::to_string(*V->getAsSignedConstant());
+ } else if (Name == "int")
+ OS << std::to_string(*V->getAsSignedConstant());
+ else if (Name == "long") {
+ OS << std::to_string(*V->getAsSignedConstant());
+ OS << "L";
+ } else if (Name == "long long") {
+ OS << std::to_string(*V->getAsSignedConstant());
+ OS << "LL";
+ } else if (Name == "unsigned int") {
+ OS << std::to_string(*V->getAsUnsignedConstant());
+ OS << "U";
+ } else if (Name == "unsigned long") {
+ OS << std::to_string(*V->getAsUnsignedConstant());
+ OS << "UL";
+ } else if (Name == "unsigned long long") {
+ OS << std::to_string(*V->getAsUnsignedConstant());
+ OS << "ULL";
+ } else if (Name == "char" ||
+ (IsQualifiedChar =
+ (Name == "unsigned char" || Name == "signed char"))) {
+ // FIXME: check T's DW_AT_type to see if it's signed or not (since
+ // char signedness is implementation defined).
+ auto Val = *V->getAsSignedConstant();
+ // Copied/hacked up from Clang's CharacterLiteral::print - incomplete
+ // (doesn't actually support different character types/widths, sign
+ // handling's not done, and doesn't correctly test if a character is
+ // printable or needs to use a numeric escape sequence instead)
+ if (IsQualifiedChar) {
+ OS << '(';
+ OS << Name;
+ OS << ')';
+ }
+ switch (Val) {
+ case '\\':
+ OS << "'\\\\'";
+ break;
+ case '\'':
+ OS << "'\\''";
+ break;
+ case '\a':
+ // TODO: K&R: the meaning of '\\a' is different in traditional C
+ OS << "'\\a'";
+ break;
+ case '\b':
+ OS << "'\\b'";
+ break;
+ case '\f':
+ OS << "'\\f'";
+ break;
+ case '\n':
+ OS << "'\\n'";
+ break;
+ case '\r':
+ OS << "'\\r'";
+ break;
+ case '\t':
+ OS << "'\\t'";
+ break;
+ case '\v':
+ OS << "'\\v'";
+ break;
+ default:
+ if ((Val & ~0xFFu) == ~0xFFu)
+ Val &= 0xFFu;
+ if (Val < 127 && Val >= 32) {
+ OS << "'";
+ OS << (char)Val;
+ OS << "'";
+ } else if (Val < 256)
+ OS << to_string(llvm::format("'\\x%02x'", Val));
+ else if (Val <= 0xFFFF)
+ OS << to_string(llvm::format("'\\u%04x'", Val));
+ else
+ OS << to_string(llvm::format("'\\U%08x'", Val));
+ }
+ }
+ continue;
+ }
+ if (C.getTag() == dwarf::DW_TAG_GNU_template_template_param) {
+ const char *RawName =
+ dwarf::toString(C.find(DW_AT_GNU_template_name), nullptr);
+ assert(RawName);
+ StringRef Name = RawName;
+ Sep();
+ OS << Name;
+ continue;
+ }
+ if (C.getTag() != dwarf::DW_TAG_template_type_parameter)
+ continue;
+ auto TypeAttr = C.find(DW_AT_type);
+ Sep();
+ appendQualifiedName(TypeAttr ? resolveReferencedType(C, *TypeAttr)
+ : DWARFDie());
+ }
+ if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue) {
+ OS << '<';
+ EndedWithTemplate = false;
+ }
+ return IsTemplate;
+}
+void DWARFTypePrinter::decomposeConstVolatile(DWARFDie &N, DWARFDie &T,
+ DWARFDie &C, DWARFDie &V) {
+ (N.getTag() == DW_TAG_const_type ? C : V) = N;
+ T = resolveReferencedType(N);
+ if (T) {
+ auto Tag = T.getTag();
+ if (Tag == DW_TAG_const_type) {
+ C = T;
+ T = resolveReferencedType(T);
+ } else if (Tag == DW_TAG_volatile_type) {
+ V = T;
+ T = resolveReferencedType(T);
+ }
+ }
+}
+void DWARFTypePrinter::appendConstVolatileQualifierAfter(DWARFDie N) {
+ DWARFDie C;
+ DWARFDie V;
+ DWARFDie T;
+ decomposeConstVolatile(N, T, C, V);
+ if (T && T.getTag() == DW_TAG_subroutine_type)
+ appendSubroutineNameAfter(T, resolveReferencedType(T), false, C.isValid(),
+ V.isValid());
+ else
+ appendUnqualifiedNameAfter(T, resolveReferencedType(T));
+}
+void DWARFTypePrinter::appendConstVolatileQualifierBefore(DWARFDie N) {
+ DWARFDie C;
+ DWARFDie V;
+ DWARFDie T;
+ decomposeConstVolatile(N, T, C, V);
+ bool Subroutine = T && T.getTag() == DW_TAG_subroutine_type;
+ DWARFDie A = T;
+ while (A && A.getTag() == DW_TAG_array_type)
+ A = resolveReferencedType(A);
+ bool Leading =
+ (!A || (A.getTag() != DW_TAG_pointer_type &&
+ A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) &&
+ !Subroutine;
+ if (Leading) {
+ if (C)
+ OS << "const ";
+ if (V)
+ OS << "volatile ";
+ }
+ appendQualifiedNameBefore(T);
+ if (!Leading && !Subroutine) {
+ Word = true;
+ if (C)
+ OS << "const";
+ if (V) {
+ if (C)
+ OS << ' ';
+ OS << "volatile";
+ }
+ }
+}
+void DWARFTypePrinter::appendUnqualifiedName(DWARFDie D,
+ std::string *OriginalFullName) {
+ // FIXME: We should have pretty printers per language. Currently we print
+ // everything as if it was C++ and fall back to the TAG type name.
+ DWARFDie Inner = appendUnqualifiedNameBefore(D, OriginalFullName);
+ appendUnqualifiedNameAfter(D, Inner);
+}
+void DWARFTypePrinter::appendSubroutineNameAfter(
+ DWARFDie D, DWARFDie Inner, bool SkipFirstParamIfArtificial, bool Const,
+ bool Volatile) {
+ DWARFDie FirstParamIfArtificial;
+ OS << '(';
+ EndedWithTemplate = false;
+ bool First = true;
+ bool RealFirst = true;
+ for (DWARFDie P : D) {
+ if (P.getTag() != DW_TAG_formal_parameter &&
+ P.getTag() != DW_TAG_unspecified_parameters)
+ return;
+ DWARFDie T = resolveReferencedType(P);
+ if (SkipFirstParamIfArtificial && RealFirst && P.find(DW_AT_artificial)) {
+ FirstParamIfArtificial = T;
+ RealFirst = false;
+ continue;
+ }
+ if (!First) {
+ OS << ", ";
+ }
+ First = false;
+ if (P.getTag() == DW_TAG_unspecified_parameters)
+ OS << "...";
+ else
+ appendQualifiedName(T);
+ }
+ EndedWithTemplate = false;
+ OS << ')';
+ if (FirstParamIfArtificial) {
+ if (DWARFDie P = FirstParamIfArtificial) {
+ if (P.getTag() == DW_TAG_pointer_type) {
+ auto CVStep = [&](DWARFDie CV) {
+ if (DWARFDie U = resolveReferencedType(CV)) {
+ Const |= U.getTag() == DW_TAG_const_type;
+ Volatile |= U.getTag() == DW_TAG_volatile_type;
+ return U;
+ }
+ return DWARFDie();
+ };
+ if (DWARFDie CV = CVStep(P)) {
+ CVStep(CV);
+ }
+ }
+ }
+ }
+
+ if (auto CC = D.find(DW_AT_calling_convention)) {
+ switch (*CC->getAsUnsignedConstant()) {
+ case CallingConvention::DW_CC_BORLAND_stdcall:
+ OS << " __attribute__((stdcall))";
+ break;
+ case CallingConvention::DW_CC_BORLAND_msfastcall:
+ OS << " __attribute__((fastcall))";
+ break;
+ case CallingConvention::DW_CC_BORLAND_thiscall:
+ OS << " __attribute__((thiscall))";
+ break;
+ case CallingConvention::DW_CC_LLVM_vectorcall:
+ OS << " __attribute__((vectorcall))";
+ break;
+ case CallingConvention::DW_CC_BORLAND_pascal:
+ OS << " __attribute__((pascal))";
+ break;
+ case CallingConvention::DW_CC_LLVM_Win64:
+ OS << " __attribute__((ms_abi))";
+ break;
+ case CallingConvention::DW_CC_LLVM_X86_64SysV:
+ OS << " __attribute__((sysv_abi))";
+ break;
+ case CallingConvention::DW_CC_LLVM_AAPCS:
+ // AArch64VectorCall missing?
+ OS << " __attribute__((pcs(\"aapcs\")))";
+ break;
+ case CallingConvention::DW_CC_LLVM_AAPCS_VFP:
+ OS << " __attribute__((pcs(\"aapcs-vfp\")))";
+ break;
+ case CallingConvention::DW_CC_LLVM_IntelOclBicc:
+ OS << " __attribute__((intel_ocl_bicc))";
+ break;
+ case CallingConvention::DW_CC_LLVM_SpirFunction:
+ case CallingConvention::DW_CC_LLVM_OpenCLKernel:
+ // These aren't available as attributes, but maybe we should still
+ // render them somehow? (Clang doesn't render them, but that's an issue
+ // for template names too - since then the DWARF names of templates
+ // instantiated with function types with these calling conventions won't
+ // have distinct names - so we'd need to fix that too)
+ break;
+ case CallingConvention::DW_CC_LLVM_Swift:
+ // SwiftAsync missing
+ OS << " __attribute__((swiftcall))";
+ break;
+ case CallingConvention::DW_CC_LLVM_PreserveMost:
+ OS << " __attribute__((preserve_most))";
+ break;
+ case CallingConvention::DW_CC_LLVM_PreserveAll:
+ OS << " __attribute__((preserve_all))";
+ break;
+ case CallingConvention::DW_CC_LLVM_X86RegCall:
+ OS << " __attribute__((regcall))";
+ break;
+ }
+ }
+
+ if (Const)
+ OS << " const";
+ if (Volatile)
+ OS << " volatile";
+ if (D.find(DW_AT_reference))
+ OS << " &";
+ if (D.find(DW_AT_rvalue_reference))
+ OS << " &&";
+
+ appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner));
+}
+void DWARFTypePrinter::appendScopes(DWARFDie D) {
+ if (D.getTag() == DW_TAG_compile_unit)
+ return;
+ if (D.getTag() == DW_TAG_type_unit)
+ return;
+ if (D.getTag() == DW_TAG_skeleton_unit)
+ return;
+ if (D.getTag() == DW_TAG_subprogram)
+ return;
+ if (D.getTag() == DW_TAG_lexical_block)
+ return;
+ D = D.resolveTypeUnitReference();
+ if (DWARFDie P = D.getParent())
+ appendScopes(P);
+ appendUnqualifiedName(D);
+ OS << "::";
+}
+} // namespace llvm
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index a301b65dd444..fe16ca06132b 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
@@ -8,9 +8,7 @@
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cinttypes>
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index eed0a60ec75e..74667fcb92bc 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -9,15 +9,23 @@
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
+#include "llvm/DebugInfo/DWARF/DWARFObject.h"
+#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Path.h"
@@ -25,7 +33,6 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
-#include <cstdio>
#include <utility>
#include <vector>
@@ -79,7 +86,14 @@ void DWARFUnitVector::addUnitsImpl(
if (!IndexEntry && IsDWO) {
const DWARFUnitIndex &Index = getDWARFUnitIndex(
Context, Header.isTypeUnit() ? DW_SECT_EXT_TYPES : DW_SECT_INFO);
- IndexEntry = Index.getFromOffset(Header.getOffset());
+ if (Index) {
+ if (Header.isTypeUnit())
+ IndexEntry = Index.getFromHash(Header.getTypeHash());
+ else if (auto DWOId = Header.getDWOId())
+ IndexEntry = Index.getFromHash(*DWOId);
+ }
+ if (!IndexEntry)
+ IndexEntry = Index.getFromOffset(Header.getOffset());
}
if (IndexEntry && !Header.applyIndexEntry(IndexEntry))
return nullptr;
@@ -366,6 +380,9 @@ void DWARFUnit::clear() {
AddrOffsetSectionBase = None;
SU = nullptr;
clearDIEs(false);
+ AddrDieMap.clear();
+ if (DWO)
+ DWO->clear();
DWO.reset();
}
@@ -407,7 +424,7 @@ void DWARFUnit::extractDIEsToVector(
assert((Parents.back() == UINT32_MAX || Parents.back() <= Dies.size()) &&
"Wrong parent index");
- // Extract die. Stop if any error occured.
+ // Extract die. Stop if any error occurred.
if (!DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,
Parents.back()))
break;
@@ -607,7 +624,7 @@ bool DWARFUnit::parseDWO() {
DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
if (getVersion() == 4) {
auto DWORangesBase = UnitDie.getRangesBaseAttribute();
- DWO->setRangesSection(RangeSection, DWORangesBase.getValueOr(0));
+ DWO->setRangesSection(RangeSection, DWORangesBase.value_or(0));
}
return true;
@@ -735,6 +752,100 @@ DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
return R->second.second;
}
+void DWARFUnit::updateVariableDieMap(DWARFDie Die) {
+ for (DWARFDie Child : Die) {
+ if (isType(Child.getTag()))
+ continue;
+ updateVariableDieMap(Child);
+ }
+
+ if (Die.getTag() != DW_TAG_variable)
+ return;
+
+ Expected<DWARFLocationExpressionsVector> Locations =
+ Die.getLocations(DW_AT_location);
+ if (!Locations) {
+ // Missing DW_AT_location is fine here.
+ consumeError(Locations.takeError());
+ return;
+ }
+
+ uint64_t Address = UINT64_MAX;
+
+ for (const DWARFLocationExpression &Location : *Locations) {
+ uint8_t AddressSize = getAddressByteSize();
+ DataExtractor Data(Location.Expr, /*IsLittleEndian=*/true, AddressSize);
+ DWARFExpression Expr(Data, AddressSize);
+ auto It = Expr.begin();
+ if (It == Expr.end())
+ continue;
+
+ // Match exactly the main sequence used to describe global variables:
+ // `DW_OP_addr[x] [+ DW_OP_plus_uconst]`. Currently, this is the sequence
+ // that LLVM produces for DILocalVariables and DIGlobalVariables. If, in
+ // future, the DWARF producer (`DwarfCompileUnit::addLocationAttribute()` is
+ // a good starting point) is extended to use further expressions, this code
+ // needs to be updated.
+ uint64_t LocationAddr;
+ if (It->getCode() == dwarf::DW_OP_addr) {
+ LocationAddr = It->getRawOperand(0);
+ } else if (It->getCode() == dwarf::DW_OP_addrx) {
+ uint64_t DebugAddrOffset = It->getRawOperand(0);
+ if (auto Pointer = getAddrOffsetSectionItem(DebugAddrOffset)) {
+ LocationAddr = Pointer->Address;
+ }
+ } else {
+ continue;
+ }
+
+ // Read the optional 2nd operand, a DW_OP_plus_uconst.
+ if (++It != Expr.end()) {
+ if (It->getCode() != dwarf::DW_OP_plus_uconst)
+ continue;
+
+ LocationAddr += It->getRawOperand(0);
+
+ // Probe for a 3rd operand, if it exists, bail.
+ if (++It != Expr.end())
+ continue;
+ }
+
+ Address = LocationAddr;
+ break;
+ }
+
+ // Get the size of the global variable. If all else fails (i.e. the global has
+ // no type), then we use a size of one to still allow symbolization of the
+ // exact address.
+ uint64_t GVSize = 1;
+ if (DWARFDie BaseType = Die.getAttributeValueAsReferencedDie(DW_AT_type))
+ if (Optional<uint64_t> Size = Die.getTypeSize(getAddressByteSize()))
+ GVSize = *Size;
+
+ if (Address != UINT64_MAX)
+ VariableDieMap[Address] = {Address + GVSize, Die};
+}
+
+DWARFDie DWARFUnit::getVariableForAddress(uint64_t Address) {
+ extractDIEsIfNeeded(false);
+
+ auto RootDie = getUnitDIE();
+
+ auto RootLookup = RootsParsedForVariables.insert(RootDie.getOffset());
+ if (RootLookup.second)
+ updateVariableDieMap(RootDie);
+
+ auto R = VariableDieMap.upper_bound(Address);
+ if (R == VariableDieMap.begin())
+ return DWARFDie();
+
+ // upper_bound's previous item contains Address.
+ --R;
+ if (Address >= R->second.first)
+ return DWARFDie();
+ return R->second.second;
+}
+
void
DWARFUnit::getInlinedChainForAddress(uint64_t Address,
SmallVectorImpl<DWARFDie> &InlinedChain) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
index d27fd08db14e..d161beef2202 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
@@ -9,6 +9,7 @@
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index ca7ac785b550..c704f8f583af 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -6,17 +6,28 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
+#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+#include "llvm/DebugInfo/DWARF/DWARFAttribute.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFObject.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Object/Error.h"
#include "llvm/Support/DJB.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
@@ -28,6 +39,10 @@ using namespace llvm;
using namespace dwarf;
using namespace object;
+namespace llvm {
+class DWARFDebugInfoEntry;
+}
+
Optional<DWARFAddressRange>
DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) {
auto Begin = Ranges.begin();
@@ -381,6 +396,59 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S) {
return NumDebugInfoErrors;
}
+unsigned DWARFVerifier::verifyIndex(StringRef Name,
+ DWARFSectionKind InfoColumnKind,
+ StringRef IndexStr) {
+ if (IndexStr.empty())
+ return 0;
+ OS << "Verifying " << Name << "...\n";
+ DWARFUnitIndex Index(InfoColumnKind);
+ DataExtractor D(IndexStr, DCtx.isLittleEndian(), 0);
+ if (!Index.parse(D))
+ return 1;
+ using MapType = IntervalMap<uint32_t, uint64_t>;
+ MapType::Allocator Alloc;
+ std::vector<std::unique_ptr<MapType>> Sections(Index.getColumnKinds().size());
+ for (const DWARFUnitIndex::Entry &E : Index.getRows()) {
+ uint64_t Sig = E.getSignature();
+ if (!E.getContributions())
+ continue;
+ for (auto E : enumerate(InfoColumnKind == DW_SECT_INFO
+ ? makeArrayRef(E.getContributions(),
+ Index.getColumnKinds().size())
+ : makeArrayRef(E.getContribution(), 1))) {
+ const DWARFUnitIndex::Entry::SectionContribution &SC = E.value();
+ int Col = E.index();
+ if (SC.Length == 0)
+ continue;
+ if (!Sections[Col])
+ Sections[Col] = std::make_unique<MapType>(Alloc);
+ auto &M = *Sections[Col];
+ auto I = M.find(SC.Offset);
+ if (I != M.end() && I.start() < (SC.Offset + SC.Length)) {
+ error() << llvm::formatv(
+ "overlapping index entries for entries {0:x16} "
+ "and {1:x16} for column {2}\n",
+ *I, Sig, toString(Index.getColumnKinds()[Col]));
+ return 1;
+ }
+ M.insert(SC.Offset, SC.Offset + SC.Length - 1, Sig);
+ }
+ }
+
+ return 0;
+}
+
+bool DWARFVerifier::handleDebugCUIndex() {
+ return verifyIndex(".debug_cu_index", DWARFSectionKind::DW_SECT_INFO,
+ DCtx.getDWARFObj().getCUIndexSection()) == 0;
+}
+
+bool DWARFVerifier::handleDebugTUIndex() {
+ return verifyIndex(".debug_tu_index", DWARFSectionKind::DW_SECT_EXT_TYPES,
+ DCtx.getDWARFObj().getTUIndexSection()) == 0;
+}
+
bool DWARFVerifier::handleDebugInfo() {
const DWARFObject &DObj = DCtx.getDWARFObj();
unsigned NumErrors = 0;
diff --git a/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp b/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp
index 6eef6f84ab40..473a69b34ac3 100644
--- a/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp
+++ b/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp
@@ -10,6 +10,7 @@
#include <unordered_set>
#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ThreadPool.h"
@@ -287,12 +288,12 @@ static void convertFunctionLineTable(raw_ostream &Log, CUInfo &CUI,
// linker problems or LTO or other DWARF re-linking so it is worth emitting
// an error, but not worth stopping the creation of the GSYM.
if (!FI.Range.contains(RowAddress)) {
- if (RowAddress < FI.Range.Start) {
+ if (RowAddress < FI.Range.start()) {
Log << "error: DIE has a start address whose LowPC is between the "
"line table Row[" << RowIndex << "] with address "
<< HEX64(RowAddress) << " and the next one.\n";
Die.dump(Log, 0, DIDumpOptions::getForSingleDIE());
- RowAddress = FI.Range.Start;
+ RowAddress = FI.Range.start();
} else {
continue;
}
@@ -403,8 +404,7 @@ void DwarfTransformer::handleDie(raw_ostream &OS, CUInfo &CUI, DWARFDie Die) {
}
FunctionInfo FI;
- FI.setStartAddress(Range.LowPC);
- FI.setEndAddress(Range.HighPC);
+ FI.Range = {Range.LowPC, Range.HighPC};
FI.Name = *NameIndex;
if (CUI.LineTable) {
convertFunctionLineTable(OS, CUI, Die, Gsym, FI);
@@ -427,11 +427,28 @@ void DwarfTransformer::handleDie(raw_ostream &OS, CUInfo &CUI, DWARFDie Die) {
Error DwarfTransformer::convert(uint32_t NumThreads) {
size_t NumBefore = Gsym.getNumFunctionInfos();
+ auto getDie = [&](DWARFUnit &DwarfUnit) -> DWARFDie {
+ DWARFDie ReturnDie = DwarfUnit.getUnitDIE(false);
+ if (llvm::Optional<uint64_t> DWOId = DwarfUnit.getDWOId()) {
+ DWARFUnit *DWOCU = DwarfUnit.getNonSkeletonUnitDIE(false).getDwarfUnit();
+ if (!DWOCU->isDWOUnit()) {
+ std::string DWOName = dwarf::toString(
+ DwarfUnit.getUnitDIE().find(
+ {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}),
+ "");
+ Log << "warning: Unable to retrieve DWO .debug_info section for "
+ << DWOName << "\n";
+ } else {
+ ReturnDie = DWOCU->getUnitDIE(false);
+ }
+ }
+ return ReturnDie;
+ };
if (NumThreads == 1) {
// Parse all DWARF data from this thread, use the same string/file table
// for everything
for (const auto &CU : DICtx.compile_units()) {
- DWARFDie Die = CU->getUnitDIE(false);
+ DWARFDie Die = getDie(*CU);
CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(CU.get()));
handleDie(Log, CUI, Die);
}
@@ -456,7 +473,7 @@ Error DwarfTransformer::convert(uint32_t NumThreads) {
// Now convert all DWARF to GSYM in a thread pool.
std::mutex LogMutex;
for (const auto &CU : DICtx.compile_units()) {
- DWARFDie Die = CU->getUnitDIE(false /*CUDieOnly*/);
+ DWARFDie Die = getDie(*CU);
if (Die) {
CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(CU.get()));
pool.async([this, CUI, &LogMutex, Die]() mutable {
diff --git a/llvm/lib/DebugInfo/GSYM/ExtractRanges.cpp b/llvm/lib/DebugInfo/GSYM/ExtractRanges.cpp
new file mode 100644
index 000000000000..4a42100c86da
--- /dev/null
+++ b/llvm/lib/DebugInfo/GSYM/ExtractRanges.cpp
@@ -0,0 +1,79 @@
+//===- ExtractRanges.cpp ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/ExtractRanges.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/Support/DataExtractor.h"
+#include <algorithm>
+#include <inttypes.h>
+
+namespace llvm {
+namespace gsym {
+
+void encodeRange(const AddressRange &Range, FileWriter &O, uint64_t BaseAddr) {
+ assert(Range.start() >= BaseAddr);
+ O.writeULEB(Range.start() - BaseAddr);
+ O.writeULEB(Range.size());
+}
+
+AddressRange decodeRange(DataExtractor &Data, uint64_t BaseAddr,
+ uint64_t &Offset) {
+ const uint64_t AddrOffset = Data.getULEB128(&Offset);
+ const uint64_t Size = Data.getULEB128(&Offset);
+ const uint64_t StartAddr = BaseAddr + AddrOffset;
+
+ return {StartAddr, StartAddr + Size};
+}
+
+void encodeRanges(const AddressRanges &Ranges, FileWriter &O,
+ uint64_t BaseAddr) {
+ O.writeULEB(Ranges.size());
+ if (Ranges.empty())
+ return;
+ for (auto Range : Ranges)
+ encodeRange(Range, O, BaseAddr);
+}
+
+void decodeRanges(AddressRanges &Ranges, DataExtractor &Data, uint64_t BaseAddr,
+ uint64_t &Offset) {
+ Ranges.clear();
+ uint64_t NumRanges = Data.getULEB128(&Offset);
+ Ranges.reserve(NumRanges);
+ for (uint64_t RangeIdx = 0; RangeIdx < NumRanges; RangeIdx++)
+ Ranges.insert(decodeRange(Data, BaseAddr, Offset));
+}
+
+void skipRange(DataExtractor &Data, uint64_t &Offset) {
+ Data.getULEB128(&Offset);
+ Data.getULEB128(&Offset);
+}
+
+uint64_t skipRanges(DataExtractor &Data, uint64_t &Offset) {
+ uint64_t NumRanges = Data.getULEB128(&Offset);
+ for (uint64_t I = 0; I < NumRanges; ++I)
+ skipRange(Data, Offset);
+ return NumRanges;
+}
+
+} // namespace gsym
+
+raw_ostream &operator<<(raw_ostream &OS, const AddressRange &R) {
+ return OS << '[' << HEX64(R.start()) << " - " << HEX64(R.end()) << ")";
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const AddressRanges &AR) {
+ size_t Size = AR.size();
+ for (size_t I = 0; I < Size; ++I) {
+ if (I)
+ OS << ' ';
+ OS << AR[I];
+ }
+ return OS;
+}
+
+} // namespace llvm
diff --git a/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp b/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
index cef1b9498c5c..4f5d240cdf72 100644
--- a/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
+++ b/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
@@ -36,12 +36,11 @@ raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const FunctionInfo &FI) {
llvm::Expected<FunctionInfo> FunctionInfo::decode(DataExtractor &Data,
uint64_t BaseAddr) {
FunctionInfo FI;
- FI.Range.Start = BaseAddr;
uint64_t Offset = 0;
if (!Data.isValidOffsetForDataOfSize(Offset, 4))
return createStringError(std::errc::io_error,
"0x%8.8" PRIx64 ": missing FunctionInfo Size", Offset);
- FI.Range.End = FI.Range.Start + Data.getU32(&Offset);
+ FI.Range = {BaseAddr, BaseAddr + Data.getU32(&Offset)};
if (!Data.isValidOffsetForDataOfSize(Offset, 4))
return createStringError(std::errc::io_error,
"0x%8.8" PRIx64 ": missing FunctionInfo Name", Offset);
@@ -109,13 +108,13 @@ llvm::Expected<uint64_t> FunctionInfo::encode(FileWriter &O) const {
// Write the name of this function as a uint32_t string table offset.
O.writeU32(Name);
- if (OptLineTable.hasValue()) {
+ if (OptLineTable) {
O.writeU32(InfoType::LineTableInfo);
// Write a uint32_t length as zero for now, we will fix this up after
// writing the LineTable out with the number of bytes that were written.
O.writeU32(0);
const auto StartOffset = O.tell();
- llvm::Error err = OptLineTable->encode(O, Range.Start);
+ llvm::Error err = OptLineTable->encode(O, Range.start());
if (err)
return std::move(err);
const auto Length = O.tell() - StartOffset;
@@ -127,13 +126,13 @@ llvm::Expected<uint64_t> FunctionInfo::encode(FileWriter &O) const {
}
// Write out the inline function info if we have any and if it is valid.
- if (Inline.hasValue()) {
+ if (Inline) {
O.writeU32(InfoType::InlineInfo);
// Write a uint32_t length as zero for now, we will fix this up after
// writing the LineTable out with the number of bytes that were written.
O.writeU32(0);
const auto StartOffset = O.tell();
- llvm::Error err = Inline->encode(O, Range.Start);
+ llvm::Error err = Inline->encode(O, Range.start());
if (err)
return std::move(err);
const auto Length = O.tell() - StartOffset;
@@ -157,9 +156,8 @@ llvm::Expected<LookupResult> FunctionInfo::lookup(DataExtractor &Data,
uint64_t Addr) {
LookupResult LR;
LR.LookupAddr = Addr;
- LR.FuncRange.Start = FuncAddr;
uint64_t Offset = 0;
- LR.FuncRange.End = FuncAddr + Data.getU32(&Offset);
+ LR.FuncRange = {FuncAddr, FuncAddr + Data.getU32(&Offset)};
uint32_t NameOffset = Data.getU32(&Offset);
// The "lookup" functions doesn't report errors as accurately as the "decode"
// function as it is meant to be fast. For more accurage errors we could call
diff --git a/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp b/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
index 1c20a59469dc..8281938770cf 100644
--- a/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
+++ b/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
@@ -271,7 +271,7 @@ llvm::Error GsymCreator::finalize(llvm::raw_ostream &OS) {
}
}
} else if (Prev.Range.size() == 0 &&
- Curr.Range.contains(Prev.Range.Start)) {
+ Curr.Range.contains(Prev.Range.start())) {
if (!Quiet) {
OS << "warning: removing symbol:\n"
<< Prev << "\nKeeping:\n"
@@ -291,8 +291,8 @@ llvm::Error GsymCreator::finalize(llvm::raw_ostream &OS) {
// has no size when doing lookups.
if (!Funcs.empty() && Funcs.back().Range.size() == 0 && ValidTextRanges) {
if (auto Range =
- ValidTextRanges->getRangeThatContains(Funcs.back().Range.Start)) {
- Funcs.back().Range.End = Range->End;
+ ValidTextRanges->getRangeThatContains(Funcs.back().Range.start())) {
+ Funcs.back().Range = {Funcs.back().Range.start(), Range->end()};
}
}
OS << "Pruned " << NumBefore - Funcs.size() << " functions, ended with "
diff --git a/llvm/lib/DebugInfo/GSYM/GsymReader.cpp b/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
index 2ad18bf63d5d..0c585cc8d306 100644
--- a/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
+++ b/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
@@ -48,7 +48,7 @@ llvm::Expected<GsymReader> GsymReader::copyBuffer(StringRef Bytes) {
llvm::Expected<llvm::gsym::GsymReader>
GsymReader::create(std::unique_ptr<MemoryBuffer> &MemBuffer) {
- if (!MemBuffer.get())
+ if (!MemBuffer)
return createStringError(std::errc::invalid_argument,
"invalid memory buffer");
GsymReader GR(std::move(MemBuffer));
diff --git a/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp b/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp
index 21679b1b78aa..f7c4637a8a5b 100644
--- a/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp
+++ b/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp
@@ -75,7 +75,7 @@ llvm::Optional<InlineInfo::InlineArray> InlineInfo::getInlineStack(uint64_t Addr
static bool skip(DataExtractor &Data, uint64_t &Offset, bool SkippedRanges) {
if (!SkippedRanges) {
- if (AddressRanges::skip(Data, Offset) == 0)
+ if (skipRanges(Data, Offset) == 0)
return false;
}
bool HasChildren = Data.getU8(&Offset) != 0;
@@ -109,7 +109,7 @@ static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset,
uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs,
llvm::Error &Err) {
InlineInfo Inline;
- Inline.Ranges.decode(Data, BaseAddr, Offset);
+ decodeRanges(Inline.Ranges, Data, BaseAddr, Offset);
if (Inline.Ranges.empty())
return true;
// Check if the address is contained within the inline information, and if
@@ -128,7 +128,7 @@ static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset,
if (HasChildren) {
// Child address ranges are encoded relative to the first address in the
// parent InlineInfo object.
- const auto ChildBaseAddr = Inline.Ranges[0].Start;
+ const auto ChildBaseAddr = Inline.Ranges[0].start();
bool Done = false;
while (!Done)
Done = lookup(GR, Data, Offset, ChildBaseAddr, Addr, SrcLocs, Err);
@@ -150,7 +150,7 @@ static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset,
SrcLoc.Base = GR.getString(CallFile->Base);
SrcLoc.Line = Inline.CallLine;
SrcLocs.back().Name = GR.getString(Inline.Name);
- SrcLocs.back().Offset = Addr - Inline.Ranges[0].Start;
+ SrcLocs.back().Offset = Addr - Inline.Ranges[0].start();
SrcLocs.push_back(SrcLoc);
}
return true;
@@ -182,7 +182,7 @@ static llvm::Expected<InlineInfo> decode(DataExtractor &Data, uint64_t &Offset,
if (!Data.isValidOffset(Offset))
return createStringError(std::errc::io_error,
"0x%8.8" PRIx64 ": missing InlineInfo address ranges data", Offset);
- Inline.Ranges.decode(Data, BaseAddr, Offset);
+ decodeRanges(Inline.Ranges, Data, BaseAddr, Offset);
if (Inline.Ranges.empty())
return Inline;
if (!Data.isValidOffsetForDataOfSize(Offset, 1))
@@ -205,7 +205,7 @@ static llvm::Expected<InlineInfo> decode(DataExtractor &Data, uint64_t &Offset,
if (HasChildren) {
// Child address ranges are encoded relative to the first address in the
// parent InlineInfo object.
- const auto ChildBaseAddr = Inline.Ranges[0].Start;
+ const auto ChildBaseAddr = Inline.Ranges[0].start();
while (true) {
llvm::Expected<InlineInfo> Child = decode(Data, Offset, ChildBaseAddr);
if (!Child)
@@ -232,7 +232,7 @@ llvm::Error InlineInfo::encode(FileWriter &O, uint64_t BaseAddr) const {
if (!isValid())
return createStringError(std::errc::invalid_argument,
"attempted to encode invalid InlineInfo object");
- Ranges.encode(O, BaseAddr);
+ encodeRanges(Ranges, O, BaseAddr);
bool HasChildren = !Children.empty();
O.writeU8(HasChildren);
O.writeU32(Name);
@@ -242,7 +242,7 @@ llvm::Error InlineInfo::encode(FileWriter &O, uint64_t BaseAddr) const {
// Child address ranges are encoded as relative to the first
// address in the Ranges for this object. This keeps the offsets
// small and allows for efficient encoding using ULEB offsets.
- const uint64_t ChildBaseAddr = Ranges[0].Start;
+ const uint64_t ChildBaseAddr = Ranges[0].start();
for (const auto &Child : Children) {
// Make sure all child address ranges are contained in the parent address
// ranges.
diff --git a/llvm/lib/DebugInfo/GSYM/LookupResult.cpp b/llvm/lib/DebugInfo/GSYM/LookupResult.cpp
index 8a624226b1d3..00a5b1bbfaa5 100644
--- a/llvm/lib/DebugInfo/GSYM/LookupResult.cpp
+++ b/llvm/lib/DebugInfo/GSYM/LookupResult.cpp
@@ -8,6 +8,7 @@
#include "llvm/DebugInfo/GSYM/LookupResult.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/DebugInfo/GSYM/ExtractRanges.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
@@ -42,7 +43,7 @@ raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const SourceLocation &SL) {
OS << " @ ";
if (!SL.Dir.empty()) {
OS << SL.Dir;
- if (SL.Dir.contains('\\') and not SL.Dir.contains('/'))
+ if (SL.Dir.contains('\\') && !SL.Dir.contains('/'))
OS << '\\';
else
OS << '/';
diff --git a/llvm/lib/DebugInfo/GSYM/Range.cpp b/llvm/lib/DebugInfo/GSYM/Range.cpp
deleted file mode 100644
index c1e8eccd0daa..000000000000
--- a/llvm/lib/DebugInfo/GSYM/Range.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-//===- Range.cpp ------------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/GSYM/Range.h"
-#include "llvm/DebugInfo/GSYM/FileWriter.h"
-#include "llvm/Support/DataExtractor.h"
-#include <algorithm>
-#include <inttypes.h>
-
-using namespace llvm;
-using namespace gsym;
-
-
-void AddressRanges::insert(AddressRange Range) {
- if (Range.size() == 0)
- return;
-
- auto It = llvm::upper_bound(Ranges, Range);
- auto It2 = It;
- while (It2 != Ranges.end() && It2->Start < Range.End)
- ++It2;
- if (It != It2) {
- Range.End = std::max(Range.End, It2[-1].End);
- It = Ranges.erase(It, It2);
- }
- if (It != Ranges.begin() && Range.Start < It[-1].End)
- It[-1].End = std::max(It[-1].End, Range.End);
- else
- Ranges.insert(It, Range);
-}
-
-bool AddressRanges::contains(uint64_t Addr) const {
- auto It = std::partition_point(
- Ranges.begin(), Ranges.end(),
- [=](const AddressRange &R) { return R.Start <= Addr; });
- return It != Ranges.begin() && Addr < It[-1].End;
-}
-
-bool AddressRanges::contains(AddressRange Range) const {
- if (Range.size() == 0)
- return false;
- auto It = std::partition_point(
- Ranges.begin(), Ranges.end(),
- [=](const AddressRange &R) { return R.Start <= Range.Start; });
- if (It == Ranges.begin())
- return false;
- return Range.End <= It[-1].End;
-}
-
-Optional<AddressRange>
-AddressRanges::getRangeThatContains(uint64_t Addr) const {
- auto It = std::partition_point(
- Ranges.begin(), Ranges.end(),
- [=](const AddressRange &R) { return R.Start <= Addr; });
- if (It != Ranges.begin() && Addr < It[-1].End)
- return It[-1];
- return llvm::None;
-}
-
-raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRange &R) {
- return OS << '[' << HEX64(R.Start) << " - " << HEX64(R.End) << ")";
-}
-
-raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRanges &AR) {
- size_t Size = AR.size();
- for (size_t I = 0; I < Size; ++I) {
- if (I)
- OS << ' ';
- OS << AR[I];
- }
- return OS;
-}
-
-void AddressRange::encode(FileWriter &O, uint64_t BaseAddr) const {
- assert(Start >= BaseAddr);
- O.writeULEB(Start - BaseAddr);
- O.writeULEB(size());
-}
-
-void AddressRange::decode(DataExtractor &Data, uint64_t BaseAddr,
- uint64_t &Offset) {
- const uint64_t AddrOffset = Data.getULEB128(&Offset);
- const uint64_t Size = Data.getULEB128(&Offset);
- const uint64_t StartAddr = BaseAddr + AddrOffset;
- Start = StartAddr;
- End = StartAddr + Size;
-}
-
-void AddressRanges::encode(FileWriter &O, uint64_t BaseAddr) const {
- O.writeULEB(Ranges.size());
- if (Ranges.empty())
- return;
- for (auto Range : Ranges)
- Range.encode(O, BaseAddr);
-}
-
-void AddressRanges::decode(DataExtractor &Data, uint64_t BaseAddr,
- uint64_t &Offset) {
- clear();
- uint64_t NumRanges = Data.getULEB128(&Offset);
- if (NumRanges == 0)
- return;
- Ranges.resize(NumRanges);
- for (auto &Range : Ranges)
- Range.decode(Data, BaseAddr, Offset);
-}
-
-void AddressRange::skip(DataExtractor &Data, uint64_t &Offset) {
- Data.getULEB128(&Offset);
- Data.getULEB128(&Offset);
-}
-
-uint64_t AddressRanges::skip(DataExtractor &Data, uint64_t &Offset) {
- uint64_t NumRanges = Data.getULEB128(&Offset);
- for (uint64_t I=0; I<NumRanges; ++I)
- AddressRange::skip(Data, Offset);
- return NumRanges;
-}
diff --git a/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp b/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp
index 00fc70ca5a54..94935d63452e 100644
--- a/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp
+++ b/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp
@@ -8,7 +8,6 @@
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Endian.h"
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index b6f11a942a26..c12ac38c2317 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -10,12 +10,10 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
-#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/Support/BinaryStreamWriter.h"
@@ -25,6 +23,12 @@ using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;
+namespace llvm {
+namespace codeview {
+class DebugSubsection;
+}
+} // namespace llvm
+
static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize,
uint32_t C13Size) {
uint32_t Size = sizeof(uint32_t); // Signature
@@ -44,7 +48,7 @@ DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
Layout.Mod = ModIndex;
}
-DbiModuleDescriptorBuilder::~DbiModuleDescriptorBuilder() {}
+DbiModuleDescriptorBuilder::~DbiModuleDescriptorBuilder() = default;
uint16_t DbiModuleDescriptorBuilder::getStreamIndex() const {
return Layout.ModDiStream;
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiModuleList.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiModuleList.cpp
index 5cf014e881cd..009cd113f652 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiModuleList.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiModuleList.cpp
@@ -10,6 +10,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
#include <algorithm>
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp
index 4eb16804171d..1a2267334049 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp
@@ -9,7 +9,6 @@
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
@@ -20,7 +19,6 @@
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
-#include <algorithm>
#include <cstddef>
#include <cstdint>
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index 0584966a98c5..3a719bd07c8a 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -14,7 +14,6 @@
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/BinaryStreamWriter.h"
@@ -30,7 +29,7 @@ DbiStreamBuilder::DbiStreamBuilder(msf::MSFBuilder &Msf)
PdbDllVersion(0), PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86),
Header(nullptr) {}
-DbiStreamBuilder::~DbiStreamBuilder() {}
+DbiStreamBuilder::~DbiStreamBuilder() = default;
void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; }
@@ -72,7 +71,7 @@ void DbiStreamBuilder::setPublicsStreamIndex(uint32_t Index) {
}
void DbiStreamBuilder::addNewFpoData(const codeview::FrameData &FD) {
- if (!NewFpoData.hasValue())
+ if (!NewFpoData)
NewFpoData.emplace(false);
NewFpoData->addFrameData(FD);
@@ -286,7 +285,7 @@ Error DbiStreamBuilder::finalize() {
}
Error DbiStreamBuilder::finalizeMsfLayout() {
- if (NewFpoData.hasValue()) {
+ if (NewFpoData) {
DbgStreams[(int)DbgHeaderType::NewFPO].emplace();
DbgStreams[(int)DbgHeaderType::NewFPO]->Size =
NewFpoData->calculateSerializedSize();
@@ -307,7 +306,7 @@ Error DbiStreamBuilder::finalizeMsfLayout() {
}
for (auto &S : DbgStreams) {
- if (!S.hasValue())
+ if (!S)
continue;
auto ExpectedIndex = Msf.addStream(S->Size);
if (!ExpectedIndex)
@@ -428,14 +427,14 @@ Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
for (auto &Stream : DbgStreams) {
uint16_t StreamNumber = kInvalidStreamIndex;
- if (Stream.hasValue())
+ if (Stream)
StreamNumber = Stream->StreamNumber;
if (auto EC = Writer.writeInteger(StreamNumber))
return EC;
}
for (auto &Stream : DbgStreams) {
- if (!Stream.hasValue())
+ if (!Stream)
continue;
assert(Stream->StreamNumber != kInvalidStreamIndex);
diff --git a/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp b/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp
index 37192ba36a04..32bad9cea7ce 100644
--- a/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp
@@ -8,6 +8,7 @@
#include "llvm/DebugInfo/PDB/Native/EnumTables.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/Support/ScopedPrinter.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/Native/FormatUtil.cpp b/llvm/lib/DebugInfo/PDB/Native/FormatUtil.cpp
new file mode 100644
index 000000000000..a167d45982a9
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/FormatUtil.cpp
@@ -0,0 +1,207 @@
+//===- FormatUtil.cpp ----------------------------------------- *- C++ --*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+std::string llvm::pdb::typesetItemList(ArrayRef<std::string> Opts,
+ uint32_t IndentLevel, uint32_t GroupSize,
+ StringRef Sep) {
+ std::string Result;
+ while (!Opts.empty()) {
+ ArrayRef<std::string> ThisGroup;
+ ThisGroup = Opts.take_front(GroupSize);
+ Opts = Opts.drop_front(ThisGroup.size());
+ Result += join(ThisGroup, Sep);
+ if (!Opts.empty()) {
+ Result += Sep;
+ Result += "\n";
+ Result += std::string(formatv("{0}", fmt_repeat(' ', IndentLevel)));
+ }
+ }
+ return Result;
+}
+
+std::string llvm::pdb::typesetStringList(uint32_t IndentLevel,
+ ArrayRef<StringRef> Strings) {
+ std::string Result = "[";
+ for (const auto &S : Strings) {
+ Result += std::string(formatv("\n{0}{1}", fmt_repeat(' ', IndentLevel), S));
+ }
+ Result += "]";
+ return Result;
+}
+
+std::string llvm::pdb::formatChunkKind(DebugSubsectionKind Kind,
+ bool Friendly) {
+ if (Friendly) {
+ switch (Kind) {
+ RETURN_CASE(DebugSubsectionKind, None, "none");
+ RETURN_CASE(DebugSubsectionKind, Symbols, "symbols");
+ RETURN_CASE(DebugSubsectionKind, Lines, "lines");
+ RETURN_CASE(DebugSubsectionKind, StringTable, "strings");
+ RETURN_CASE(DebugSubsectionKind, FileChecksums, "checksums");
+ RETURN_CASE(DebugSubsectionKind, FrameData, "frames");
+ RETURN_CASE(DebugSubsectionKind, InlineeLines, "inlinee lines");
+ RETURN_CASE(DebugSubsectionKind, CrossScopeImports, "xmi");
+ RETURN_CASE(DebugSubsectionKind, CrossScopeExports, "xme");
+ RETURN_CASE(DebugSubsectionKind, ILLines, "il lines");
+ RETURN_CASE(DebugSubsectionKind, FuncMDTokenMap, "func md token map");
+ RETURN_CASE(DebugSubsectionKind, TypeMDTokenMap, "type md token map");
+ RETURN_CASE(DebugSubsectionKind, MergedAssemblyInput,
+ "merged assembly input");
+ RETURN_CASE(DebugSubsectionKind, CoffSymbolRVA, "coff symbol rva");
+ }
+ } else {
+ switch (Kind) {
+ RETURN_CASE(DebugSubsectionKind, None, "none");
+ RETURN_CASE(DebugSubsectionKind, Symbols, "DEBUG_S_SYMBOLS");
+ RETURN_CASE(DebugSubsectionKind, Lines, "DEBUG_S_LINES");
+ RETURN_CASE(DebugSubsectionKind, StringTable, "DEBUG_S_STRINGTABLE");
+ RETURN_CASE(DebugSubsectionKind, FileChecksums, "DEBUG_S_FILECHKSMS");
+ RETURN_CASE(DebugSubsectionKind, FrameData, "DEBUG_S_FRAMEDATA");
+ RETURN_CASE(DebugSubsectionKind, InlineeLines, "DEBUG_S_INLINEELINES");
+ RETURN_CASE(DebugSubsectionKind, CrossScopeImports,
+ "DEBUG_S_CROSSSCOPEIMPORTS");
+ RETURN_CASE(DebugSubsectionKind, CrossScopeExports,
+ "DEBUG_S_CROSSSCOPEEXPORTS");
+ RETURN_CASE(DebugSubsectionKind, ILLines, "DEBUG_S_IL_LINES");
+ RETURN_CASE(DebugSubsectionKind, FuncMDTokenMap,
+ "DEBUG_S_FUNC_MDTOKEN_MAP");
+ RETURN_CASE(DebugSubsectionKind, TypeMDTokenMap,
+ "DEBUG_S_TYPE_MDTOKEN_MAP");
+ RETURN_CASE(DebugSubsectionKind, MergedAssemblyInput,
+ "DEBUG_S_MERGED_ASSEMBLYINPUT");
+ RETURN_CASE(DebugSubsectionKind, CoffSymbolRVA,
+ "DEBUG_S_COFF_SYMBOL_RVA");
+ }
+ }
+ return formatUnknownEnum(Kind);
+}
+
+std::string llvm::pdb::formatSymbolKind(SymbolKind K) {
+ switch (uint32_t(K)) {
+#define SYMBOL_RECORD(EnumName, value, name) \
+ case EnumName: \
+ return #EnumName;
+#define CV_SYMBOL(EnumName, value) SYMBOL_RECORD(EnumName, value, EnumName)
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
+ }
+ return formatUnknownEnum(K);
+}
+
+std::string llvm::pdb::formatTypeLeafKind(TypeLeafKind K) {
+ switch (K) {
+#define TYPE_RECORD(EnumName, value, name) \
+ case EnumName: \
+ return #EnumName;
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+ default:
+ return formatv("UNKNOWN RECORD ({0:X})",
+ static_cast<std::underlying_type_t<TypeLeafKind>>(K))
+ .str();
+ }
+}
+
+std::string llvm::pdb::formatSegmentOffset(uint16_t Segment, uint32_t Offset) {
+ return std::string(formatv("{0:4}:{1:4}", Segment, Offset));
+}
+
+#define PUSH_CHARACTERISTIC_FLAG(Enum, TheOpt, Value, Style, Descriptive) \
+ PUSH_FLAG(Enum, TheOpt, Value, \
+ ((Style == CharacteristicStyle::HeaderDefinition) ? #TheOpt \
+ : Descriptive))
+
+#define PUSH_MASKED_CHARACTERISTIC_FLAG(Enum, Mask, TheOpt, Value, Style, \
+ Descriptive) \
+ PUSH_MASKED_FLAG(Enum, Mask, TheOpt, Value, \
+ ((Style == CharacteristicStyle::HeaderDefinition) \
+ ? #TheOpt \
+ : Descriptive))
+
+std::string llvm::pdb::formatSectionCharacteristics(uint32_t IndentLevel,
+ uint32_t C,
+ uint32_t FlagsPerLine,
+ StringRef Separator,
+ CharacteristicStyle Style) {
+ using SC = COFF::SectionCharacteristics;
+ std::vector<std::string> Opts;
+ if (C == COFF::SC_Invalid)
+ return "invalid";
+ if (C == 0)
+ return "none";
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_TYPE_NOLOAD, C, Style, "noload");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_TYPE_NO_PAD, C, Style, "no padding");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_CODE, C, Style, "code");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_INITIALIZED_DATA, C, Style,
+ "initialized data");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_UNINITIALIZED_DATA, C, Style,
+ "uninitialized data");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_OTHER, C, Style, "other");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_INFO, C, Style, "info");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_REMOVE, C, Style, "remove");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_COMDAT, C, Style, "comdat");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_GPREL, C, Style, "gp rel");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_PURGEABLE, C, Style, "purgeable");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_16BIT, C, Style, "16-bit");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_LOCKED, C, Style, "locked");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_PRELOAD, C, Style, "preload");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1BYTES, C,
+ Style, "1 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2BYTES, C,
+ Style, "2 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4BYTES, C,
+ Style, "4 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8BYTES, C,
+ Style, "8 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_16BYTES, C,
+ Style, "16 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_32BYTES, C,
+ Style, "32 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_64BYTES, C,
+ Style, "64 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_128BYTES, C,
+ Style, "128 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_256BYTES, C,
+ Style, "256 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_512BYTES, C,
+ Style, "512 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1024BYTES, C,
+ Style, "1024 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2048BYTES, C,
+ Style, "2048 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4096BYTES, C,
+ Style, "4096 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8192BYTES, C,
+ Style, "8192 byte align");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_NRELOC_OVFL, C, Style,
+ "noreloc overflow");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_DISCARDABLE, C, Style,
+ "discardable");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_NOT_CACHED, C, Style,
+ "not cached");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_NOT_PAGED, C, Style, "not paged");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_SHARED, C, Style, "shared");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_EXECUTE, C, Style,
+ "execute permissions");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_READ, C, Style,
+ "read permissions");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_WRITE, C, Style,
+ "write permissions");
+ return typesetItemList(Opts, IndentLevel, FlagsPerLine, Separator);
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
index 9084e689d165..262873c6e6ab 100644
--- a/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
@@ -14,7 +14,7 @@
#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
#include "llvm/DebugInfo/CodeView/RecordName.h"
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
@@ -22,6 +22,7 @@
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/BinaryItemStream.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Parallel.h"
@@ -196,7 +197,7 @@ void GSIStreamBuilder::finalizeGlobalBuckets(uint32_t RecordZeroOffset) {
void GSIHashStreamBuilder::finalizeBuckets(
uint32_t RecordZeroOffset, MutableArrayRef<BulkPublic> Records) {
// Hash every name in parallel.
- parallelForEachN(0, Records.size(), [&](size_t I) {
+ parallelFor(0, Records.size(), [&](size_t I) {
Records[I].setBucketIdx(hashStringV1(Records[I].Name) % IPHR_HASH);
});
@@ -231,7 +232,7 @@ void GSIHashStreamBuilder::finalizeBuckets(
// bucket can properly early-out when it detects the record won't be found.
// The algorithm used here corresponds to the function
// caseInsensitiveComparePchPchCchCch in the reference implementation.
- parallelForEachN(0, IPHR_HASH, [&](size_t I) {
+ parallelFor(0, IPHR_HASH, [&](size_t I) {
auto B = HashRecords.begin() + BucketStarts[I];
auto E = HashRecords.begin() + BucketCursors[I];
if (B == E)
@@ -286,7 +287,7 @@ GSIStreamBuilder::GSIStreamBuilder(msf::MSFBuilder &Msf)
: Msf(Msf), PSH(std::make_unique<GSIHashStreamBuilder>()),
GSH(std::make_unique<GSIHashStreamBuilder>()) {}
-GSIStreamBuilder::~GSIStreamBuilder() {}
+GSIStreamBuilder::~GSIStreamBuilder() = default;
uint32_t GSIStreamBuilder::calculatePublicsHashStreamSize() const {
uint32_t Size = 0;
diff --git a/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp b/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
index f27d60f46815..7217fe38be55 100644
--- a/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
@@ -21,6 +21,7 @@
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/CodeView/RecordName.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
@@ -141,14 +142,12 @@ readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
return joinErrors(std::move(EC),
make_error<RawError>(raw_error_code::corrupt_file,
"Could not read a bitmap."));
- uint32_t NumBuckets1 = 0;
uint32_t CompressedBucketIdx = 0;
for (uint32_t I = 0; I <= IPHR_HASH; ++I) {
uint8_t WordIdx = I / 32;
uint8_t BitIdx = I % 32;
bool IsSet = HashBitmap[WordIdx] & (1U << BitIdx);
if (IsSet) {
- ++NumBuckets1;
BucketMap[I] = CompressedBucketIdx++;
} else {
BucketMap[I] = -1;
diff --git a/llvm/lib/DebugInfo/PDB/Native/HashTable.cpp b/llvm/lib/DebugInfo/PDB/Native/HashTable.cpp
index dfdcdf1f4eaf..030a59821914 100644
--- a/llvm/lib/DebugInfo/PDB/Native/HashTable.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/HashTable.cpp
@@ -7,14 +7,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/HashTable.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
-#include <algorithm>
-#include <cassert>
#include <cstdint>
#include <utility>
diff --git a/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp
index f41bb32d69af..927a0ffee28c 100644
--- a/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp
@@ -7,8 +7,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
@@ -16,7 +14,7 @@
using namespace llvm;
using namespace llvm::codeview;
-using namespace llvm::msf;
+// using namespace llvm::msf;
using namespace llvm::pdb;
InfoStream::InfoStream(std::unique_ptr<BinaryStream> Stream)
diff --git a/llvm/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
index 42daa7cae799..e8f5a451b08e 100644
--- a/llvm/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
@@ -10,11 +10,9 @@
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"
using namespace llvm;
diff --git a/llvm/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp b/llvm/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp
index 3f4101db7b93..f1e8adeb1b21 100644
--- a/llvm/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp
@@ -9,7 +9,7 @@
#include "llvm/DebugInfo/PDB/Native/InjectedSourceStream.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/DebugInfo/PDB/Native/HashTable.h"
#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
diff --git a/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp b/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp
new file mode 100644
index 000000000000..495b25077737
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/InputFile.cpp
@@ -0,0 +1,587 @@
+//===- InputFile.cpp ------------------------------------------ *- C++ --*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/InputFile.h"
+
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
+#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDB.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::object;
+using namespace llvm::pdb;
+
+InputFile::InputFile() = default;
+InputFile::~InputFile() = default;
+
+Expected<ModuleDebugStreamRef>
+llvm::pdb::getModuleDebugStream(PDBFile &File, StringRef &ModuleName,
+ uint32_t Index) {
+ Expected<DbiStream &> DbiOrErr = File.getPDBDbiStream();
+ if (!DbiOrErr)
+ return DbiOrErr.takeError();
+ DbiStream &Dbi = *DbiOrErr;
+ const auto &Modules = Dbi.modules();
+ if (Index >= Modules.getModuleCount())
+ return make_error<RawError>(raw_error_code::index_out_of_bounds,
+ "Invalid module index");
+
+ auto Modi = Modules.getModuleDescriptor(Index);
+
+ ModuleName = Modi.getModuleName();
+
+ uint16_t ModiStream = Modi.getModuleStreamIndex();
+ if (ModiStream == kInvalidStreamIndex)
+ return make_error<RawError>(raw_error_code::no_stream,
+ "Module stream not present");
+
+ auto ModStreamData = File.createIndexedStream(ModiStream);
+
+ ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
+ if (auto EC = ModS.reload())
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid module stream");
+
+ return std::move(ModS);
+}
+
+Expected<ModuleDebugStreamRef> llvm::pdb::getModuleDebugStream(PDBFile &File,
+ uint32_t Index) {
+ Expected<DbiStream &> DbiOrErr = File.getPDBDbiStream();
+ if (!DbiOrErr)
+ return DbiOrErr.takeError();
+ DbiStream &Dbi = *DbiOrErr;
+ const auto &Modules = Dbi.modules();
+ auto Modi = Modules.getModuleDescriptor(Index);
+
+ uint16_t ModiStream = Modi.getModuleStreamIndex();
+ if (ModiStream == kInvalidStreamIndex)
+ return make_error<RawError>(raw_error_code::no_stream,
+ "Module stream not present");
+
+ auto ModStreamData = File.createIndexedStream(ModiStream);
+
+ ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
+ if (Error Err = ModS.reload())
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid module stream");
+
+ return std::move(ModS);
+}
+
+static inline bool isCodeViewDebugSubsection(object::SectionRef Section,
+ StringRef Name,
+ BinaryStreamReader &Reader) {
+ if (Expected<StringRef> NameOrErr = Section.getName()) {
+ if (*NameOrErr != Name)
+ return false;
+ } else {
+ consumeError(NameOrErr.takeError());
+ return false;
+ }
+
+ Expected<StringRef> ContentsOrErr = Section.getContents();
+ if (!ContentsOrErr) {
+ consumeError(ContentsOrErr.takeError());
+ return false;
+ }
+
+ Reader = BinaryStreamReader(*ContentsOrErr, support::little);
+ uint32_t Magic;
+ if (Reader.bytesRemaining() < sizeof(uint32_t))
+ return false;
+ cantFail(Reader.readInteger(Magic));
+ if (Magic != COFF::DEBUG_SECTION_MAGIC)
+ return false;
+ return true;
+}
+
+static inline bool isDebugSSection(object::SectionRef Section,
+ DebugSubsectionArray &Subsections) {
+ BinaryStreamReader Reader;
+ if (!isCodeViewDebugSubsection(Section, ".debug$S", Reader))
+ return false;
+
+ cantFail(Reader.readArray(Subsections, Reader.bytesRemaining()));
+ return true;
+}
+
+static bool isDebugTSection(SectionRef Section, CVTypeArray &Types) {
+ BinaryStreamReader Reader;
+ if (!isCodeViewDebugSubsection(Section, ".debug$T", Reader) &&
+ !isCodeViewDebugSubsection(Section, ".debug$P", Reader))
+ return false;
+ cantFail(Reader.readArray(Types, Reader.bytesRemaining()));
+ return true;
+}
+
+static std::string formatChecksumKind(FileChecksumKind Kind) {
+ switch (Kind) {
+ RETURN_CASE(FileChecksumKind, None, "None");
+ RETURN_CASE(FileChecksumKind, MD5, "MD5");
+ RETURN_CASE(FileChecksumKind, SHA1, "SHA-1");
+ RETURN_CASE(FileChecksumKind, SHA256, "SHA-256");
+ }
+ return formatUnknownEnum(Kind);
+}
+
+template <typename... Args>
+static void formatInternal(LinePrinter &Printer, bool Append, Args &&...args) {
+ if (Append)
+ Printer.format(std::forward<Args>(args)...);
+ else
+ Printer.formatLine(std::forward<Args>(args)...);
+}
+
+SymbolGroup::SymbolGroup(InputFile *File, uint32_t GroupIndex) : File(File) {
+ if (!File)
+ return;
+
+ if (File->isPdb())
+ initializeForPdb(GroupIndex);
+ else {
+ Name = ".debug$S";
+ uint32_t I = 0;
+ for (const auto &S : File->obj().sections()) {
+ DebugSubsectionArray SS;
+ if (!isDebugSSection(S, SS))
+ continue;
+
+ if (!SC.hasChecksums() || !SC.hasStrings())
+ SC.initialize(SS);
+
+ if (I == GroupIndex)
+ Subsections = SS;
+
+ if (SC.hasChecksums() && SC.hasStrings())
+ break;
+ }
+ rebuildChecksumMap();
+ }
+}
+
+StringRef SymbolGroup::name() const { return Name; }
+
+void SymbolGroup::updateDebugS(const codeview::DebugSubsectionArray &SS) {
+ Subsections = SS;
+}
+
+void SymbolGroup::updatePdbModi(uint32_t Modi) { initializeForPdb(Modi); }
+
+void SymbolGroup::initializeForPdb(uint32_t Modi) {
+ assert(File && File->isPdb());
+
+ // PDB always uses the same string table, but each module has its own
+ // checksums. So we only set the strings if they're not already set.
+ if (!SC.hasStrings()) {
+ auto StringTable = File->pdb().getStringTable();
+ if (StringTable)
+ SC.setStrings(StringTable->getStringTable());
+ else
+ consumeError(StringTable.takeError());
+ }
+
+ SC.resetChecksums();
+ auto MDS = getModuleDebugStream(File->pdb(), Name, Modi);
+ if (!MDS) {
+ consumeError(MDS.takeError());
+ return;
+ }
+
+ DebugStream = std::make_shared<ModuleDebugStreamRef>(std::move(*MDS));
+ Subsections = DebugStream->getSubsectionsArray();
+ SC.initialize(Subsections);
+ rebuildChecksumMap();
+}
+
+void SymbolGroup::rebuildChecksumMap() {
+ if (!SC.hasChecksums())
+ return;
+
+ for (const auto &Entry : SC.checksums()) {
+ auto S = SC.strings().getString(Entry.FileNameOffset);
+ if (!S)
+ continue;
+ ChecksumsByFile[*S] = Entry;
+ }
+}
+
+const ModuleDebugStreamRef &SymbolGroup::getPdbModuleStream() const {
+ assert(File && File->isPdb() && DebugStream);
+ return *DebugStream;
+}
+
+Expected<StringRef> SymbolGroup::getNameFromStringTable(uint32_t Offset) const {
+ return SC.strings().getString(Offset);
+}
+
+Expected<StringRef> SymbolGroup::getNameFromChecksums(uint32_t Offset) const {
+ StringRef Name;
+ if (!SC.hasChecksums()) {
+ return std::move(Name);
+ }
+
+ auto Iter = SC.checksums().getArray().at(Offset);
+ if (Iter == SC.checksums().getArray().end()) {
+ return std::move(Name);
+ }
+
+ uint32_t FO = Iter->FileNameOffset;
+ auto ExpectedFile = getNameFromStringTable(FO);
+ if (!ExpectedFile) {
+ return std::move(Name);
+ }
+
+ return *ExpectedFile;
+}
+
+void SymbolGroup::formatFromFileName(LinePrinter &Printer, StringRef File,
+ bool Append) const {
+ auto FC = ChecksumsByFile.find(File);
+ if (FC == ChecksumsByFile.end()) {
+ formatInternal(Printer, Append, "- (no checksum) {0}", File);
+ return;
+ }
+
+ formatInternal(Printer, Append, "- ({0}: {1}) {2}",
+ formatChecksumKind(FC->getValue().Kind),
+ toHex(FC->getValue().Checksum), File);
+}
+
+void SymbolGroup::formatFromChecksumsOffset(LinePrinter &Printer,
+ uint32_t Offset,
+ bool Append) const {
+ if (!SC.hasChecksums()) {
+ formatInternal(Printer, Append, "(unknown file name offset {0})", Offset);
+ return;
+ }
+
+ auto Iter = SC.checksums().getArray().at(Offset);
+ if (Iter == SC.checksums().getArray().end()) {
+ formatInternal(Printer, Append, "(unknown file name offset {0})", Offset);
+ return;
+ }
+
+ uint32_t FO = Iter->FileNameOffset;
+ auto ExpectedFile = getNameFromStringTable(FO);
+ if (!ExpectedFile) {
+ formatInternal(Printer, Append, "(unknown file name offset {0})", Offset);
+ consumeError(ExpectedFile.takeError());
+ return;
+ }
+ if (Iter->Kind == FileChecksumKind::None) {
+ formatInternal(Printer, Append, "{0} (no checksum)", *ExpectedFile);
+ } else {
+ formatInternal(Printer, Append, "{0} ({1}: {2})", *ExpectedFile,
+ formatChecksumKind(Iter->Kind), toHex(Iter->Checksum));
+ }
+}
+
+Expected<InputFile> InputFile::open(StringRef Path, bool AllowUnknownFile) {
+ InputFile IF;
+ if (!llvm::sys::fs::exists(Path))
+ return make_error<StringError>(formatv("File {0} not found", Path),
+ inconvertibleErrorCode());
+
+ file_magic Magic;
+ if (auto EC = identify_magic(Path, Magic))
+ return make_error<StringError>(
+ formatv("Unable to identify file type for file {0}", Path), EC);
+
+ if (Magic == file_magic::coff_object) {
+ Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(Path);
+ if (!BinaryOrErr)
+ return BinaryOrErr.takeError();
+
+ IF.CoffObject = std::move(*BinaryOrErr);
+ IF.PdbOrObj = llvm::cast<COFFObjectFile>(IF.CoffObject.getBinary());
+ return std::move(IF);
+ }
+
+ if (Magic == file_magic::pdb) {
+ std::unique_ptr<IPDBSession> Session;
+ if (auto Err = loadDataForPDB(PDB_ReaderType::Native, Path, Session))
+ return std::move(Err);
+
+ IF.PdbSession.reset(static_cast<NativeSession *>(Session.release()));
+ IF.PdbOrObj = &IF.PdbSession->getPDBFile();
+
+ return std::move(IF);
+ }
+
+ if (!AllowUnknownFile)
+ return make_error<StringError>(
+ formatv("File {0} is not a supported file type", Path),
+ inconvertibleErrorCode());
+
+ auto Result = MemoryBuffer::getFile(Path, /*IsText=*/false,
+ /*RequiresNullTerminator=*/false);
+ if (!Result)
+ return make_error<StringError>(
+ formatv("File {0} could not be opened", Path), Result.getError());
+
+ IF.UnknownFile = std::move(*Result);
+ IF.PdbOrObj = IF.UnknownFile.get();
+ return std::move(IF);
+}
+
+PDBFile &InputFile::pdb() {
+ assert(isPdb());
+ return *PdbOrObj.get<PDBFile *>();
+}
+
+const PDBFile &InputFile::pdb() const {
+ assert(isPdb());
+ return *PdbOrObj.get<PDBFile *>();
+}
+
+object::COFFObjectFile &InputFile::obj() {
+ assert(isObj());
+ return *PdbOrObj.get<object::COFFObjectFile *>();
+}
+
+const object::COFFObjectFile &InputFile::obj() const {
+ assert(isObj());
+ return *PdbOrObj.get<object::COFFObjectFile *>();
+}
+
+MemoryBuffer &InputFile::unknown() {
+ assert(isUnknown());
+ return *PdbOrObj.get<MemoryBuffer *>();
+}
+
+const MemoryBuffer &InputFile::unknown() const {
+ assert(isUnknown());
+ return *PdbOrObj.get<MemoryBuffer *>();
+}
+
+StringRef InputFile::getFilePath() const {
+ if (isPdb())
+ return pdb().getFilePath();
+ if (isObj())
+ return obj().getFileName();
+ assert(isUnknown());
+ return unknown().getBufferIdentifier();
+}
+
+bool InputFile::hasTypes() const {
+ if (isPdb())
+ return pdb().hasPDBTpiStream();
+
+ for (const auto &Section : obj().sections()) {
+ CVTypeArray Types;
+ if (isDebugTSection(Section, Types))
+ return true;
+ }
+ return false;
+}
+
+bool InputFile::hasIds() const {
+ if (isObj())
+ return false;
+ return pdb().hasPDBIpiStream();
+}
+
+bool InputFile::isPdb() const { return PdbOrObj.is<PDBFile *>(); }
+
+bool InputFile::isObj() const {
+ return PdbOrObj.is<object::COFFObjectFile *>();
+}
+
+bool InputFile::isUnknown() const { return PdbOrObj.is<MemoryBuffer *>(); }
+
+codeview::LazyRandomTypeCollection &
+InputFile::getOrCreateTypeCollection(TypeCollectionKind Kind) {
+ if (Types && Kind == kTypes)
+ return *Types;
+ if (Ids && Kind == kIds)
+ return *Ids;
+
+ if (Kind == kIds) {
+ assert(isPdb() && pdb().hasPDBIpiStream());
+ }
+
+ // If the collection was already initialized, we should have just returned it
+ // in step 1.
+ if (isPdb()) {
+ TypeCollectionPtr &Collection = (Kind == kIds) ? Ids : Types;
+ auto &Stream = cantFail((Kind == kIds) ? pdb().getPDBIpiStream()
+ : pdb().getPDBTpiStream());
+
+ auto &Array = Stream.typeArray();
+ uint32_t Count = Stream.getNumTypeRecords();
+ auto Offsets = Stream.getTypeIndexOffsets();
+ Collection =
+ std::make_unique<LazyRandomTypeCollection>(Array, Count, Offsets);
+ return *Collection;
+ }
+
+ assert(isObj());
+ assert(Kind == kTypes);
+ assert(!Types);
+
+ for (const auto &Section : obj().sections()) {
+ CVTypeArray Records;
+ if (!isDebugTSection(Section, Records))
+ continue;
+
+ Types = std::make_unique<LazyRandomTypeCollection>(Records, 100);
+ return *Types;
+ }
+
+ Types = std::make_unique<LazyRandomTypeCollection>(100);
+ return *Types;
+}
+
+codeview::LazyRandomTypeCollection &InputFile::types() {
+ return getOrCreateTypeCollection(kTypes);
+}
+
+codeview::LazyRandomTypeCollection &InputFile::ids() {
+ // Object files have only one type stream that contains both types and ids.
+ // Similarly, some PDBs don't contain an IPI stream, and for those both types
+ // and IDs are in the same stream.
+ if (isObj() || !pdb().hasPDBIpiStream())
+ return types();
+
+ return getOrCreateTypeCollection(kIds);
+}
+
+iterator_range<SymbolGroupIterator> InputFile::symbol_groups() {
+ return make_range<SymbolGroupIterator>(symbol_groups_begin(),
+ symbol_groups_end());
+}
+
+SymbolGroupIterator InputFile::symbol_groups_begin() {
+ return SymbolGroupIterator(*this);
+}
+
+SymbolGroupIterator InputFile::symbol_groups_end() {
+ return SymbolGroupIterator();
+}
+
+SymbolGroupIterator::SymbolGroupIterator() : Value(nullptr) {}
+
+SymbolGroupIterator::SymbolGroupIterator(InputFile &File) : Value(&File) {
+ if (File.isObj()) {
+ SectionIter = File.obj().section_begin();
+ scanToNextDebugS();
+ }
+}
+
+bool SymbolGroupIterator::operator==(const SymbolGroupIterator &R) const {
+ bool E = isEnd();
+ bool RE = R.isEnd();
+ if (E || RE)
+ return E == RE;
+
+ if (Value.File != R.Value.File)
+ return false;
+ return Index == R.Index;
+}
+
+const SymbolGroup &SymbolGroupIterator::operator*() const {
+ assert(!isEnd());
+ return Value;
+}
+SymbolGroup &SymbolGroupIterator::operator*() {
+ assert(!isEnd());
+ return Value;
+}
+
+SymbolGroupIterator &SymbolGroupIterator::operator++() {
+ assert(Value.File && !isEnd());
+ ++Index;
+ if (isEnd())
+ return *this;
+
+ if (Value.File->isPdb()) {
+ Value.updatePdbModi(Index);
+ return *this;
+ }
+
+ scanToNextDebugS();
+ return *this;
+}
+
+void SymbolGroupIterator::scanToNextDebugS() {
+ assert(SectionIter);
+ auto End = Value.File->obj().section_end();
+ auto &Iter = *SectionIter;
+ assert(!isEnd());
+
+ while (++Iter != End) {
+ DebugSubsectionArray SS;
+ SectionRef SR = *Iter;
+ if (!isDebugSSection(SR, SS))
+ continue;
+
+ Value.updateDebugS(SS);
+ return;
+ }
+}
+
+bool SymbolGroupIterator::isEnd() const {
+ if (!Value.File)
+ return true;
+ if (Value.File->isPdb()) {
+ DbiStream &Dbi = cantFail(Value.File->pdb().getPDBDbiStream());
+ uint32_t Count = Dbi.modules().getModuleCount();
+ assert(Index <= Count);
+ return Index == Count;
+ }
+
+ assert(SectionIter);
+ return *SectionIter == Value.File->obj().section_end();
+}
+
+static bool isMyCode(const SymbolGroup &Group) {
+ if (Group.getFile().isObj())
+ return true;
+
+ StringRef Name = Group.name();
+ if (Name.startswith("Import:"))
+ return false;
+ if (Name.endswith_insensitive(".dll"))
+ return false;
+ if (Name.equals_insensitive("* linker *"))
+ return false;
+ if (Name.startswith_insensitive("f:\\binaries\\Intermediate\\vctools"))
+ return false;
+ if (Name.startswith_insensitive("f:\\dd\\vctools\\crt"))
+ return false;
+ return true;
+}
+
+bool llvm::pdb::shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group,
+ const FilterOptions &Filters) {
+ if (Filters.JustMyCode && !isMyCode(Group))
+ return false;
+
+ // If the arg was not specified on the command line, always dump all modules.
+ if (!Filters.DumpModi)
+ return true;
+
+ // Otherwise, only dump if this is the same module specified.
+ return (Filters.DumpModi == Idx);
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/LinePrinter.cpp b/llvm/lib/DebugInfo/PDB/Native/LinePrinter.cpp
new file mode 100644
index 000000000000..c12fedc23833
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/LinePrinter.cpp
@@ -0,0 +1,340 @@
+//===- LinePrinter.cpp ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/InputFile.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/UDTLayout.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Regex.h"
+
+#include <algorithm>
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+namespace {
+bool IsItemExcluded(llvm::StringRef Item,
+ std::list<llvm::Regex> &IncludeFilters,
+ std::list<llvm::Regex> &ExcludeFilters) {
+ if (Item.empty())
+ return false;
+
+ auto match_pred = [Item](llvm::Regex &R) { return R.match(Item); };
+
+ // Include takes priority over exclude. If the user specified include
+ // filters, and none of them include this item, them item is gone.
+ if (!IncludeFilters.empty() && !any_of(IncludeFilters, match_pred))
+ return true;
+
+ if (any_of(ExcludeFilters, match_pred))
+ return true;
+
+ return false;
+}
+} // namespace
+
+using namespace llvm;
+
+LinePrinter::LinePrinter(int Indent, bool UseColor, llvm::raw_ostream &Stream,
+ const FilterOptions &Filters)
+ : OS(Stream), IndentSpaces(Indent), CurrentIndent(0), UseColor(UseColor),
+ Filters(Filters) {
+ SetFilters(ExcludeTypeFilters, Filters.ExcludeTypes.begin(),
+ Filters.ExcludeTypes.end());
+ SetFilters(ExcludeSymbolFilters, Filters.ExcludeSymbols.begin(),
+ Filters.ExcludeSymbols.end());
+ SetFilters(ExcludeCompilandFilters, Filters.ExcludeCompilands.begin(),
+ Filters.ExcludeCompilands.end());
+
+ SetFilters(IncludeTypeFilters, Filters.IncludeTypes.begin(),
+ Filters.IncludeTypes.end());
+ SetFilters(IncludeSymbolFilters, Filters.IncludeSymbols.begin(),
+ Filters.IncludeSymbols.end());
+ SetFilters(IncludeCompilandFilters, Filters.IncludeCompilands.begin(),
+ Filters.IncludeCompilands.end());
+}
+
+void LinePrinter::Indent(uint32_t Amount) {
+ if (Amount == 0)
+ Amount = IndentSpaces;
+ CurrentIndent += Amount;
+}
+
+void LinePrinter::Unindent(uint32_t Amount) {
+ if (Amount == 0)
+ Amount = IndentSpaces;
+ CurrentIndent = std::max<int>(0, CurrentIndent - Amount);
+}
+
+void LinePrinter::NewLine() {
+ OS << "\n";
+ OS.indent(CurrentIndent);
+}
+
+void LinePrinter::print(const Twine &T) { OS << T; }
+
+void LinePrinter::printLine(const Twine &T) {
+ NewLine();
+ OS << T;
+}
+
+bool LinePrinter::IsClassExcluded(const ClassLayout &Class) {
+ if (IsTypeExcluded(Class.getName(), Class.getSize()))
+ return true;
+ if (Class.deepPaddingSize() < Filters.PaddingThreshold)
+ return true;
+ return false;
+}
+
+void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
+ uint64_t StartOffset) {
+ NewLine();
+ OS << Label << " (";
+ if (!Data.empty()) {
+ OS << "\n";
+ OS << format_bytes_with_ascii(Data, StartOffset, 32, 4,
+ CurrentIndent + IndentSpaces, true);
+ NewLine();
+ }
+ OS << ")";
+}
+
+void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
+ uint64_t Base, uint64_t StartOffset) {
+ NewLine();
+ OS << Label << " (";
+ if (!Data.empty()) {
+ OS << "\n";
+ Base += StartOffset;
+ OS << format_bytes_with_ascii(Data, Base, 32, 4,
+ CurrentIndent + IndentSpaces, true);
+ NewLine();
+ }
+ OS << ")";
+}
+
+namespace {
+struct Run {
+ Run() = default;
+ explicit Run(uint32_t Block) : Block(Block) {}
+ uint32_t Block = 0;
+ uint64_t ByteLen = 0;
+};
+} // namespace
+
+static std::vector<Run> computeBlockRuns(uint32_t BlockSize,
+ const msf::MSFStreamLayout &Layout) {
+ std::vector<Run> Runs;
+ if (Layout.Length == 0)
+ return Runs;
+
+ ArrayRef<support::ulittle32_t> Blocks = Layout.Blocks;
+ assert(!Blocks.empty());
+ uint64_t StreamBytesRemaining = Layout.Length;
+ uint32_t CurrentBlock = Blocks[0];
+ Runs.emplace_back(CurrentBlock);
+ while (!Blocks.empty()) {
+ Run *CurrentRun = &Runs.back();
+ uint32_t NextBlock = Blocks.front();
+ if (NextBlock < CurrentBlock || (NextBlock - CurrentBlock > 1)) {
+ Runs.emplace_back(NextBlock);
+ CurrentRun = &Runs.back();
+ }
+ uint64_t Used =
+ std::min(static_cast<uint64_t>(BlockSize), StreamBytesRemaining);
+ CurrentRun->ByteLen += Used;
+ StreamBytesRemaining -= Used;
+ CurrentBlock = NextBlock;
+ Blocks = Blocks.drop_front();
+ }
+ return Runs;
+}
+
+static std::pair<Run, uint64_t> findRun(uint64_t Offset, ArrayRef<Run> Runs) {
+ for (const auto &R : Runs) {
+ if (Offset < R.ByteLen)
+ return std::make_pair(R, Offset);
+ Offset -= R.ByteLen;
+ }
+ llvm_unreachable("Invalid offset!");
+}
+
+void LinePrinter::formatMsfStreamData(StringRef Label, PDBFile &File,
+ uint32_t StreamIdx,
+ StringRef StreamPurpose, uint64_t Offset,
+ uint64_t Size) {
+ if (StreamIdx >= File.getNumStreams()) {
+ formatLine("Stream {0}: Not present", StreamIdx);
+ return;
+ }
+ if (Size + Offset > File.getStreamByteSize(StreamIdx)) {
+ formatLine(
+ "Stream {0}: Invalid offset and size, range out of stream bounds",
+ StreamIdx);
+ return;
+ }
+
+ auto S = File.createIndexedStream(StreamIdx);
+ if (!S) {
+ NewLine();
+ formatLine("Stream {0}: Not present", StreamIdx);
+ return;
+ }
+
+ uint64_t End =
+ (Size == 0) ? S->getLength() : std::min(Offset + Size, S->getLength());
+ Size = End - Offset;
+
+ formatLine("Stream {0}: {1} (dumping {2:N} / {3:N} bytes)", StreamIdx,
+ StreamPurpose, Size, S->getLength());
+ AutoIndent Indent(*this);
+ BinaryStreamRef Slice(*S);
+ BinarySubstreamRef Substream;
+ Substream.Offset = Offset;
+ Substream.StreamData = Slice.drop_front(Offset).keep_front(Size);
+
+ auto Layout = File.getStreamLayout(StreamIdx);
+ formatMsfStreamData(Label, File, Layout, Substream);
+}
+
+void LinePrinter::formatMsfStreamData(StringRef Label, PDBFile &File,
+ const msf::MSFStreamLayout &Stream,
+ BinarySubstreamRef Substream) {
+ BinaryStreamReader Reader(Substream.StreamData);
+
+ auto Runs = computeBlockRuns(File.getBlockSize(), Stream);
+
+ NewLine();
+ OS << Label << " (";
+ while (Reader.bytesRemaining() > 0) {
+ OS << "\n";
+
+ Run FoundRun;
+ uint64_t RunOffset;
+ std::tie(FoundRun, RunOffset) = findRun(Substream.Offset, Runs);
+ assert(FoundRun.ByteLen >= RunOffset);
+ uint64_t Len = FoundRun.ByteLen - RunOffset;
+ Len = std::min(Len, Reader.bytesRemaining());
+ uint64_t Base = FoundRun.Block * File.getBlockSize() + RunOffset;
+ ArrayRef<uint8_t> Data;
+ consumeError(Reader.readBytes(Data, Len));
+ OS << format_bytes_with_ascii(Data, Base, 32, 4,
+ CurrentIndent + IndentSpaces, true);
+ if (Reader.bytesRemaining() > 0) {
+ NewLine();
+ OS << formatv(" {0}",
+ fmt_align("<discontinuity>", AlignStyle::Center, 114, '-'));
+ }
+ Substream.Offset += Len;
+ }
+ NewLine();
+ OS << ")";
+}
+
+void LinePrinter::formatMsfStreamBlocks(
+ PDBFile &File, const msf::MSFStreamLayout &StreamLayout) {
+ auto Blocks = makeArrayRef(StreamLayout.Blocks);
+ uint64_t L = StreamLayout.Length;
+
+ while (L > 0) {
+ NewLine();
+ assert(!Blocks.empty());
+ OS << formatv("Block {0} (\n", uint32_t(Blocks.front()));
+ uint64_t UsedBytes =
+ std::min(L, static_cast<uint64_t>(File.getBlockSize()));
+ ArrayRef<uint8_t> BlockData =
+ cantFail(File.getBlockData(Blocks.front(), File.getBlockSize()));
+ uint64_t BaseOffset = Blocks.front();
+ BaseOffset *= File.getBlockSize();
+ OS << format_bytes_with_ascii(BlockData, BaseOffset, 32, 4,
+ CurrentIndent + IndentSpaces, true);
+ NewLine();
+ OS << ")";
+ NewLine();
+ L -= UsedBytes;
+ Blocks = Blocks.drop_front();
+ }
+}
+
+bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName, uint64_t Size) {
+ if (IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters))
+ return true;
+ if (Size < Filters.SizeThreshold)
+ return true;
+ return false;
+}
+
+bool LinePrinter::IsSymbolExcluded(llvm::StringRef SymbolName) {
+ return IsItemExcluded(SymbolName, IncludeSymbolFilters, ExcludeSymbolFilters);
+}
+
+bool LinePrinter::IsCompilandExcluded(llvm::StringRef CompilandName) {
+ return IsItemExcluded(CompilandName, IncludeCompilandFilters,
+ ExcludeCompilandFilters);
+}
+
+WithColor::WithColor(LinePrinter &P, PDB_ColorItem C)
+ : OS(P.OS), UseColor(P.hasColor()) {
+ if (UseColor)
+ applyColor(C);
+}
+
+WithColor::~WithColor() {
+ if (UseColor)
+ OS.resetColor();
+}
+
+void WithColor::applyColor(PDB_ColorItem C) {
+ switch (C) {
+ case PDB_ColorItem::None:
+ OS.resetColor();
+ return;
+ case PDB_ColorItem::Comment:
+ OS.changeColor(raw_ostream::GREEN, false);
+ return;
+ case PDB_ColorItem::Address:
+ OS.changeColor(raw_ostream::YELLOW, /*bold=*/true);
+ return;
+ case PDB_ColorItem::Keyword:
+ OS.changeColor(raw_ostream::MAGENTA, true);
+ return;
+ case PDB_ColorItem::Register:
+ case PDB_ColorItem::Offset:
+ OS.changeColor(raw_ostream::YELLOW, false);
+ return;
+ case PDB_ColorItem::Type:
+ OS.changeColor(raw_ostream::CYAN, true);
+ return;
+ case PDB_ColorItem::Identifier:
+ OS.changeColor(raw_ostream::CYAN, false);
+ return;
+ case PDB_ColorItem::Path:
+ OS.changeColor(raw_ostream::CYAN, false);
+ return;
+ case PDB_ColorItem::Padding:
+ case PDB_ColorItem::SectionHeader:
+ OS.changeColor(raw_ostream::RED, true);
+ return;
+ case PDB_ColorItem::LiteralValue:
+ OS.changeColor(raw_ostream::GREEN, true);
+ return;
+ }
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp b/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
index 1445f0bd9e1b..f0e96a7cd659 100644
--- a/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
@@ -10,16 +10,17 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Error.h"
-#include <algorithm>
#include <cstdint>
using namespace llvm;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp b/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
index 1d873b87b347..500923e57fbb 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
@@ -7,21 +7,19 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
+#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/DebugInfo/PDB/Native/HashTable.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
-#include <tuple>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
index 7717f062eac1..d24364312b31 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
@@ -9,8 +9,6 @@
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/ADT/STLExtras.h"
-
namespace llvm {
namespace pdb {
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp
index 54646867bc5f..b861fc2435b8 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp
@@ -8,13 +8,15 @@
#include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
using namespace llvm;
using namespace llvm::codeview;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
index 5e6412275063..65e253ed115f 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
@@ -8,9 +8,11 @@
#include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
-#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/HashTable.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
namespace llvm {
namespace pdb {
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
index 1e4b07646335..b912bf77e579 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
@@ -8,13 +8,11 @@
#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
+
+#include <vector>
using namespace llvm;
using namespace llvm::codeview;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
index c6621924b516..7108b8efff83 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
@@ -8,13 +8,10 @@
#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
namespace llvm {
namespace pdb {
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp
index feede1dbc958..24fe2244cfc5 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp
@@ -8,11 +8,11 @@
#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
using namespace llvm;
using namespace llvm::codeview;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
index 2524e10cb6c5..6912b8dc838e 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
@@ -8,13 +8,16 @@
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
using namespace llvm;
using namespace llvm::codeview;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
index 895f8943157a..ae0f66c31fde 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
@@ -8,14 +8,14 @@
#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
-#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
index 7f3b35c297b4..b1caa5add5b3 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
@@ -8,11 +8,15 @@
#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -25,7 +29,7 @@ NativeFunctionSymbol::NativeFunctionSymbol(NativeSession &Session,
: NativeRawSymbol(Session, PDB_SymType::Function, Id), Sym(Sym),
RecordOffset(Offset) {}
-NativeFunctionSymbol::~NativeFunctionSymbol() {}
+NativeFunctionSymbol::~NativeFunctionSymbol() = default;
void NativeFunctionSymbol::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp
index 8314353c3890..99ec627fcd26 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp
@@ -12,8 +12,14 @@
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
+#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -25,7 +31,7 @@ NativeInlineSiteSymbol::NativeInlineSiteSymbol(
: NativeRawSymbol(Session, PDB_SymType::InlineSite, Id), Sym(Sym),
ParentAddr(ParentAddr) {}
-NativeInlineSiteSymbol::~NativeInlineSiteSymbol() {}
+NativeInlineSiteSymbol::~NativeInlineSiteSymbol() = default;
void NativeInlineSiteSymbol::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
@@ -98,29 +104,81 @@ void NativeInlineSiteSymbol::getLineOffset(uint32_t OffsetInFunc,
LineOffset = 0;
FileOffset = 0;
uint32_t CodeOffset = 0;
+ Optional<uint32_t> CodeOffsetBase;
+ Optional<uint32_t> CodeOffsetEnd;
+ Optional<int32_t> CurLineOffset;
+ Optional<int32_t> NextLineOffset;
+ Optional<uint32_t> NextFileOffset;
+ auto UpdateCodeOffset = [&](uint32_t Delta) {
+ if (!CodeOffsetBase)
+ CodeOffsetBase = CodeOffset;
+ else if (!CodeOffsetEnd)
+ CodeOffsetEnd = *CodeOffsetBase + Delta;
+ };
+ auto UpdateLineOffset = [&](int32_t Delta) {
+ LineOffset += Delta;
+ if (!CodeOffsetBase || !CurLineOffset)
+ CurLineOffset = LineOffset;
+ else
+ NextLineOffset = LineOffset;
+ };
+ auto UpdateFileOffset = [&](uint32_t Offset) {
+ if (!CodeOffsetBase)
+ FileOffset = Offset;
+ else
+ NextFileOffset = Offset;
+ };
+ auto ValidateAndReset = [&]() {
+ // Current range is finished. Check if OffsetInFunc is in the range.
+ if (CodeOffsetBase && CodeOffsetEnd && CurLineOffset) {
+ if (CodeOffsetBase <= OffsetInFunc && OffsetInFunc < CodeOffsetEnd) {
+ LineOffset = *CurLineOffset;
+ return true;
+ }
+ // Set base, end, file offset and line offset for next range.
+ if (NextFileOffset)
+ FileOffset = *NextFileOffset;
+ if (NextLineOffset) {
+ CurLineOffset = NextLineOffset;
+ NextLineOffset = None;
+ }
+ CodeOffsetBase = CodeOffsetEnd;
+ CodeOffsetEnd = NextFileOffset = None;
+ }
+ return false;
+ };
for (const auto &Annot : Sym.annotations()) {
switch (Annot.OpCode) {
case BinaryAnnotationsOpCode::CodeOffset:
case BinaryAnnotationsOpCode::ChangeCodeOffset:
- case BinaryAnnotationsOpCode::ChangeCodeLength:
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
CodeOffset += Annot.U1;
+ UpdateCodeOffset(Annot.U1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ UpdateCodeOffset(Annot.U1);
break;
case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
CodeOffset += Annot.U2;
+ UpdateCodeOffset(Annot.U2);
+ UpdateCodeOffset(Annot.U1);
break;
case BinaryAnnotationsOpCode::ChangeLineOffset:
+ UpdateLineOffset(Annot.S1);
+ break;
case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
CodeOffset += Annot.U1;
- LineOffset += Annot.S1;
+ UpdateCodeOffset(Annot.U1);
+ UpdateLineOffset(Annot.S1);
break;
case BinaryAnnotationsOpCode::ChangeFile:
- FileOffset = Annot.U1;
+ UpdateFileOffset(Annot.U1);
break;
default:
break;
}
- if (CodeOffset >= OffsetInFunc)
+ if (ValidateAndReset())
return;
}
}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
index 155ed0cdb828..aa7d6ac6f29d 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
index 1265e688b867..339af6108009 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
@@ -9,8 +9,7 @@
#include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -20,7 +19,7 @@ NativePublicSymbol::NativePublicSymbol(NativeSession &Session, SymIndexId Id,
const codeview::PublicSym32 &Sym)
: NativeRawSymbol(Session, PDB_SymType::PublicSymbol, Id), Sym(Sym) {}
-NativePublicSymbol::~NativePublicSymbol() {}
+NativePublicSymbol::~NativePublicSymbol() = default;
void NativePublicSymbol::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
index 2ad552470b61..89f9f9836fec 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
@@ -10,7 +10,6 @@
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
index 7212a0e65035..cf314c3bede3 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -8,31 +8,33 @@
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
-#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
-#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
@@ -45,6 +47,12 @@ using namespace llvm;
using namespace llvm::msf;
using namespace llvm::pdb;
+namespace llvm {
+namespace codeview {
+union DebugInfo;
+}
+} // namespace llvm
+
static DbiStream *getDbiStreamPtr(PDBFile &File) {
Expected<DbiStream &> DbiS = File.getPDBDbiStream();
if (DbiS)
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
index fd813dee6b9f..8d6f8ebebf4c 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
@@ -8,6 +8,8 @@
#include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp
index e5f1dcaf801e..a6e8cbf71548 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp
@@ -8,7 +8,7 @@
#include "llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
@@ -22,7 +22,7 @@ NativeSymbolEnumerator::NativeSymbolEnumerator(
: NativeRawSymbol(Session, PDB_SymType::Data, Id), Parent(Parent),
Record(std::move(Record)) {}
-NativeSymbolEnumerator::~NativeSymbolEnumerator() {}
+NativeSymbolEnumerator::~NativeSymbolEnumerator() = default;
void NativeSymbolEnumerator::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp
index 63ac9fae0e87..e98f357ac485 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp
@@ -8,9 +8,10 @@
#include "llvm/DebugInfo/PDB/Native/NativeTypeArray.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -21,7 +22,7 @@ NativeTypeArray::NativeTypeArray(NativeSession &Session, SymIndexId Id,
codeview::ArrayRecord Record)
: NativeRawSymbol(Session, PDB_SymType::ArrayType, Id), Record(Record),
Index(TI) {}
-NativeTypeArray::~NativeTypeArray() {}
+NativeTypeArray::~NativeTypeArray() = default;
void NativeTypeArray::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
index a08663aa91ba..80f892c7b118 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -19,7 +18,7 @@ NativeTypeBuiltin::NativeTypeBuiltin(NativeSession &PDBSession, SymIndexId Id,
: NativeRawSymbol(PDBSession, PDB_SymType::BuiltinType, Id),
Session(PDBSession), Mods(Mods), Type(T), Length(L) {}
-NativeTypeBuiltin::~NativeTypeBuiltin() {}
+NativeTypeBuiltin::~NativeTypeBuiltin() = default;
void NativeTypeBuiltin::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
index aaec3a5e7c60..ec37d276e66b 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
@@ -9,8 +9,9 @@
#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
@@ -18,8 +19,6 @@
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-#include "llvm/Support/FormatVariadic.h"
-
#include <cassert>
using namespace llvm;
@@ -68,10 +67,13 @@ NativeEnumEnumEnumerators::NativeEnumEnumEnumerators(
ContinuationIndex = ClassParent.getEnumRecord().FieldList;
while (ContinuationIndex) {
- CVType FieldList = Types.getType(*ContinuationIndex);
- assert(FieldList.kind() == LF_FIELDLIST);
+ CVType FieldListCVT = Types.getType(*ContinuationIndex);
+ assert(FieldListCVT.kind() == LF_FIELDLIST);
ContinuationIndex.reset();
- cantFail(visitMemberRecordStream(FieldList.data(), *this));
+ FieldListRecord FieldList;
+ cantFail(TypeDeserializer::deserializeAs<FieldListRecord>(FieldListCVT,
+ FieldList));
+ cantFail(visitMemberRecordStream(FieldList.Data, *this));
}
}
@@ -123,7 +125,7 @@ NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
: NativeRawSymbol(Session, PDB_SymType::Enum, Id),
UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
-NativeTypeEnum::~NativeTypeEnum() {}
+NativeTypeEnum::~NativeTypeEnum() = default;
void NativeTypeEnum::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
@@ -138,7 +140,7 @@ void NativeTypeEnum::dump(raw_ostream &OS, int Indent,
dumpSymbolField(OS, "name", getName(), Indent);
dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
- if (Modifiers.hasValue())
+ if (Modifiers)
dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
RecurseIdFields);
@@ -206,6 +208,8 @@ PDB_BuiltinType NativeTypeEnum::getBuiltinType() const {
return PDB_BuiltinType::Char16;
case SimpleTypeKind::Character32:
return PDB_BuiltinType::Char32;
+ case SimpleTypeKind::Character8:
+ return PDB_BuiltinType::Char8;
case SimpleTypeKind::Int128:
case SimpleTypeKind::Int128Oct:
case SimpleTypeKind::Int16:
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
index f98a4c3043eb..7db3f1c63128 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
@@ -10,9 +10,10 @@
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
-#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -96,7 +97,7 @@ void NativeTypeFunctionSig::initialize() {
}
}
-NativeTypeFunctionSig::~NativeTypeFunctionSig() {}
+NativeTypeFunctionSig::~NativeTypeFunctionSig() = default;
void NativeTypeFunctionSig::initializeArgList(codeview::TypeIndex ArgListTI) {
TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp
index 32dcfc235954..14b903ccef5a 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp
@@ -7,8 +7,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include <cassert>
@@ -29,7 +30,7 @@ NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
: NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI),
Record(std::move(Record)) {}
-NativeTypePointer::~NativeTypePointer() {}
+NativeTypePointer::~NativeTypePointer() = default;
void NativeTypePointer::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp
index 72964a9e0d4d..11cd349b72ca 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp
@@ -1,4 +1,6 @@
#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -9,7 +11,7 @@ NativeTypeTypedef::NativeTypeTypedef(NativeSession &Session, SymIndexId Id,
: NativeRawSymbol(Session, PDB_SymType::Typedef, Id),
Record(std::move(Typedef)) {}
-NativeTypeTypedef::~NativeTypeTypedef() {}
+NativeTypeTypedef::~NativeTypeTypedef() = default;
void NativeTypeTypedef::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
index 917ec14e58d6..b708fb644e7a 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
@@ -7,10 +7,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
-
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-
-#include <cassert>
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -32,7 +33,7 @@ NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
: NativeRawSymbol(Session, PDB_SymType::UDT, Id),
UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
-NativeTypeUDT::~NativeTypeUDT() {}
+NativeTypeUDT::~NativeTypeUDT() = default;
void NativeTypeUDT::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
@@ -44,7 +45,7 @@ void NativeTypeUDT::dump(raw_ostream &OS, int Indent,
dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
PdbSymbolIdField::LexicalParent, ShowIdFields,
RecurseIdFields);
- if (Modifiers.hasValue())
+ if (Modifiers)
dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
RecurseIdFields);
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp
index 837fe19ec88c..63bb3f046e23 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp
@@ -1,4 +1,7 @@
#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
using namespace llvm;
using namespace llvm::pdb;
@@ -10,7 +13,7 @@ NativeTypeVTShape::NativeTypeVTShape(NativeSession &Session, SymIndexId Id,
: NativeRawSymbol(Session, PDB_SymType::VTableShape, Id), TI(TI),
Record(std::move(SR)) {}
-NativeTypeVTShape::~NativeTypeVTShape() {}
+NativeTypeVTShape::~NativeTypeVTShape() = default;
void NativeTypeVTShape::dump(raw_ostream &OS, int Indent,
PdbSymbolIdField ShowIdFields,
diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
index 5c61530c470d..471d183a5f53 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
@@ -8,7 +8,6 @@
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
index f33125474e3a..641043a8e186 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
@@ -7,34 +7,41 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/GUID.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
-#include "llvm/Support/BinaryStream.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/CRC.h"
-#include "llvm/Support/Chrono.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/xxhash.h"
+#include <ctime>
+
using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;
using namespace llvm::support;
+namespace llvm {
+class WritableBinaryStream;
+}
+
PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
: Allocator(Allocator), InjectedSourceHashTraits(Strings),
InjectedSourceTable(2) {}
-PDBFileBuilder::~PDBFileBuilder() {}
+PDBFileBuilder::~PDBFileBuilder() = default;
Error PDBFileBuilder::initialize(uint32_t BlockSize) {
auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
@@ -348,7 +355,7 @@ Error PDBFileBuilder::commit(StringRef Filename, codeview::GUID *Guid) {
H->Age = Info->getAge();
H->Guid = Info->getGuid();
Optional<uint32_t> Sig = Info->getSignature();
- H->Signature = Sig.hasValue() ? *Sig : time(nullptr);
+ H->Signature = Sig ? *Sig : time(nullptr);
}
return Buffer.commit();
diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
index 2be1656e06bb..5bd12f50f1d7 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
@@ -8,7 +8,6 @@
#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
index f7f36901e4d4..45a5bdb48f01 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
@@ -71,7 +71,7 @@ static uint32_t computeBucketCount(uint32_t NumStrings) {
// This list contains all StringCount, BucketCount pairs where BucketCount was
// just incremented. It ends before the first BucketCount entry where
// BucketCount * 3 would overflow a 32-bit unsigned int.
- static std::map<uint32_t, uint32_t> StringsToBuckets = {
+ static const std::pair<uint32_t, uint32_t> StringsToBuckets[] = {
{0, 1},
{1, 2},
{2, 4},
@@ -124,8 +124,9 @@ static uint32_t computeBucketCount(uint32_t NumStrings) {
{517197275, 1034394550},
{775795913, 1551591826},
{1163693870, 2327387740}};
- auto Entry = StringsToBuckets.lower_bound(NumStrings);
- assert(Entry != StringsToBuckets.end());
+ const auto *Entry = llvm::lower_bound(
+ StringsToBuckets, std::make_pair(NumStrings, 0U), llvm::less_first());
+ assert(Entry != std::end(StringsToBuckets));
return Entry->second;
}
diff --git a/llvm/lib/DebugInfo/PDB/Native/PublicsStream.cpp b/llvm/lib/DebugInfo/PDB/Native/PublicsStream.cpp
index a33bf03bf8fb..c7b9f443da5e 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PublicsStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PublicsStream.cpp
@@ -22,14 +22,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
-#include <algorithm>
#include <cstdint>
using namespace llvm;
diff --git a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
index f9e67014477e..f89f09aa3399 100644
--- a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
@@ -1,20 +1,25 @@
#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
-#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
-#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
-#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
+#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
#include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
@@ -32,7 +37,6 @@
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -60,6 +64,7 @@ static const struct BuiltinTypeEntry {
{codeview::SimpleTypeKind::WideCharacter, PDB_BuiltinType::WCharT, 2},
{codeview::SimpleTypeKind::Character16, PDB_BuiltinType::Char16, 2},
{codeview::SimpleTypeKind::Character32, PDB_BuiltinType::Char32, 4},
+ {codeview::SimpleTypeKind::Character8, PDB_BuiltinType::Char8, 1},
{codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
{codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
{codeview::SimpleTypeKind::Float32, PDB_BuiltinType::Float, 4},
diff --git a/llvm/lib/DebugInfo/PDB/Native/SymbolStream.cpp b/llvm/lib/DebugInfo/PDB/Native/SymbolStream.cpp
index 003840b6e67e..5802d1c77527 100644
--- a/llvm/lib/DebugInfo/PDB/Native/SymbolStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/SymbolStream.cpp
@@ -8,10 +8,7 @@
#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
@@ -22,7 +19,7 @@ using namespace llvm::pdb;
SymbolStream::SymbolStream(std::unique_ptr<MappedBlockStream> Stream)
: Stream(std::move(Stream)) {}
-SymbolStream::~SymbolStream() {}
+SymbolStream::~SymbolStream() = default;
Error SymbolStream::reload() {
BinaryStreamReader Reader(*Stream);
diff --git a/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
index 5f4f497690b6..986e45e050c7 100644
--- a/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -9,17 +9,13 @@
#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamArray.h"
-#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
diff --git a/llvm/lib/DebugInfo/PDB/PDB.cpp b/llvm/lib/DebugInfo/PDB/PDB.cpp
index e5b7731f6f4a..d106ba8fefc1 100644
--- a/llvm/lib/DebugInfo/PDB/PDB.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDB.cpp
@@ -15,7 +15,6 @@
#endif
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBContext.cpp b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
index 0ebb70e010d5..e600fb7385f1 100644
--- a/llvm/lib/DebugInfo/PDB/PDBContext.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
@@ -14,6 +14,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/Object/COFF.h"
using namespace llvm;
@@ -62,6 +64,13 @@ DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address,
return Result;
}
+DILineInfo
+PDBContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+ // Unimplemented. S_GDATA and S_LDATA in CodeView (used to describe global
+ // variables) aren't capable of carrying line information.
+ return DILineInfo();
+}
+
DILineInfoTable
PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address,
uint64_t Size,
diff --git a/llvm/lib/DebugInfo/PDB/PDBExtras.cpp b/llvm/lib/DebugInfo/PDB/PDBExtras.cpp
index a6d7ca0da7a9..571510e6bad9 100644
--- a/llvm/lib/DebugInfo/PDB/PDBExtras.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBExtras.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/PDBExtras.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -64,6 +63,7 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, HResult, OS)
CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char16, OS)
CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char32, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char8, OS)
}
return OS;
}
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp
index d6bc7ee9c951..4eb5af9bd292 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp
@@ -8,6 +8,7 @@
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
@@ -43,7 +44,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include <algorithm>
#include <memory>
using namespace llvm;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
index 0fa83efb7ae0..089f4de0f422 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
@@ -10,8 +10,6 @@
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolBlock.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
index 9452282a8817..49ee4937521b 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
@@ -9,9 +9,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
index 529100b23ba5..bd60489b6bed 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
@@ -9,10 +9,11 @@
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Path.h"
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
index 0d86dfe1e632..f775ac949cd8 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
@@ -9,9 +9,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
index 61f119405fd9..2c2ed59c1726 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
@@ -10,9 +10,7 @@
#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolCustom.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
index 6c9a4aa76c3d..405b07c2b689 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
@@ -10,9 +10,6 @@
#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp
index d2b82111ccd5..c604b5cd3a6a 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp
@@ -7,12 +7,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp
index c85756c43e47..3887c23b18ef 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp
@@ -8,10 +8,10 @@
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
-
-#include <utility>
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
index cb0329bc0ed7..59d57e83fc10 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
@@ -10,7 +10,9 @@
#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
index 66433dc17b49..5c72e3f62121 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
@@ -9,9 +9,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
index fe32c93c0121..fd537a9eeea4 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
@@ -8,10 +8,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolLabel.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
index 1fffe69a0c83..896719a6a8e2 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
@@ -10,8 +10,6 @@
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
index 08697683f641..a00b1be40e18 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
@@ -8,10 +8,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolThunk.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
index 6483858183e5..42502a55ef76 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
@@ -10,8 +10,6 @@
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
index a0d521abe43f..bb4eb43f22e5 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
@@ -10,8 +10,6 @@
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
index 08467059b5e1..539c3547a4b0 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
@@ -8,10 +8,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
index a0dd9ef601c0..eca2a09c1f77 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
@@ -10,8 +10,6 @@
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
index 6723894c90ea..a616b4e26cb1 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
@@ -9,9 +9,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
index 4a25a391f278..2828ce4df3f8 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
@@ -10,9 +10,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
index b9fdf6aec811..db8ca327da1e 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
@@ -8,11 +8,10 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
index 4ffea42cbb0a..d4bd9996d786 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
@@ -9,9 +9,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
index 683e93548fb1..acda57f44e33 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
@@ -10,8 +10,6 @@
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
index e80e6c716572..fa6e630e3c45 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
@@ -9,9 +9,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
index 462fc315359b..9e238c7caa37 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
@@ -8,11 +8,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
index 70749d9bf5f5..c2ce21c6ca69 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
@@ -10,8 +10,6 @@
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
index d302c29a3bec..122111d32027 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
@@ -8,16 +8,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
index 4e2a45116d51..a4d81888e457 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
@@ -10,8 +10,6 @@
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include <utility>
-
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
index 78957620e083..835a86e165af 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
@@ -9,9 +9,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
index 650d01183171..85294a4cded2 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
@@ -9,9 +9,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
index 74afbdb18086..98aaaa9b10b9 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
@@ -9,9 +9,6 @@
#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
using namespace llvm;
using namespace llvm::pdb;
diff --git a/llvm/lib/DebugInfo/PDB/UDTLayout.cpp b/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
index 55854bb49888..6e388834f199 100644
--- a/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
+++ b/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
@@ -10,6 +10,8 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
@@ -17,6 +19,7 @@
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
diff --git a/llvm/lib/DebugInfo/Symbolize/DIFetcher.cpp b/llvm/lib/DebugInfo/Symbolize/DIFetcher.cpp
new file mode 100644
index 000000000000..119830de595a
--- /dev/null
+++ b/llvm/lib/DebugInfo/Symbolize/DIFetcher.cpp
@@ -0,0 +1,57 @@
+//===-- lib/DebugInfo/Symbolize/DIFetcher.cpp -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines the implementation of the local debug info fetcher, which
+/// searches cache directories.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/Symbolize/DIFetcher.h"
+
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+namespace llvm {
+namespace symbolize {
+
+Optional<std::string>
+LocalDIFetcher::fetchBuildID(ArrayRef<uint8_t> BuildID) const {
+ auto GetDebugPath = [&](StringRef Directory) {
+ SmallString<128> Path{Directory};
+ sys::path::append(Path, ".build-id",
+ llvm::toHex(BuildID[0], /*LowerCase=*/true),
+ llvm::toHex(BuildID.slice(1), /*LowerCase=*/true));
+ Path += ".debug";
+ return Path;
+ };
+ if (DebugFileDirectory.empty()) {
+ SmallString<128> Path = GetDebugPath(
+#if defined(__NetBSD__)
+ // Try /usr/libdata/debug/.build-id/../...
+ "/usr/libdata/debug"
+#else
+ // Try /usr/lib/debug/.build-id/../...
+ "/usr/lib/debug"
+#endif
+ );
+ if (llvm::sys::fs::exists(Path))
+ return std::string(Path);
+ } else {
+ for (const auto &Directory : DebugFileDirectory) {
+ // Try <debug-file-directory>/.build-id/../...
+ SmallString<128> Path = GetDebugPath(Directory);
+ if (llvm::sys::fs::exists(Path))
+ return std::string(Path);
+ }
+ }
+ return None;
+}
+
+} // namespace symbolize
+} // namespace llvm
diff --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
index e29968d113bd..877380213f21 100644
--- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -16,9 +16,7 @@
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/LineIterator.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cmath>
@@ -208,6 +206,10 @@ void PlainPrinterBase::print(const Request &Request, const DIGlobal &Global) {
Name = DILineInfo::Addr2LineBadString;
OS << Name << "\n";
OS << Global.Start << " " << Global.Size << "\n";
+ if (Global.DeclFile.empty())
+ OS << "??:?\n";
+ else
+ OS << Global.DeclFile << ":" << Global.DeclLine << "\n";
printFooter();
}
diff --git a/llvm/lib/DebugInfo/Symbolize/Markup.cpp b/llvm/lib/DebugInfo/Symbolize/Markup.cpp
new file mode 100644
index 000000000000..9bc65e763287
--- /dev/null
+++ b/llvm/lib/DebugInfo/Symbolize/Markup.cpp
@@ -0,0 +1,202 @@
+//===- lib/DebugInfo/Symbolize/Markup.cpp ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines the log symbolizer markup data model and parser.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/Symbolize/Markup.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+
+namespace llvm {
+namespace symbolize {
+
+// Matches the following:
+// "\033[0m"
+// "\033[1m"
+// "\033[30m" -- "\033[37m"
+static const char SGRSyntaxStr[] = "\033\\[([0-1]|3[0-7])m";
+
+MarkupParser::MarkupParser(StringSet<> MultilineTags)
+ : MultilineTags(std::move(MultilineTags)), SGRSyntax(SGRSyntaxStr) {}
+
+static StringRef takeTo(StringRef Str, StringRef::iterator Pos) {
+ return Str.take_front(Pos - Str.begin());
+}
+static void advanceTo(StringRef &Str, StringRef::iterator Pos) {
+ Str = Str.drop_front(Pos - Str.begin());
+}
+
+void MarkupParser::parseLine(StringRef Line) {
+ Buffer.clear();
+ NextIdx = 0;
+ FinishedMultiline.clear();
+ this->Line = Line;
+}
+
+Optional<MarkupNode> MarkupParser::nextNode() {
+ // Pull something out of the buffer if possible.
+ if (!Buffer.empty()) {
+ if (NextIdx < Buffer.size())
+ return std::move(Buffer[NextIdx++]);
+ NextIdx = 0;
+ Buffer.clear();
+ }
+
+ // The buffer is empty, so parse the next bit of the line.
+
+ if (Line.empty())
+ return None;
+
+ if (!InProgressMultiline.empty()) {
+ if (Optional<StringRef> MultilineEnd = parseMultiLineEnd(Line)) {
+ llvm::append_range(InProgressMultiline, *MultilineEnd);
+ assert(FinishedMultiline.empty() &&
+ "At most one multi-line element can be finished at a time.");
+ FinishedMultiline.swap(InProgressMultiline);
+ // Parse the multi-line element as if it were contiguous.
+ advanceTo(Line, MultilineEnd->end());
+ return *parseElement(FinishedMultiline);
+ }
+
+ // The whole line is part of the multi-line element.
+ llvm::append_range(InProgressMultiline, Line);
+ Line = Line.drop_front(Line.size());
+ return None;
+ }
+
+ // Find the first valid markup element, if any.
+ if (Optional<MarkupNode> Element = parseElement(Line)) {
+ parseTextOutsideMarkup(takeTo(Line, Element->Text.begin()));
+ Buffer.push_back(std::move(*Element));
+ advanceTo(Line, Element->Text.end());
+ return nextNode();
+ }
+
+ // Since there were no valid elements remaining, see if the line opens a
+ // multi-line element.
+ if (Optional<StringRef> MultilineBegin = parseMultiLineBegin(Line)) {
+ // Emit any text before the element.
+ parseTextOutsideMarkup(takeTo(Line, MultilineBegin->begin()));
+
+ // Begin recording the multi-line element.
+ llvm::append_range(InProgressMultiline, *MultilineBegin);
+ Line = Line.drop_front(Line.size());
+ return nextNode();
+ }
+
+ // The line doesn't contain any more markup elements, so emit it as text.
+ parseTextOutsideMarkup(Line);
+ Line = Line.drop_front(Line.size());
+ return nextNode();
+}
+
+void MarkupParser::flush() {
+ if (InProgressMultiline.empty())
+ return;
+ FinishedMultiline.swap(InProgressMultiline);
+ parseTextOutsideMarkup(FinishedMultiline);
+}
+
+// Finds and returns the next valid markup element in the given line. Returns
+// None if the line contains no valid elements.
+Optional<MarkupNode> MarkupParser::parseElement(StringRef Line) {
+ while (true) {
+ // Find next element using begin and end markers.
+ size_t BeginPos = Line.find("{{{");
+ if (BeginPos == StringRef::npos)
+ return None;
+ size_t EndPos = Line.find("}}}", BeginPos + 3);
+ if (EndPos == StringRef::npos)
+ return None;
+ EndPos += 3;
+ MarkupNode Element;
+ Element.Text = Line.slice(BeginPos, EndPos);
+ Line = Line.substr(EndPos);
+
+ // Parse tag.
+ StringRef Content = Element.Text.drop_front(3).drop_back(3);
+ StringRef FieldsContent;
+ std::tie(Element.Tag, FieldsContent) = Content.split(':');
+ if (Element.Tag.empty())
+ continue;
+
+ // Parse fields.
+ if (!FieldsContent.empty())
+ FieldsContent.split(Element.Fields, ":");
+ else if (Content.back() == ':')
+ Element.Fields.push_back(FieldsContent);
+
+ return Element;
+ }
+}
+
+static MarkupNode textNode(StringRef Text) {
+ MarkupNode Node;
+ Node.Text = Text;
+ return Node;
+}
+
+// Parses a region of text known to be outside any markup elements. Such text
+// may still contain SGR control codes, so the region is further subdivided into
+// control codes and true text regions.
+void MarkupParser::parseTextOutsideMarkup(StringRef Text) {
+ if (Text.empty())
+ return;
+ SmallVector<StringRef> Matches;
+ while (SGRSyntax.match(Text, &Matches)) {
+ // Emit any text before the SGR element.
+ if (Matches.begin()->begin() != Text.begin())
+ Buffer.push_back(textNode(takeTo(Text, Matches.begin()->begin())));
+
+ Buffer.push_back(textNode(*Matches.begin()));
+ advanceTo(Text, Matches.begin()->end());
+ }
+ if (!Text.empty())
+ Buffer.push_back(textNode(Text));
+}
+
+// Given that a line doesn't contain any valid markup, see if it ends with the
+// start of a multi-line element. If so, returns the beginning.
+Optional<StringRef> MarkupParser::parseMultiLineBegin(StringRef Line) {
+ // A multi-line begin marker must be the last one on the line.
+ size_t BeginPos = Line.rfind("{{{");
+ if (BeginPos == StringRef::npos)
+ return None;
+ size_t BeginTagPos = BeginPos + 3;
+
+ // If there are any end markers afterwards, the begin marker cannot belong to
+ // a multi-line element.
+ size_t EndPos = Line.find("}}}", BeginTagPos);
+ if (EndPos != StringRef::npos)
+ return None;
+
+ // Check whether the tag is registered multi-line.
+ size_t EndTagPos = Line.find(':', BeginTagPos);
+ if (EndTagPos == StringRef::npos)
+ return None;
+ StringRef Tag = Line.slice(BeginTagPos, EndTagPos);
+ if (!MultilineTags.contains(Tag))
+ return None;
+ return Line.substr(BeginPos);
+}
+
+// See if the line begins with the ending of an in-progress multi-line element.
+// If so, return the ending.
+Optional<StringRef> MarkupParser::parseMultiLineEnd(StringRef Line) {
+ size_t EndPos = Line.find("}}}");
+ if (EndPos == StringRef::npos)
+ return None;
+ return Line.take_front(EndPos + 3);
+}
+
+} // end namespace symbolize
+} // end namespace llvm
diff --git a/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp b/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp
new file mode 100644
index 000000000000..3363fe5e531f
--- /dev/null
+++ b/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp
@@ -0,0 +1,143 @@
+//===-- lib/DebugInfo/Symbolize/MarkupFilter.cpp -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines the implementation of a filter that replaces symbolizer
+/// markup with human-readable expressions.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/Symbolize/MarkupFilter.h"
+
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Demangle/Demangle.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace llvm::symbolize;
+
+MarkupFilter::MarkupFilter(raw_ostream &OS, Optional<bool> ColorsEnabled)
+ : OS(OS), ColorsEnabled(ColorsEnabled.value_or(
+ WithColor::defaultAutoDetectFunction()(OS))) {}
+
+void MarkupFilter::beginLine(StringRef Line) {
+ this->Line = Line;
+ resetColor();
+}
+
+void MarkupFilter::filter(const MarkupNode &Node) {
+ if (!checkTag(Node))
+ return;
+
+ if (trySGR(Node))
+ return;
+
+ if (Node.Tag == "symbol") {
+ if (!checkNumFields(Node, 1))
+ return;
+ highlight();
+ OS << llvm::demangle(Node.Fields.front().str());
+ restoreColor();
+ return;
+ }
+
+ OS << Node.Text;
+}
+
+bool MarkupFilter::trySGR(const MarkupNode &Node) {
+ if (Node.Text == "\033[0m") {
+ resetColor();
+ return true;
+ }
+ if (Node.Text == "\033[1m") {
+ Bold = true;
+ if (ColorsEnabled)
+ OS.changeColor(raw_ostream::Colors::SAVEDCOLOR, Bold);
+ return true;
+ }
+ auto SGRColor = StringSwitch<Optional<raw_ostream::Colors>>(Node.Text)
+ .Case("\033[30m", raw_ostream::Colors::BLACK)
+ .Case("\033[31m", raw_ostream::Colors::RED)
+ .Case("\033[32m", raw_ostream::Colors::GREEN)
+ .Case("\033[33m", raw_ostream::Colors::YELLOW)
+ .Case("\033[34m", raw_ostream::Colors::BLUE)
+ .Case("\033[35m", raw_ostream::Colors::MAGENTA)
+ .Case("\033[36m", raw_ostream::Colors::CYAN)
+ .Case("\033[37m", raw_ostream::Colors::WHITE)
+ .Default(llvm::None);
+ if (SGRColor) {
+ Color = *SGRColor;
+ if (ColorsEnabled)
+ OS.changeColor(*Color);
+ return true;
+ }
+
+ return false;
+}
+
+// Begin highlighting text by picking a different color than the current color
+// state.
+void MarkupFilter::highlight() {
+ if (!ColorsEnabled)
+ return;
+ OS.changeColor(Color == raw_ostream::Colors::BLUE ? raw_ostream::Colors::CYAN
+ : raw_ostream::Colors::BLUE,
+ Bold);
+}
+
+// Set the output stream's color to the current color and bold state of the SGR
+// abstract machine.
+void MarkupFilter::restoreColor() {
+ if (!ColorsEnabled)
+ return;
+ if (Color) {
+ OS.changeColor(*Color, Bold);
+ } else {
+ OS.resetColor();
+ if (Bold)
+ OS.changeColor(raw_ostream::Colors::SAVEDCOLOR, Bold);
+ }
+}
+
+// Set the SGR and output stream's color and bold states back to the default.
+void MarkupFilter::resetColor() {
+ if (!Color && !Bold)
+ return;
+ Color.reset();
+ Bold = false;
+ if (ColorsEnabled)
+ OS.resetColor();
+}
+
+bool MarkupFilter::checkTag(const MarkupNode &Node) const {
+ if (any_of(Node.Tag, [](char C) { return C < 'a' || C > 'z'; })) {
+ WithColor::error(errs()) << "tags must be all lowercase characters\n";
+ reportLocation(Node.Tag.begin());
+ return false;
+ }
+ return true;
+}
+
+bool MarkupFilter::checkNumFields(const MarkupNode &Node, size_t Size) const {
+ if (Node.Fields.size() != Size) {
+ WithColor::error(errs()) << "expected " << Size << " fields; found "
+ << Node.Fields.size() << "\n";
+ reportLocation(Node.Tag.end());
+ return false;
+ }
+ return true;
+}
+
+void MarkupFilter::reportLocation(StringRef::iterator Loc) const {
+ errs() << Line;
+ WithColor(errs().indent(Loc - Line.begin()), HighlightColor::String) << '^';
+ errs() << '\n';
+}
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index a9c78830fa59..d8ee9264b64f 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//
-#include "SymbolizableObjectFile.h"
+#include "llvm/DebugInfo/Symbolize/SymbolizableObjectFile.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/BinaryFormat/COFF.h"
@@ -327,6 +327,14 @@ DIGlobal SymbolizableObjectFile::symbolizeData(
std::string FileName;
getNameFromSymbolTable(ModuleOffset.Address, Res.Name, Res.Start, Res.Size,
FileName);
+ Res.DeclFile = FileName;
+
+ // Try and get a better filename:lineno pair from the debuginfo, if present.
+ DILineInfo DL = DebugInfoContext->getLineInfoForDataAddress(ModuleOffset);
+ if (DL.Line != 0) {
+ Res.DeclFile = DL.FileName;
+ Res.DeclLine = DL.Line;
+ }
return Res;
}
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
deleted file mode 100644
index 8fb003fff0ae..000000000000
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//===- SymbolizableObjectFile.h ---------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the SymbolizableObjectFile class.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEOBJECTFILE_H
-#define LLVM_LIB_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEOBJECTFILE_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace llvm {
-
-class DataExtractor;
-
-namespace symbolize {
-
-class SymbolizableObjectFile : public SymbolizableModule {
-public:
- static Expected<std::unique_ptr<SymbolizableObjectFile>>
- create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx,
- bool UntagAddresses);
-
- DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset,
- DILineInfoSpecifier LineInfoSpecifier,
- bool UseSymbolTable) const override;
- DIInliningInfo symbolizeInlinedCode(object::SectionedAddress ModuleOffset,
- DILineInfoSpecifier LineInfoSpecifier,
- bool UseSymbolTable) const override;
- DIGlobal symbolizeData(object::SectionedAddress ModuleOffset) const override;
- std::vector<DILocal>
- symbolizeFrame(object::SectionedAddress ModuleOffset) const override;
-
- // Return true if this is a 32-bit x86 PE COFF module.
- bool isWin32Module() const override;
-
- // Returns the preferred base of the module, i.e. where the loader would place
- // it in memory assuming there were no conflicts.
- uint64_t getModulePreferredBase() const override;
-
-private:
- bool shouldOverrideWithSymbolTable(FunctionNameKind FNKind,
- bool UseSymbolTable) const;
-
- bool getNameFromSymbolTable(uint64_t Address, std::string &Name,
- uint64_t &Addr, uint64_t &Size,
- std::string &FileName) const;
- // For big-endian PowerPC64 ELF, OpdAddress is the address of the .opd
- // (function descriptor) section and OpdExtractor refers to its contents.
- Error addSymbol(const object::SymbolRef &Symbol, uint64_t SymbolSize,
- DataExtractor *OpdExtractor = nullptr,
- uint64_t OpdAddress = 0);
- Error addCoffExportSymbols(const object::COFFObjectFile *CoffObj);
-
- /// Search for the first occurence of specified Address in ObjectFile.
- uint64_t getModuleSectionIndexForAddress(uint64_t Address) const;
-
- const object::ObjectFile *Module;
- std::unique_ptr<DIContext> DebugInfoContext;
- bool UntagAddresses;
-
- struct SymbolDesc {
- uint64_t Addr;
- // If size is 0, assume that symbol occupies the whole memory range up to
- // the following symbol.
- uint64_t Size;
-
- StringRef Name;
- // Non-zero if this is an ELF local symbol. See the comment in
- // getNameFromSymbolTable.
- uint32_t ELFLocalSymIdx;
-
- bool operator<(const SymbolDesc &RHS) const {
- return Addr != RHS.Addr ? Addr < RHS.Addr : Size < RHS.Size;
- }
- };
- std::vector<SymbolDesc> Symbols;
- // (index, filename) pairs of ELF STT_FILE symbols.
- std::vector<std::pair<uint32_t, StringRef>> FileSymbols;
-
- SymbolizableObjectFile(const object::ObjectFile *Obj,
- std::unique_ptr<DIContext> DICtx,
- bool UntagAddresses);
-};
-
-} // end namespace symbolize
-
-} // end namespace llvm
-
-#endif // LLVM_LIB_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEOBJECTFILE_H
diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 5ec79df17fed..d2ff8aa7c995 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -12,22 +12,19 @@
#include "llvm/DebugInfo/Symbolize/Symbolize.h"
-#include "SymbolizableObjectFile.h"
-
#include "llvm/ADT/STLExtras.h"
-#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/Config/config.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/DebugInfo/PDB/PDBContext.h"
-#include "llvm/Debuginfod/Debuginfod.h"
+#include "llvm/DebugInfo/Symbolize/DIFetcher.h"
+#include "llvm/DebugInfo/Symbolize/SymbolizableObjectFile.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Support/CRC.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compression.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
@@ -38,8 +35,20 @@
#include <cstring>
namespace llvm {
+namespace codeview {
+union DebugInfo;
+}
+namespace object {
+template <class ELFT> class ELFFile;
+}
namespace symbolize {
+LLVMSymbolizer::LLVMSymbolizer() = default;
+
+LLVMSymbolizer::LLVMSymbolizer(const Options &Opts) : Opts(Opts) {}
+
+LLVMSymbolizer::~LLVMSymbolizer() = default;
+
template <typename T>
Expected<DILineInfo>
LLVMSymbolizer::symbolizeCodeCommon(const T &ModuleSpecifier,
@@ -81,6 +90,12 @@ LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
return symbolizeCodeCommon(ModuleName, ModuleOffset);
}
+Expected<DILineInfo>
+LLVMSymbolizer::symbolizeCode(ArrayRef<uint8_t> BuildID,
+ object::SectionedAddress ModuleOffset) {
+ return symbolizeCodeCommon(BuildID, ModuleOffset);
+}
+
template <typename T>
Expected<DIInliningInfo> LLVMSymbolizer::symbolizeInlinedCodeCommon(
const T &ModuleSpecifier, object::SectionedAddress ModuleOffset) {
@@ -124,6 +139,12 @@ LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
return symbolizeInlinedCodeCommon(ModuleName, ModuleOffset);
}
+Expected<DIInliningInfo>
+LLVMSymbolizer::symbolizeInlinedCode(ArrayRef<uint8_t> BuildID,
+ object::SectionedAddress ModuleOffset) {
+ return symbolizeInlinedCodeCommon(BuildID, ModuleOffset);
+}
+
template <typename T>
Expected<DIGlobal>
LLVMSymbolizer::symbolizeDataCommon(const T &ModuleSpecifier,
@@ -163,6 +184,12 @@ LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
return symbolizeDataCommon(ModuleName, ModuleOffset);
}
+Expected<DIGlobal>
+LLVMSymbolizer::symbolizeData(ArrayRef<uint8_t> BuildID,
+ object::SectionedAddress ModuleOffset) {
+ return symbolizeDataCommon(BuildID, ModuleOffset);
+}
+
template <typename T>
Expected<std::vector<DILocal>>
LLVMSymbolizer::symbolizeFrameCommon(const T &ModuleSpecifier,
@@ -198,11 +225,20 @@ LLVMSymbolizer::symbolizeFrame(const std::string &ModuleName,
return symbolizeFrameCommon(ModuleName, ModuleOffset);
}
+Expected<std::vector<DILocal>>
+LLVMSymbolizer::symbolizeFrame(ArrayRef<uint8_t> BuildID,
+ object::SectionedAddress ModuleOffset) {
+ return symbolizeFrameCommon(BuildID, ModuleOffset);
+}
+
void LLVMSymbolizer::flush() {
ObjectForUBPathAndArch.clear();
+ LRUBinaries.clear();
+ CacheSize = 0;
BinaryForPath.clear();
ObjectPairForPathArch.clear();
Modules.clear();
+ BuildIDPaths.clear();
}
namespace {
@@ -230,51 +266,6 @@ bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
return CRCHash == llvm::crc32(arrayRefFromStringRef(MB.get()->getBuffer()));
}
-bool findDebugBinary(const std::string &OrigPath,
- const std::string &DebuglinkName, uint32_t CRCHash,
- const std::string &FallbackDebugPath,
- std::string &Result) {
- SmallString<16> OrigDir(OrigPath);
- llvm::sys::path::remove_filename(OrigDir);
- SmallString<16> DebugPath = OrigDir;
- // Try relative/path/to/original_binary/debuglink_name
- llvm::sys::path::append(DebugPath, DebuglinkName);
- if (checkFileCRC(DebugPath, CRCHash)) {
- Result = std::string(DebugPath.str());
- return true;
- }
- // Try relative/path/to/original_binary/.debug/debuglink_name
- DebugPath = OrigDir;
- llvm::sys::path::append(DebugPath, ".debug", DebuglinkName);
- if (checkFileCRC(DebugPath, CRCHash)) {
- Result = std::string(DebugPath.str());
- return true;
- }
- // Make the path absolute so that lookups will go to
- // "/usr/lib/debug/full/path/to/debug", not
- // "/usr/lib/debug/to/debug"
- llvm::sys::fs::make_absolute(OrigDir);
- if (!FallbackDebugPath.empty()) {
- // Try <FallbackDebugPath>/absolute/path/to/original_binary/debuglink_name
- DebugPath = FallbackDebugPath;
- } else {
-#if defined(__NetBSD__)
- // Try /usr/libdata/debug/absolute/path/to/original_binary/debuglink_name
- DebugPath = "/usr/libdata/debug";
-#else
- // Try /usr/lib/debug/absolute/path/to/original_binary/debuglink_name
- DebugPath = "/usr/lib/debug";
-#endif
- }
- llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir),
- DebuglinkName);
- if (checkFileCRC(DebugPath, CRCHash)) {
- Result = std::string(DebugPath.str());
- return true;
- }
- return false;
-}
-
bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName,
uint32_t &CRCHash) {
if (!Obj)
@@ -351,50 +342,6 @@ Optional<ArrayRef<uint8_t>> getBuildID(const ELFObjectFileBase *Obj) {
return BuildID;
}
-bool findDebugBinary(const std::vector<std::string> &DebugFileDirectory,
- const ArrayRef<uint8_t> BuildID, std::string &Result) {
- auto getDebugPath = [&](StringRef Directory) {
- SmallString<128> Path{Directory};
- sys::path::append(Path, ".build-id",
- llvm::toHex(BuildID[0], /*LowerCase=*/true),
- llvm::toHex(BuildID.slice(1), /*LowerCase=*/true));
- Path += ".debug";
- return Path;
- };
- if (DebugFileDirectory.empty()) {
- SmallString<128> Path = getDebugPath(
-#if defined(__NetBSD__)
- // Try /usr/libdata/debug/.build-id/../...
- "/usr/libdata/debug"
-#else
- // Try /usr/lib/debug/.build-id/../...
- "/usr/lib/debug"
-#endif
- );
- if (llvm::sys::fs::exists(Path)) {
- Result = std::string(Path.str());
- return true;
- }
- } else {
- for (const auto &Directory : DebugFileDirectory) {
- // Try <debug-file-directory>/.build-id/../...
- SmallString<128> Path = getDebugPath(Directory);
- if (llvm::sys::fs::exists(Path)) {
- Result = std::string(Path.str());
- return true;
- }
- }
- }
- // Try debuginfod client cache and known servers.
- Expected<std::string> PathOrErr = getCachedOrDownloadDebuginfo(BuildID);
- if (!PathOrErr) {
- consumeError(PathOrErr.takeError());
- return false;
- }
- Result = *PathOrErr;
- return true;
-}
-
} // end anonymous namespace
ObjectFile *LLVMSymbolizer::lookUpDsymFile(const std::string &ExePath,
@@ -437,8 +384,7 @@ ObjectFile *LLVMSymbolizer::lookUpDebuglinkObject(const std::string &Path,
std::string DebugBinaryPath;
if (!getGNUDebuglinkContents(Obj, DebuglinkName, CRCHash))
return nullptr;
- if (!findDebugBinary(Path, DebuglinkName, CRCHash, Opts.FallbackDebugPath,
- DebugBinaryPath))
+ if (!findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath))
return nullptr;
auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
if (!DbgObjOrErr) {
@@ -458,7 +404,7 @@ ObjectFile *LLVMSymbolizer::lookUpBuildIDObject(const std::string &Path,
if (BuildID->size() < 2)
return nullptr;
std::string DebugBinaryPath;
- if (!findDebugBinary(Opts.DebugFileDirectory, *BuildID, DebugBinaryPath))
+ if (!getOrFindDebugBinary(*BuildID, DebugBinaryPath))
return nullptr;
auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
if (!DbgObjOrErr) {
@@ -468,12 +414,97 @@ ObjectFile *LLVMSymbolizer::lookUpBuildIDObject(const std::string &Path,
return DbgObjOrErr.get();
}
+bool LLVMSymbolizer::findDebugBinary(const std::string &OrigPath,
+ const std::string &DebuglinkName,
+ uint32_t CRCHash, std::string &Result) {
+ SmallString<16> OrigDir(OrigPath);
+ llvm::sys::path::remove_filename(OrigDir);
+ SmallString<16> DebugPath = OrigDir;
+ // Try relative/path/to/original_binary/debuglink_name
+ llvm::sys::path::append(DebugPath, DebuglinkName);
+ if (checkFileCRC(DebugPath, CRCHash)) {
+ Result = std::string(DebugPath.str());
+ return true;
+ }
+ // Try relative/path/to/original_binary/.debug/debuglink_name
+ DebugPath = OrigDir;
+ llvm::sys::path::append(DebugPath, ".debug", DebuglinkName);
+ if (checkFileCRC(DebugPath, CRCHash)) {
+ Result = std::string(DebugPath.str());
+ return true;
+ }
+ // Make the path absolute so that lookups will go to
+ // "/usr/lib/debug/full/path/to/debug", not
+ // "/usr/lib/debug/to/debug"
+ llvm::sys::fs::make_absolute(OrigDir);
+ if (!Opts.FallbackDebugPath.empty()) {
+ // Try <FallbackDebugPath>/absolute/path/to/original_binary/debuglink_name
+ DebugPath = Opts.FallbackDebugPath;
+ } else {
+#if defined(__NetBSD__)
+ // Try /usr/libdata/debug/absolute/path/to/original_binary/debuglink_name
+ DebugPath = "/usr/libdata/debug";
+#else
+ // Try /usr/lib/debug/absolute/path/to/original_binary/debuglink_name
+ DebugPath = "/usr/lib/debug";
+#endif
+ }
+ llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir),
+ DebuglinkName);
+ if (checkFileCRC(DebugPath, CRCHash)) {
+ Result = std::string(DebugPath.str());
+ return true;
+ }
+ return false;
+}
+
+static StringRef getBuildIDStr(ArrayRef<uint8_t> BuildID) {
+ return StringRef(reinterpret_cast<const char *>(BuildID.data()),
+ BuildID.size());
+}
+
+bool LLVMSymbolizer::getOrFindDebugBinary(const ArrayRef<uint8_t> BuildID,
+ std::string &Result) {
+ StringRef BuildIDStr = getBuildIDStr(BuildID);
+ auto I = BuildIDPaths.find(BuildIDStr);
+ if (I != BuildIDPaths.end()) {
+ Result = I->second;
+ return true;
+ }
+ auto recordPath = [&](StringRef Path) {
+ Result = Path.str();
+ auto InsertResult = BuildIDPaths.insert({BuildIDStr, Result});
+ assert(InsertResult.second);
+ (void)InsertResult;
+ };
+
+ Optional<std::string> Path;
+ Path = LocalDIFetcher(Opts.DebugFileDirectory).fetchBuildID(BuildID);
+ if (Path) {
+ recordPath(*Path);
+ return true;
+ }
+
+ // Try caller-provided debug info fetchers.
+ for (const std::unique_ptr<DIFetcher> &Fetcher : DIFetchers) {
+ Path = Fetcher->fetchBuildID(BuildID);
+ if (Path) {
+ recordPath(*Path);
+ return true;
+ }
+ }
+
+ return false;
+}
+
Expected<LLVMSymbolizer::ObjectPair>
LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path,
const std::string &ArchName) {
auto I = ObjectPairForPathArch.find(std::make_pair(Path, ArchName));
- if (I != ObjectPairForPathArch.end())
+ if (I != ObjectPairForPathArch.end()) {
+ recordAccess(BinaryForPath.find(Path)->second);
return I->second;
+ }
auto ObjOrErr = getOrCreateObject(Path, ArchName);
if (!ObjOrErr) {
@@ -495,7 +526,12 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path,
if (!DbgObj)
DbgObj = Obj;
ObjectPair Res = std::make_pair(Obj, DbgObj);
- ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName), Res);
+ std::string DbgObjPath = DbgObj->getFileName().str();
+ auto Pair =
+ ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName), Res);
+ BinaryForPath.find(DbgObjPath)->second.pushEvictor([this, I = Pair.first]() {
+ ObjectPairForPathArch.erase(I);
+ });
return Res;
}
@@ -505,13 +541,19 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path,
Binary *Bin;
auto Pair = BinaryForPath.emplace(Path, OwningBinary<Binary>());
if (!Pair.second) {
- Bin = Pair.first->second.getBinary();
+ Bin = Pair.first->second->getBinary();
+ recordAccess(Pair.first->second);
} else {
Expected<OwningBinary<Binary>> BinOrErr = createBinary(Path);
if (!BinOrErr)
return BinOrErr.takeError();
- Pair.first->second = std::move(BinOrErr.get());
- Bin = Pair.first->second.getBinary();
+
+ CachedBinary &CachedBin = Pair.first->second;
+ CachedBin = std::move(BinOrErr.get());
+ CachedBin.pushEvictor([this, I = Pair.first]() { BinaryForPath.erase(I); });
+ LRUBinaries.push_back(CachedBin);
+ CacheSize += CachedBin.size();
+ Bin = CachedBin->getBinary();
}
if (!Bin)
@@ -530,8 +572,10 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path,
return ObjOrErr.takeError();
}
ObjectFile *Res = ObjOrErr->get();
- ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName),
- std::move(ObjOrErr.get()));
+ auto Pair = ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName),
+ std::move(ObjOrErr.get()));
+ BinaryForPath.find(Path)->second.pushEvictor(
+ [this, Iter = Pair.first]() { ObjectForUBPathAndArch.erase(Iter); });
return Res;
}
if (Bin->isObject()) {
@@ -559,10 +603,6 @@ LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj,
Expected<SymbolizableModule *>
LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
- auto I = Modules.find(ModuleName);
- if (I != Modules.end())
- return I->second.get();
-
std::string BinaryName = ModuleName;
std::string ArchName = Opts.DefaultArch;
size_t ColonPos = ModuleName.find_last_of(':');
@@ -574,6 +614,13 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
ArchName = ArchStr;
}
}
+
+ auto I = Modules.find(ModuleName);
+ if (I != Modules.end()) {
+ recordAccess(BinaryForPath.find(BinaryName)->second);
+ return I->second.get();
+ }
+
auto ObjectsOrErr = getOrCreateObjectPair(BinaryName, ArchName);
if (!ObjectsOrErr) {
// Failed to find valid object file.
@@ -608,7 +655,15 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
Context = DWARFContext::create(
*Objects.second, DWARFContext::ProcessDebugRelocations::Process,
nullptr, Opts.DWPName);
- return createModuleInfo(Objects.first, std::move(Context), ModuleName);
+ auto ModuleOrErr =
+ createModuleInfo(Objects.first, std::move(Context), ModuleName);
+ if (ModuleOrErr) {
+ auto I = Modules.find(ModuleName);
+ BinaryForPath.find(BinaryName)->second.pushEvictor([this, I]() {
+ Modules.erase(I);
+ });
+ }
+ return ModuleOrErr;
}
Expected<SymbolizableModule *>
@@ -623,6 +678,17 @@ LLVMSymbolizer::getOrCreateModuleInfo(const ObjectFile &Obj) {
return createModuleInfo(&Obj, std::move(Context), ObjName);
}
+Expected<SymbolizableModule *>
+LLVMSymbolizer::getOrCreateModuleInfo(ArrayRef<uint8_t> BuildID) {
+ std::string Path;
+ if (!getOrFindDebugBinary(BuildID, Path)) {
+ return createStringError(errc::no_such_file_or_directory,
+ Twine("could not find build ID '") +
+ toHex(BuildID) + "'");
+ }
+ return getOrCreateModuleInfo(Path);
+}
+
namespace {
// Undo these various manglings for Win32 extern "C" functions:
@@ -680,5 +746,35 @@ LLVMSymbolizer::DemangleName(const std::string &Name,
return Name;
}
+void LLVMSymbolizer::recordAccess(CachedBinary &Bin) {
+ if (Bin->getBinary())
+ LRUBinaries.splice(LRUBinaries.end(), LRUBinaries, Bin.getIterator());
+}
+
+void LLVMSymbolizer::pruneCache() {
+ // Evict the LRU binary until the max cache size is reached or there's <= 1
+ // item in the cache. The MRU binary is always kept to avoid thrashing if it's
+ // larger than the cache size.
+ while (CacheSize > Opts.MaxCacheSize && !LRUBinaries.empty() &&
+ std::next(LRUBinaries.begin()) != LRUBinaries.end()) {
+ CachedBinary &Bin = LRUBinaries.front();
+ CacheSize -= Bin.size();
+ LRUBinaries.pop_front();
+ Bin.evict();
+ }
+}
+
+void CachedBinary::pushEvictor(std::function<void()> NewEvictor) {
+ if (Evictor) {
+ this->Evictor = [OldEvictor = std::move(this->Evictor),
+ NewEvictor = std::move(NewEvictor)]() {
+ NewEvictor();
+ OldEvictor();
+ };
+ } else {
+ this->Evictor = std::move(NewEvictor);
+ }
+}
+
} // namespace symbolize
} // namespace llvm