18c099fe0SZachary Turner //===- DebugInlineeLinesSubsection.cpp ------------------------*- C++-*-===//
28c099fe0SZachary Turner //
38c099fe0SZachary Turner //                     The LLVM Compiler Infrastructure
48c099fe0SZachary Turner //
58c099fe0SZachary Turner // This file is distributed under the University of Illinois Open Source
68c099fe0SZachary Turner // License. See LICENSE.TXT for details.
78c099fe0SZachary Turner //
88c099fe0SZachary Turner //===----------------------------------------------------------------------===//
98c099fe0SZachary Turner 
108c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
118c099fe0SZachary Turner 
128c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewError.h"
138c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
14591312c5SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
158c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
168c099fe0SZachary Turner 
178c099fe0SZachary Turner using namespace llvm;
188c099fe0SZachary Turner using namespace llvm::codeview;
198c099fe0SZachary Turner 
20*7e62cd17SZachary Turner Error VarStreamArrayExtractor<InlineeSourceLine>::
21*7e62cd17SZachary Turner operator()(BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item) {
228c099fe0SZachary Turner   BinaryStreamReader Reader(Stream);
238c099fe0SZachary Turner 
248c099fe0SZachary Turner   if (auto EC = Reader.readObject(Item.Header))
258c099fe0SZachary Turner     return EC;
268c099fe0SZachary Turner 
278c099fe0SZachary Turner   if (HasExtraFiles) {
288c099fe0SZachary Turner     uint32_t ExtraFileCount;
298c099fe0SZachary Turner     if (auto EC = Reader.readInteger(ExtraFileCount))
308c099fe0SZachary Turner       return EC;
318c099fe0SZachary Turner     if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
328c099fe0SZachary Turner       return EC;
338c099fe0SZachary Turner   }
348c099fe0SZachary Turner 
358c099fe0SZachary Turner   Len = Reader.getOffset();
368c099fe0SZachary Turner   return Error::success();
378c099fe0SZachary Turner }
388c099fe0SZachary Turner 
398c099fe0SZachary Turner DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef()
408c099fe0SZachary Turner     : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {}
418c099fe0SZachary Turner 
428c099fe0SZachary Turner Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
438c099fe0SZachary Turner   if (auto EC = Reader.readEnum(Signature))
448c099fe0SZachary Turner     return EC;
458c099fe0SZachary Turner 
46*7e62cd17SZachary Turner   Lines.getExtractor().HasExtraFiles = hasExtraFiles();
47*7e62cd17SZachary Turner   if (auto EC = Reader.readArray(Lines, Reader.bytesRemaining()))
488c099fe0SZachary Turner     return EC;
498c099fe0SZachary Turner 
508c099fe0SZachary Turner   assert(Reader.bytesRemaining() == 0);
518c099fe0SZachary Turner   return Error::success();
528c099fe0SZachary Turner }
538c099fe0SZachary Turner 
548c099fe0SZachary Turner bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const {
558c099fe0SZachary Turner   return Signature == InlineeLinesSignature::ExtraFiles;
568c099fe0SZachary Turner }
578c099fe0SZachary Turner 
588c099fe0SZachary Turner DebugInlineeLinesSubsection::DebugInlineeLinesSubsection(
598c099fe0SZachary Turner     DebugChecksumsSubsection &Checksums, bool HasExtraFiles)
608c099fe0SZachary Turner     : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums),
618c099fe0SZachary Turner       HasExtraFiles(HasExtraFiles) {}
628c099fe0SZachary Turner 
63591312c5SZachary Turner uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const {
648c099fe0SZachary Turner   // 4 bytes for the signature
658c099fe0SZachary Turner   uint32_t Size = sizeof(InlineeLinesSignature);
668c099fe0SZachary Turner 
678c099fe0SZachary Turner   // one header for each entry.
688c099fe0SZachary Turner   Size += Entries.size() * sizeof(InlineeSourceLineHeader);
698c099fe0SZachary Turner   if (HasExtraFiles) {
708c099fe0SZachary Turner     // If extra files are enabled, one count for each entry.
718c099fe0SZachary Turner     Size += Entries.size() * sizeof(uint32_t);
728c099fe0SZachary Turner 
738c099fe0SZachary Turner     // And one file id for each file.
748c099fe0SZachary Turner     Size += ExtraFileCount * sizeof(uint32_t);
758c099fe0SZachary Turner   }
768c099fe0SZachary Turner   assert(Size % 4 == 0);
778c099fe0SZachary Turner   return Size;
788c099fe0SZachary Turner }
798c099fe0SZachary Turner 
80591312c5SZachary Turner Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const {
818c099fe0SZachary Turner   InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
828c099fe0SZachary Turner   if (HasExtraFiles)
838c099fe0SZachary Turner     Sig = InlineeLinesSignature::ExtraFiles;
848c099fe0SZachary Turner 
858c099fe0SZachary Turner   if (auto EC = Writer.writeEnum(Sig))
868c099fe0SZachary Turner     return EC;
878c099fe0SZachary Turner 
888c099fe0SZachary Turner   for (const auto &E : Entries) {
898c099fe0SZachary Turner     if (auto EC = Writer.writeObject(E.Header))
908c099fe0SZachary Turner       return EC;
918c099fe0SZachary Turner 
928c099fe0SZachary Turner     if (!HasExtraFiles)
938c099fe0SZachary Turner       continue;
948c099fe0SZachary Turner 
958c099fe0SZachary Turner     if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
968c099fe0SZachary Turner       return EC;
978c099fe0SZachary Turner     if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles)))
988c099fe0SZachary Turner       return EC;
998c099fe0SZachary Turner   }
1008c099fe0SZachary Turner 
1018c099fe0SZachary Turner   return Error::success();
1028c099fe0SZachary Turner }
1038c099fe0SZachary Turner 
1048c099fe0SZachary Turner void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) {
1058c099fe0SZachary Turner   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
1068c099fe0SZachary Turner 
1078c099fe0SZachary Turner   auto &Entry = Entries.back();
1088c099fe0SZachary Turner   Entry.ExtraFiles.push_back(ulittle32_t(Offset));
1098c099fe0SZachary Turner   ++ExtraFileCount;
1108c099fe0SZachary Turner }
1118c099fe0SZachary Turner 
1128c099fe0SZachary Turner void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId,
1138c099fe0SZachary Turner                                                 StringRef FileName,
1148c099fe0SZachary Turner                                                 uint32_t SourceLine) {
1158c099fe0SZachary Turner   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
1168c099fe0SZachary Turner 
1178c099fe0SZachary Turner   Entries.emplace_back();
1188c099fe0SZachary Turner   auto &Entry = Entries.back();
1198c099fe0SZachary Turner   Entry.Header.FileID = Offset;
1208c099fe0SZachary Turner   Entry.Header.SourceLineNum = SourceLine;
1218c099fe0SZachary Turner   Entry.Header.Inlinee = FuncId;
1228c099fe0SZachary Turner }
123