Line data Source code
1 : //===- ModuleDebugInlineeLineFragment.cpp ------------------------*- C++-*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
11 :
12 : #include "llvm/DebugInfo/CodeView/CodeViewError.h"
13 : #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
14 : #include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
15 : #include "llvm/DebugInfo/CodeView/StringTable.h"
16 :
17 : using namespace llvm;
18 : using namespace llvm::codeview;
19 :
20 22 : Error VarStreamArrayExtractor<InlineeSourceLine>::extract(
21 : BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item,
22 : bool HasExtraFiles) {
23 66 : BinaryStreamReader Reader(Stream);
24 :
25 66 : if (auto EC = Reader.readObject(Item.Header))
26 0 : return EC;
27 :
28 22 : if (HasExtraFiles) {
29 : uint32_t ExtraFileCount;
30 9 : if (auto EC = Reader.readInteger(ExtraFileCount))
31 0 : return EC;
32 9 : if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
33 0 : return EC;
34 : }
35 :
36 22 : Len = Reader.getOffset();
37 66 : return Error::success();
38 : }
39 :
40 12 : ModuleDebugInlineeLineFragmentRef::ModuleDebugInlineeLineFragmentRef()
41 36 : : ModuleDebugFragmentRef(ModuleDebugFragmentKind::InlineeLines) {}
42 :
43 12 : Error ModuleDebugInlineeLineFragmentRef::initialize(BinaryStreamReader Reader) {
44 36 : if (auto EC = Reader.readEnum(Signature))
45 0 : return EC;
46 :
47 12 : if (auto EC =
48 36 : Reader.readArray(Lines, Reader.bytesRemaining(), hasExtraFiles()))
49 0 : return EC;
50 :
51 : assert(Reader.bytesRemaining() == 0);
52 36 : return Error::success();
53 : }
54 :
55 35 : bool ModuleDebugInlineeLineFragmentRef::hasExtraFiles() const {
56 35 : return Signature == InlineeLinesSignature::ExtraFiles;
57 : }
58 :
59 1 : ModuleDebugInlineeLineFragment::ModuleDebugInlineeLineFragment(
60 1 : ModuleDebugFileChecksumFragment &Checksums, bool HasExtraFiles)
61 : : ModuleDebugFragment(ModuleDebugFragmentKind::InlineeLines),
62 3 : Checksums(Checksums), HasExtraFiles(HasExtraFiles) {}
63 :
64 3 : uint32_t ModuleDebugInlineeLineFragment::calculateSerializedLength() {
65 : // 4 bytes for the signature
66 3 : uint32_t Size = sizeof(InlineeLinesSignature);
67 :
68 : // one header for each entry.
69 6 : Size += Entries.size() * sizeof(InlineeSourceLineHeader);
70 3 : if (HasExtraFiles) {
71 : // If extra files are enabled, one count for each entry.
72 0 : Size += Entries.size() * sizeof(uint32_t);
73 :
74 : // And one file id for each file.
75 0 : Size += ExtraFileCount * sizeof(uint32_t);
76 : }
77 : assert(Size % 4 == 0);
78 3 : return Size;
79 : }
80 :
81 1 : Error ModuleDebugInlineeLineFragment::commit(BinaryStreamWriter &Writer) {
82 1 : InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
83 1 : if (HasExtraFiles)
84 0 : Sig = InlineeLinesSignature::ExtraFiles;
85 :
86 3 : if (auto EC = Writer.writeEnum(Sig))
87 0 : return EC;
88 :
89 5 : for (const auto &E : Entries) {
90 4 : if (auto EC = Writer.writeObject(E.Header))
91 0 : return EC;
92 :
93 1 : if (!HasExtraFiles)
94 : continue;
95 :
96 0 : if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
97 0 : return EC;
98 0 : if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles)))
99 0 : return EC;
100 : }
101 :
102 3 : return Error::success();
103 : }
104 :
105 0 : void ModuleDebugInlineeLineFragment::addExtraFile(StringRef FileName) {
106 0 : uint32_t Offset = Checksums.mapChecksumOffset(FileName);
107 :
108 0 : auto &Entry = Entries.back();
109 0 : Entry.ExtraFiles.push_back(ulittle32_t(Offset));
110 0 : ++ExtraFileCount;
111 0 : }
112 :
113 1 : void ModuleDebugInlineeLineFragment::addInlineSite(TypeIndex FuncId,
114 : StringRef FileName,
115 : uint32_t SourceLine) {
116 1 : uint32_t Offset = Checksums.mapChecksumOffset(FileName);
117 :
118 1 : Entries.emplace_back();
119 2 : auto &Entry = Entries.back();
120 2 : Entry.Header.FileID = Offset;
121 2 : Entry.Header.SourceLineNum = SourceLine;
122 1 : Entry.Header.Inlinee = FuncId;
123 1 : }
|