xref: /llvm-project/llvm/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp (revision 7e62cd17d6813d66e46e7177574be81c665d8eab)
1 //===- DebugInlineeLinesSubsection.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/DebugInlineeLinesSubsection.h"
11 
12 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
13 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
14 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
15 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
16 
17 using namespace llvm;
18 using namespace llvm::codeview;
19 
20 Error VarStreamArrayExtractor<InlineeSourceLine>::
21 operator()(BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item) {
22   BinaryStreamReader Reader(Stream);
23 
24   if (auto EC = Reader.readObject(Item.Header))
25     return EC;
26 
27   if (HasExtraFiles) {
28     uint32_t ExtraFileCount;
29     if (auto EC = Reader.readInteger(ExtraFileCount))
30       return EC;
31     if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
32       return EC;
33   }
34 
35   Len = Reader.getOffset();
36   return Error::success();
37 }
38 
39 DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef()
40     : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {}
41 
42 Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
43   if (auto EC = Reader.readEnum(Signature))
44     return EC;
45 
46   Lines.getExtractor().HasExtraFiles = hasExtraFiles();
47   if (auto EC = Reader.readArray(Lines, Reader.bytesRemaining()))
48     return EC;
49 
50   assert(Reader.bytesRemaining() == 0);
51   return Error::success();
52 }
53 
54 bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const {
55   return Signature == InlineeLinesSignature::ExtraFiles;
56 }
57 
58 DebugInlineeLinesSubsection::DebugInlineeLinesSubsection(
59     DebugChecksumsSubsection &Checksums, bool HasExtraFiles)
60     : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums),
61       HasExtraFiles(HasExtraFiles) {}
62 
63 uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const {
64   // 4 bytes for the signature
65   uint32_t Size = sizeof(InlineeLinesSignature);
66 
67   // one header for each entry.
68   Size += Entries.size() * sizeof(InlineeSourceLineHeader);
69   if (HasExtraFiles) {
70     // If extra files are enabled, one count for each entry.
71     Size += Entries.size() * sizeof(uint32_t);
72 
73     // And one file id for each file.
74     Size += ExtraFileCount * sizeof(uint32_t);
75   }
76   assert(Size % 4 == 0);
77   return Size;
78 }
79 
80 Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const {
81   InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
82   if (HasExtraFiles)
83     Sig = InlineeLinesSignature::ExtraFiles;
84 
85   if (auto EC = Writer.writeEnum(Sig))
86     return EC;
87 
88   for (const auto &E : Entries) {
89     if (auto EC = Writer.writeObject(E.Header))
90       return EC;
91 
92     if (!HasExtraFiles)
93       continue;
94 
95     if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
96       return EC;
97     if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles)))
98       return EC;
99   }
100 
101   return Error::success();
102 }
103 
104 void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) {
105   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
106 
107   auto &Entry = Entries.back();
108   Entry.ExtraFiles.push_back(ulittle32_t(Offset));
109   ++ExtraFileCount;
110 }
111 
112 void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId,
113                                                 StringRef FileName,
114                                                 uint32_t SourceLine) {
115   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
116 
117   Entries.emplace_back();
118   auto &Entry = Entries.back();
119   Entry.Header.FileID = Offset;
120   Entry.Header.SourceLineNum = SourceLine;
121   Entry.Header.Inlinee = FuncId;
122 }
123