]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / DebugInfo / CodeView / DebugInlineeLinesSubsection.cpp
1 //===- DebugInlineeLinesSubsection.cpp ------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
10 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/DebugInfo/CodeView/CodeView.h"
12 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
13 #include "llvm/Support/BinaryStreamReader.h"
14 #include "llvm/Support/BinaryStreamWriter.h"
15 #include "llvm/Support/Endian.h"
16 #include "llvm/Support/Error.h"
17 #include <cassert>
18 #include <cstdint>
19
20 using namespace llvm;
21 using namespace llvm::codeview;
22
23 Error VarStreamArrayExtractor<InlineeSourceLine>::
24 operator()(BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item) {
25   BinaryStreamReader Reader(Stream);
26
27   if (auto EC = Reader.readObject(Item.Header))
28     return EC;
29
30   if (HasExtraFiles) {
31     uint32_t ExtraFileCount;
32     if (auto EC = Reader.readInteger(ExtraFileCount))
33       return EC;
34     if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
35       return EC;
36   }
37
38   Len = Reader.getOffset();
39   return Error::success();
40 }
41
42 DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef()
43     : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {}
44
45 Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
46   if (auto EC = Reader.readEnum(Signature))
47     return EC;
48
49   Lines.getExtractor().HasExtraFiles = hasExtraFiles();
50   if (auto EC = Reader.readArray(Lines, Reader.bytesRemaining()))
51     return EC;
52
53   assert(Reader.bytesRemaining() == 0);
54   return Error::success();
55 }
56
57 bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const {
58   return Signature == InlineeLinesSignature::ExtraFiles;
59 }
60
61 DebugInlineeLinesSubsection::DebugInlineeLinesSubsection(
62     DebugChecksumsSubsection &Checksums, bool HasExtraFiles)
63     : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums),
64       HasExtraFiles(HasExtraFiles) {}
65
66 uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const {
67   // 4 bytes for the signature
68   uint32_t Size = sizeof(InlineeLinesSignature);
69
70   // one header for each entry.
71   Size += Entries.size() * sizeof(InlineeSourceLineHeader);
72   if (HasExtraFiles) {
73     // If extra files are enabled, one count for each entry.
74     Size += Entries.size() * sizeof(uint32_t);
75
76     // And one file id for each file.
77     Size += ExtraFileCount * sizeof(uint32_t);
78   }
79   assert(Size % 4 == 0);
80   return Size;
81 }
82
83 Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const {
84   InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
85   if (HasExtraFiles)
86     Sig = InlineeLinesSignature::ExtraFiles;
87
88   if (auto EC = Writer.writeEnum(Sig))
89     return EC;
90
91   for (const auto &E : Entries) {
92     if (auto EC = Writer.writeObject(E.Header))
93       return EC;
94
95     if (!HasExtraFiles)
96       continue;
97
98     if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
99       return EC;
100     if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles)))
101       return EC;
102   }
103
104   return Error::success();
105 }
106
107 void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) {
108   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
109
110   auto &Entry = Entries.back();
111   Entry.ExtraFiles.push_back(ulittle32_t(Offset));
112   ++ExtraFileCount;
113 }
114
115 void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId,
116                                                 StringRef FileName,
117                                                 uint32_t SourceLine) {
118   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
119
120   Entries.emplace_back();
121   auto &Entry = Entries.back();
122   Entry.Header.FileID = Offset;
123   Entry.Header.SourceLineNum = SourceLine;
124   Entry.Header.Inlinee = FuncId;
125 }