blob: c54fb2d784a313c17f02ed7d37113a4675273c00 [file] [log] [blame]
Zachary Turneredef1452017-05-02 16:56:09 +00001//===- 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/ModuleDebugFragmentRecord.h"
14
15using namespace llvm;
16using namespace llvm::codeview;
17
18Error VarStreamArrayExtractor<InlineeSourceLine>::extract(
19 BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item,
Zachary Turner59e83892017-05-03 05:34:00 +000020 bool HasExtraFiles) {
Zachary Turneredef1452017-05-02 16:56:09 +000021 BinaryStreamReader Reader(Stream);
22
23 if (auto EC = Reader.readObject(Item.Header))
24 return EC;
25
Zachary Turner59e83892017-05-03 05:34:00 +000026 if (HasExtraFiles) {
Zachary Turneredef1452017-05-02 16:56:09 +000027 uint32_t ExtraFileCount;
28 if (auto EC = Reader.readInteger(ExtraFileCount))
29 return EC;
30 if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
31 return EC;
32 }
33
34 Len = Reader.getOffset();
35 return Error::success();
36}
37
38ModuleDebugInlineeLineFragmentRef::ModuleDebugInlineeLineFragmentRef()
39 : ModuleDebugFragmentRef(ModuleDebugFragmentKind::InlineeLines) {}
40
41Error ModuleDebugInlineeLineFragmentRef::initialize(BinaryStreamReader Reader) {
42 if (auto EC = Reader.readEnum(Signature))
43 return EC;
44
Zachary Turner59e83892017-05-03 05:34:00 +000045 if (auto EC =
46 Reader.readArray(Lines, Reader.bytesRemaining(), hasExtraFiles()))
Zachary Turneredef1452017-05-02 16:56:09 +000047 return EC;
48
49 assert(Reader.bytesRemaining() == 0);
50 return Error::success();
51}
52
53bool ModuleDebugInlineeLineFragmentRef::hasExtraFiles() const {
54 return Signature == InlineeLinesSignature::ExtraFiles;
55}
56
57ModuleDebugInlineeLineFragment::ModuleDebugInlineeLineFragment(
58 bool HasExtraFiles)
59 : ModuleDebugFragment(ModuleDebugFragmentKind::InlineeLines),
60 HasExtraFiles(HasExtraFiles) {}
61
62uint32_t ModuleDebugInlineeLineFragment::calculateSerializedLength() {
63 // 4 bytes for the signature
64 uint32_t Size = sizeof(InlineeLinesSignature);
65
66 // one header for each entry.
67 Size += Entries.size() * sizeof(InlineeSourceLineHeader);
68 if (HasExtraFiles) {
69 // If extra files are enabled, one count for each entry.
70 Size += Entries.size() * sizeof(uint32_t);
71
72 // And one file id for each file.
73 Size += ExtraFileCount * sizeof(uint32_t);
74 }
75 assert(Size % 4 == 0);
76 return Size;
77}
78
79Error ModuleDebugInlineeLineFragment::commit(BinaryStreamWriter &Writer) {
80 InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
81 if (HasExtraFiles)
82 Sig = InlineeLinesSignature::ExtraFiles;
83
84 if (auto EC = Writer.writeEnum(Sig))
85 return EC;
86
87 for (const auto &E : Entries) {
88 if (auto EC = Writer.writeObject(E.Header))
89 return EC;
90
91 if (!HasExtraFiles)
92 continue;
93
94 if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
95 return EC;
96 if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles)))
97 return EC;
98 }
99
100 return Error::success();
101}
102
103void ModuleDebugInlineeLineFragment::addExtraFile(uint32_t FileOffset) {
104 auto &Entry = Entries.back();
105 Entry.ExtraFiles.push_back(ulittle32_t(FileOffset));
106 ++ExtraFileCount;
107}
108
109void ModuleDebugInlineeLineFragment::addInlineSite(TypeIndex FuncId,
110 uint32_t FileOffset,
111 uint32_t SourceLine) {
112 Entries.emplace_back();
113 auto &Entry = Entries.back();
114 Entry.Header.FileID = FileOffset;
115 Entry.Header.SourceLineNum = SourceLine;
116 Entry.Header.Inlinee = FuncId;
117}