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"
14*591312c5SZachary 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 
208c099fe0SZachary Turner Error VarStreamArrayExtractor<InlineeSourceLine>::extract(
218c099fe0SZachary Turner     BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item,
228c099fe0SZachary Turner     bool HasExtraFiles) {
238c099fe0SZachary Turner   BinaryStreamReader Reader(Stream);
248c099fe0SZachary Turner 
258c099fe0SZachary Turner   if (auto EC = Reader.readObject(Item.Header))
268c099fe0SZachary Turner     return EC;
278c099fe0SZachary Turner 
288c099fe0SZachary Turner   if (HasExtraFiles) {
298c099fe0SZachary Turner     uint32_t ExtraFileCount;
308c099fe0SZachary Turner     if (auto EC = Reader.readInteger(ExtraFileCount))
318c099fe0SZachary Turner       return EC;
328c099fe0SZachary Turner     if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
338c099fe0SZachary Turner       return EC;
348c099fe0SZachary Turner   }
358c099fe0SZachary Turner 
368c099fe0SZachary Turner   Len = Reader.getOffset();
378c099fe0SZachary Turner   return Error::success();
388c099fe0SZachary Turner }
398c099fe0SZachary Turner 
408c099fe0SZachary Turner DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef()
418c099fe0SZachary Turner     : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {}
428c099fe0SZachary Turner 
438c099fe0SZachary Turner Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
448c099fe0SZachary Turner   if (auto EC = Reader.readEnum(Signature))
458c099fe0SZachary Turner     return EC;
468c099fe0SZachary Turner 
478c099fe0SZachary Turner   if (auto EC =
488c099fe0SZachary Turner           Reader.readArray(Lines, Reader.bytesRemaining(), hasExtraFiles()))
498c099fe0SZachary Turner     return EC;
508c099fe0SZachary Turner 
518c099fe0SZachary Turner   assert(Reader.bytesRemaining() == 0);
528c099fe0SZachary Turner   return Error::success();
538c099fe0SZachary Turner }
548c099fe0SZachary Turner 
558c099fe0SZachary Turner bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const {
568c099fe0SZachary Turner   return Signature == InlineeLinesSignature::ExtraFiles;
578c099fe0SZachary Turner }
588c099fe0SZachary Turner 
598c099fe0SZachary Turner DebugInlineeLinesSubsection::DebugInlineeLinesSubsection(
608c099fe0SZachary Turner     DebugChecksumsSubsection &Checksums, bool HasExtraFiles)
618c099fe0SZachary Turner     : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums),
628c099fe0SZachary Turner       HasExtraFiles(HasExtraFiles) {}
638c099fe0SZachary Turner 
64*591312c5SZachary Turner uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const {
658c099fe0SZachary Turner   // 4 bytes for the signature
668c099fe0SZachary Turner   uint32_t Size = sizeof(InlineeLinesSignature);
678c099fe0SZachary Turner 
688c099fe0SZachary Turner   // one header for each entry.
698c099fe0SZachary Turner   Size += Entries.size() * sizeof(InlineeSourceLineHeader);
708c099fe0SZachary Turner   if (HasExtraFiles) {
718c099fe0SZachary Turner     // If extra files are enabled, one count for each entry.
728c099fe0SZachary Turner     Size += Entries.size() * sizeof(uint32_t);
738c099fe0SZachary Turner 
748c099fe0SZachary Turner     // And one file id for each file.
758c099fe0SZachary Turner     Size += ExtraFileCount * sizeof(uint32_t);
768c099fe0SZachary Turner   }
778c099fe0SZachary Turner   assert(Size % 4 == 0);
788c099fe0SZachary Turner   return Size;
798c099fe0SZachary Turner }
808c099fe0SZachary Turner 
81*591312c5SZachary Turner Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const {
828c099fe0SZachary Turner   InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
838c099fe0SZachary Turner   if (HasExtraFiles)
848c099fe0SZachary Turner     Sig = InlineeLinesSignature::ExtraFiles;
858c099fe0SZachary Turner 
868c099fe0SZachary Turner   if (auto EC = Writer.writeEnum(Sig))
878c099fe0SZachary Turner     return EC;
888c099fe0SZachary Turner 
898c099fe0SZachary Turner   for (const auto &E : Entries) {
908c099fe0SZachary Turner     if (auto EC = Writer.writeObject(E.Header))
918c099fe0SZachary Turner       return EC;
928c099fe0SZachary Turner 
938c099fe0SZachary Turner     if (!HasExtraFiles)
948c099fe0SZachary Turner       continue;
958c099fe0SZachary Turner 
968c099fe0SZachary Turner     if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
978c099fe0SZachary Turner       return EC;
988c099fe0SZachary Turner     if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles)))
998c099fe0SZachary Turner       return EC;
1008c099fe0SZachary Turner   }
1018c099fe0SZachary Turner 
1028c099fe0SZachary Turner   return Error::success();
1038c099fe0SZachary Turner }
1048c099fe0SZachary Turner 
1058c099fe0SZachary Turner void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) {
1068c099fe0SZachary Turner   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
1078c099fe0SZachary Turner 
1088c099fe0SZachary Turner   auto &Entry = Entries.back();
1098c099fe0SZachary Turner   Entry.ExtraFiles.push_back(ulittle32_t(Offset));
1108c099fe0SZachary Turner   ++ExtraFileCount;
1118c099fe0SZachary Turner }
1128c099fe0SZachary Turner 
1138c099fe0SZachary Turner void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId,
1148c099fe0SZachary Turner                                                 StringRef FileName,
1158c099fe0SZachary Turner                                                 uint32_t SourceLine) {
1168c099fe0SZachary Turner   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
1178c099fe0SZachary Turner 
1188c099fe0SZachary Turner   Entries.emplace_back();
1198c099fe0SZachary Turner   auto &Entry = Entries.back();
1208c099fe0SZachary Turner   Entry.Header.FileID = Offset;
1218c099fe0SZachary Turner   Entry.Header.SourceLineNum = SourceLine;
1228c099fe0SZachary Turner   Entry.Header.Inlinee = FuncId;
1238c099fe0SZachary Turner }
124