11b88f4f3SZachary Turner //===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===//
21b88f4f3SZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61b88f4f3SZachary Turner //
71b88f4f3SZachary Turner //===----------------------------------------------------------------------===//
81b88f4f3SZachary Turner //
91b88f4f3SZachary Turner // This file defines classes for handling the YAML representation of CodeView
101b88f4f3SZachary Turner // Debug Info.
111b88f4f3SZachary Turner //
121b88f4f3SZachary Turner //===----------------------------------------------------------------------===//
131b88f4f3SZachary Turner 
141b88f4f3SZachary Turner #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
1528082ab0SEugene Zelenko #include "llvm/ADT/STLExtras.h"
161b88f4f3SZachary Turner #include "llvm/ADT/StringExtras.h"
1728082ab0SEugene Zelenko #include "llvm/ADT/StringRef.h"
1828082ab0SEugene Zelenko #include "llvm/BinaryFormat/COFF.h"
1928082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/CodeView.h"
201b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewError.h"
2192dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
22349c18f8SZachary Turner #include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
23349c18f8SZachary Turner #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
24deb39130SZachary Turner #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
2592dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
2692dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
2792dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
2828082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/DebugSubsection.h"
2992dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
303226fe95SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
31deb39130SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
3228082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/Line.h"
33a8cfc29cSZachary Turner #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
3428082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/TypeIndex.h"
35deb39130SZachary Turner #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
3628082ab0SEugene Zelenko #include "llvm/Support/Allocator.h"
3728082ab0SEugene Zelenko #include "llvm/Support/BinaryStreamReader.h"
3828082ab0SEugene Zelenko #include "llvm/Support/Endian.h"
3928082ab0SEugene Zelenko #include "llvm/Support/Error.h"
4028082ab0SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
4128082ab0SEugene Zelenko #include "llvm/Support/YAMLTraits.h"
4228082ab0SEugene Zelenko #include "llvm/Support/raw_ostream.h"
4328082ab0SEugene Zelenko #include <algorithm>
4428082ab0SEugene Zelenko #include <cassert>
4528082ab0SEugene Zelenko #include <cstdint>
4628082ab0SEugene Zelenko #include <memory>
4728082ab0SEugene Zelenko #include <string>
4828082ab0SEugene Zelenko #include <tuple>
4928082ab0SEugene Zelenko #include <vector>
5028082ab0SEugene Zelenko 
511b88f4f3SZachary Turner using namespace llvm;
521b88f4f3SZachary Turner using namespace llvm::codeview;
531b88f4f3SZachary Turner using namespace llvm::CodeViewYAML;
541b88f4f3SZachary Turner using namespace llvm::CodeViewYAML::detail;
551b88f4f3SZachary Turner using namespace llvm::yaml;
561b88f4f3SZachary Turner 
571b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry)
581b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry)
591b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry)
601b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock)
611b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo)
621b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite)
631b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo)
64349c18f8SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport)
65349c18f8SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport)
66deb39130SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData)
671b88f4f3SZachary Turner 
68b213b27eSFrancis Visoiu Mistrih LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, QuotingType::None)
6992dcdda6SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind)
701b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind)
711b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags)
721b88f4f3SZachary Turner 
73349c18f8SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleExport)
74deb39130SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLFrameData)
75349c18f8SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLCrossModuleImport)
76349c18f8SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleImportItem)
7792dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry)
7892dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry)
7992dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry)
8092dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock)
8192dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite)
8292dcdda6SZachary Turner 
8392dcdda6SZachary Turner namespace llvm {
8492dcdda6SZachary Turner namespace CodeViewYAML {
8592dcdda6SZachary Turner namespace detail {
8628082ab0SEugene Zelenko 
8792dcdda6SZachary Turner struct YAMLSubsectionBase {
YAMLSubsectionBasellvm::CodeViewYAML::detail::YAMLSubsectionBase8892dcdda6SZachary Turner   explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {}
8928082ab0SEugene Zelenko   virtual ~YAMLSubsectionBase() = default;
9092dcdda6SZachary Turner 
9192dcdda6SZachary Turner   virtual void map(IO &IO) = 0;
92a8cfc29cSZachary Turner   virtual std::shared_ptr<DebugSubsection>
93deb39130SZachary Turner   toCodeViewSubsection(BumpPtrAllocator &Allocator,
94a8cfc29cSZachary Turner                        const codeview::StringsAndChecksums &SC) const = 0;
9528082ab0SEugene Zelenko 
9628082ab0SEugene Zelenko   DebugSubsectionKind Kind;
9792dcdda6SZachary Turner };
9828082ab0SEugene Zelenko 
9928082ab0SEugene Zelenko } // end namespace detail
10028082ab0SEugene Zelenko } // end namespace CodeViewYAML
10128082ab0SEugene Zelenko } // end namespace llvm
10292dcdda6SZachary Turner 
10392dcdda6SZachary Turner namespace {
10428082ab0SEugene Zelenko 
10592dcdda6SZachary Turner struct YAMLChecksumsSubsection : public YAMLSubsectionBase {
YAMLChecksumsSubsection__anon88e5e0310111::YAMLChecksumsSubsection10692dcdda6SZachary Turner   YAMLChecksumsSubsection()
10792dcdda6SZachary Turner       : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {}
10892dcdda6SZachary Turner 
10992dcdda6SZachary Turner   void map(IO &IO) override;
110a8cfc29cSZachary Turner   std::shared_ptr<DebugSubsection>
111deb39130SZachary Turner   toCodeViewSubsection(BumpPtrAllocator &Allocator,
112a8cfc29cSZachary Turner                        const codeview::StringsAndChecksums &SC) const override;
11392dcdda6SZachary Turner   static Expected<std::shared_ptr<YAMLChecksumsSubsection>>
11492dcdda6SZachary Turner   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
11592dcdda6SZachary Turner                          const DebugChecksumsSubsectionRef &FC);
11692dcdda6SZachary Turner 
11792dcdda6SZachary Turner   std::vector<SourceFileChecksumEntry> Checksums;
11892dcdda6SZachary Turner };
11992dcdda6SZachary Turner 
12092dcdda6SZachary Turner struct YAMLLinesSubsection : public YAMLSubsectionBase {
YAMLLinesSubsection__anon88e5e0310111::YAMLLinesSubsection12192dcdda6SZachary Turner   YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {}
12292dcdda6SZachary Turner 
12392dcdda6SZachary Turner   void map(IO &IO) override;
124a8cfc29cSZachary Turner   std::shared_ptr<DebugSubsection>
125deb39130SZachary Turner   toCodeViewSubsection(BumpPtrAllocator &Allocator,
126a8cfc29cSZachary Turner                        const codeview::StringsAndChecksums &SC) const override;
12792dcdda6SZachary Turner   static Expected<std::shared_ptr<YAMLLinesSubsection>>
12892dcdda6SZachary Turner   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
12992dcdda6SZachary Turner                          const DebugChecksumsSubsectionRef &Checksums,
13092dcdda6SZachary Turner                          const DebugLinesSubsectionRef &Lines);
13192dcdda6SZachary Turner 
13292dcdda6SZachary Turner   SourceLineInfo Lines;
13392dcdda6SZachary Turner };
13492dcdda6SZachary Turner 
13592dcdda6SZachary Turner struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase {
YAMLInlineeLinesSubsection__anon88e5e0310111::YAMLInlineeLinesSubsection13692dcdda6SZachary Turner   YAMLInlineeLinesSubsection()
13792dcdda6SZachary Turner       : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {}
13892dcdda6SZachary Turner 
13992dcdda6SZachary Turner   void map(IO &IO) override;
140a8cfc29cSZachary Turner   std::shared_ptr<DebugSubsection>
141deb39130SZachary Turner   toCodeViewSubsection(BumpPtrAllocator &Allocator,
142a8cfc29cSZachary Turner                        const codeview::StringsAndChecksums &SC) const override;
14392dcdda6SZachary Turner   static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
14492dcdda6SZachary Turner   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
14592dcdda6SZachary Turner                          const DebugChecksumsSubsectionRef &Checksums,
14692dcdda6SZachary Turner                          const DebugInlineeLinesSubsectionRef &Lines);
14792dcdda6SZachary Turner 
14892dcdda6SZachary Turner   InlineeInfo InlineeLines;
14992dcdda6SZachary Turner };
150349c18f8SZachary Turner 
151349c18f8SZachary Turner struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase {
YAMLCrossModuleExportsSubsection__anon88e5e0310111::YAMLCrossModuleExportsSubsection152349c18f8SZachary Turner   YAMLCrossModuleExportsSubsection()
153349c18f8SZachary Turner       : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {}
154349c18f8SZachary Turner 
155349c18f8SZachary Turner   void map(IO &IO) override;
156a8cfc29cSZachary Turner   std::shared_ptr<DebugSubsection>
157deb39130SZachary Turner   toCodeViewSubsection(BumpPtrAllocator &Allocator,
158a8cfc29cSZachary Turner                        const codeview::StringsAndChecksums &SC) const override;
159349c18f8SZachary Turner   static Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
160349c18f8SZachary Turner   fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports);
161349c18f8SZachary Turner 
162349c18f8SZachary Turner   std::vector<CrossModuleExport> Exports;
163349c18f8SZachary Turner };
164349c18f8SZachary Turner 
165349c18f8SZachary Turner struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase {
YAMLCrossModuleImportsSubsection__anon88e5e0310111::YAMLCrossModuleImportsSubsection166349c18f8SZachary Turner   YAMLCrossModuleImportsSubsection()
167349c18f8SZachary Turner       : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {}
168349c18f8SZachary Turner 
169349c18f8SZachary Turner   void map(IO &IO) override;
170a8cfc29cSZachary Turner   std::shared_ptr<DebugSubsection>
171deb39130SZachary Turner   toCodeViewSubsection(BumpPtrAllocator &Allocator,
172a8cfc29cSZachary Turner                        const codeview::StringsAndChecksums &SC) const override;
173349c18f8SZachary Turner   static Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
174349c18f8SZachary Turner   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
175349c18f8SZachary Turner                          const DebugCrossModuleImportsSubsectionRef &Imports);
176349c18f8SZachary Turner 
177349c18f8SZachary Turner   std::vector<YAMLCrossModuleImport> Imports;
178349c18f8SZachary Turner };
179deb39130SZachary Turner 
180deb39130SZachary Turner struct YAMLSymbolsSubsection : public YAMLSubsectionBase {
YAMLSymbolsSubsection__anon88e5e0310111::YAMLSymbolsSubsection181deb39130SZachary Turner   YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {}
182deb39130SZachary Turner 
183deb39130SZachary Turner   void map(IO &IO) override;
184a8cfc29cSZachary Turner   std::shared_ptr<DebugSubsection>
185deb39130SZachary Turner   toCodeViewSubsection(BumpPtrAllocator &Allocator,
186a8cfc29cSZachary Turner                        const codeview::StringsAndChecksums &SC) const override;
187deb39130SZachary Turner   static Expected<std::shared_ptr<YAMLSymbolsSubsection>>
188deb39130SZachary Turner   fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols);
189deb39130SZachary Turner 
190deb39130SZachary Turner   std::vector<CodeViewYAML::SymbolRecord> Symbols;
191deb39130SZachary Turner };
192deb39130SZachary Turner 
193deb39130SZachary Turner struct YAMLStringTableSubsection : public YAMLSubsectionBase {
YAMLStringTableSubsection__anon88e5e0310111::YAMLStringTableSubsection194deb39130SZachary Turner   YAMLStringTableSubsection()
195deb39130SZachary Turner       : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {}
196deb39130SZachary Turner 
197deb39130SZachary Turner   void map(IO &IO) override;
198a8cfc29cSZachary Turner   std::shared_ptr<DebugSubsection>
199deb39130SZachary Turner   toCodeViewSubsection(BumpPtrAllocator &Allocator,
200a8cfc29cSZachary Turner                        const codeview::StringsAndChecksums &SC) const override;
201deb39130SZachary Turner   static Expected<std::shared_ptr<YAMLStringTableSubsection>>
202deb39130SZachary Turner   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings);
203deb39130SZachary Turner 
204deb39130SZachary Turner   std::vector<StringRef> Strings;
205deb39130SZachary Turner };
206deb39130SZachary Turner 
207deb39130SZachary Turner struct YAMLFrameDataSubsection : public YAMLSubsectionBase {
YAMLFrameDataSubsection__anon88e5e0310111::YAMLFrameDataSubsection208deb39130SZachary Turner   YAMLFrameDataSubsection()
209deb39130SZachary Turner       : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {}
210deb39130SZachary Turner 
211deb39130SZachary Turner   void map(IO &IO) override;
212a8cfc29cSZachary Turner   std::shared_ptr<DebugSubsection>
213deb39130SZachary Turner   toCodeViewSubsection(BumpPtrAllocator &Allocator,
214a8cfc29cSZachary Turner                        const codeview::StringsAndChecksums &SC) const override;
215deb39130SZachary Turner   static Expected<std::shared_ptr<YAMLFrameDataSubsection>>
216deb39130SZachary Turner   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
217deb39130SZachary Turner                          const DebugFrameDataSubsectionRef &Frames);
218deb39130SZachary Turner 
219deb39130SZachary Turner   std::vector<YAMLFrameData> Frames;
220deb39130SZachary Turner };
2213226fe95SZachary Turner 
2223226fe95SZachary Turner struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase {
YAMLCoffSymbolRVASubsection__anon88e5e0310111::YAMLCoffSymbolRVASubsection2233226fe95SZachary Turner   YAMLCoffSymbolRVASubsection()
2243226fe95SZachary Turner       : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {}
2253226fe95SZachary Turner 
2263226fe95SZachary Turner   void map(IO &IO) override;
227a8cfc29cSZachary Turner   std::shared_ptr<DebugSubsection>
2283226fe95SZachary Turner   toCodeViewSubsection(BumpPtrAllocator &Allocator,
229a8cfc29cSZachary Turner                        const codeview::StringsAndChecksums &SC) const override;
2303226fe95SZachary Turner   static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
2313226fe95SZachary Turner   fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs);
2323226fe95SZachary Turner 
2333226fe95SZachary Turner   std::vector<uint32_t> RVAs;
2343226fe95SZachary Turner };
23528082ab0SEugene Zelenko 
23628082ab0SEugene Zelenko } // end anonymous namespace
2371b88f4f3SZachary Turner 
bitset(IO & io,LineFlags & Flags)2381b88f4f3SZachary Turner void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) {
2391b88f4f3SZachary Turner   io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns);
2401b88f4f3SZachary Turner   io.enumFallback<Hex16>(Flags);
2411b88f4f3SZachary Turner }
2421b88f4f3SZachary Turner 
enumeration(IO & io,FileChecksumKind & Kind)2431b88f4f3SZachary Turner void ScalarEnumerationTraits<FileChecksumKind>::enumeration(
2441b88f4f3SZachary Turner     IO &io, FileChecksumKind &Kind) {
2451b88f4f3SZachary Turner   io.enumCase(Kind, "None", FileChecksumKind::None);
2461b88f4f3SZachary Turner   io.enumCase(Kind, "MD5", FileChecksumKind::MD5);
2471b88f4f3SZachary Turner   io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1);
2481b88f4f3SZachary Turner   io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256);
2491b88f4f3SZachary Turner }
2501b88f4f3SZachary Turner 
output(const HexFormattedString & Value,void * ctx,raw_ostream & Out)2511b88f4f3SZachary Turner void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value,
2521b88f4f3SZachary Turner                                               void *ctx, raw_ostream &Out) {
2531b88f4f3SZachary Turner   StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()),
2541b88f4f3SZachary Turner                   Value.Bytes.size());
2551b88f4f3SZachary Turner   Out << toHex(Bytes);
2561b88f4f3SZachary Turner }
2571b88f4f3SZachary Turner 
input(StringRef Scalar,void * ctxt,HexFormattedString & Value)2581b88f4f3SZachary Turner StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt,
2591b88f4f3SZachary Turner                                                   HexFormattedString &Value) {
2601b88f4f3SZachary Turner   std::string H = fromHex(Scalar);
2611b88f4f3SZachary Turner   Value.Bytes.assign(H.begin(), H.end());
2621b88f4f3SZachary Turner   return StringRef();
2631b88f4f3SZachary Turner }
2641b88f4f3SZachary Turner 
mapping(IO & IO,SourceLineEntry & Obj)2651b88f4f3SZachary Turner void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) {
2661b88f4f3SZachary Turner   IO.mapRequired("Offset", Obj.Offset);
2671b88f4f3SZachary Turner   IO.mapRequired("LineStart", Obj.LineStart);
2681b88f4f3SZachary Turner   IO.mapRequired("IsStatement", Obj.IsStatement);
2691b88f4f3SZachary Turner   IO.mapRequired("EndDelta", Obj.EndDelta);
2701b88f4f3SZachary Turner }
2711b88f4f3SZachary Turner 
mapping(IO & IO,SourceColumnEntry & Obj)2721b88f4f3SZachary Turner void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) {
2731b88f4f3SZachary Turner   IO.mapRequired("StartColumn", Obj.StartColumn);
2741b88f4f3SZachary Turner   IO.mapRequired("EndColumn", Obj.EndColumn);
2751b88f4f3SZachary Turner }
2761b88f4f3SZachary Turner 
mapping(IO & IO,SourceLineBlock & Obj)2771b88f4f3SZachary Turner void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) {
2781b88f4f3SZachary Turner   IO.mapRequired("FileName", Obj.FileName);
2791b88f4f3SZachary Turner   IO.mapRequired("Lines", Obj.Lines);
2801b88f4f3SZachary Turner   IO.mapRequired("Columns", Obj.Columns);
2811b88f4f3SZachary Turner }
2821b88f4f3SZachary Turner 
mapping(IO & IO,CrossModuleExport & Obj)283349c18f8SZachary Turner void MappingTraits<CrossModuleExport>::mapping(IO &IO, CrossModuleExport &Obj) {
284349c18f8SZachary Turner   IO.mapRequired("LocalId", Obj.Local);
285349c18f8SZachary Turner   IO.mapRequired("GlobalId", Obj.Global);
286349c18f8SZachary Turner }
287349c18f8SZachary Turner 
mapping(IO & IO,YAMLCrossModuleImport & Obj)288349c18f8SZachary Turner void MappingTraits<YAMLCrossModuleImport>::mapping(IO &IO,
289349c18f8SZachary Turner                                                    YAMLCrossModuleImport &Obj) {
290349c18f8SZachary Turner   IO.mapRequired("Module", Obj.ModuleName);
291349c18f8SZachary Turner   IO.mapRequired("Imports", Obj.ImportIds);
292349c18f8SZachary Turner }
293349c18f8SZachary Turner 
mapping(IO & IO,SourceFileChecksumEntry & Obj)2941b88f4f3SZachary Turner void MappingTraits<SourceFileChecksumEntry>::mapping(
2951b88f4f3SZachary Turner     IO &IO, SourceFileChecksumEntry &Obj) {
2961b88f4f3SZachary Turner   IO.mapRequired("FileName", Obj.FileName);
2971b88f4f3SZachary Turner   IO.mapRequired("Kind", Obj.Kind);
2981b88f4f3SZachary Turner   IO.mapRequired("Checksum", Obj.ChecksumBytes);
2991b88f4f3SZachary Turner }
3001b88f4f3SZachary Turner 
mapping(IO & IO,InlineeSite & Obj)3011b88f4f3SZachary Turner void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) {
3021b88f4f3SZachary Turner   IO.mapRequired("FileName", Obj.FileName);
3031b88f4f3SZachary Turner   IO.mapRequired("LineNum", Obj.SourceLineNum);
3041b88f4f3SZachary Turner   IO.mapRequired("Inlinee", Obj.Inlinee);
3051b88f4f3SZachary Turner   IO.mapOptional("ExtraFiles", Obj.ExtraFiles);
3061b88f4f3SZachary Turner }
3071b88f4f3SZachary Turner 
mapping(IO & IO,YAMLFrameData & Obj)308deb39130SZachary Turner void MappingTraits<YAMLFrameData>::mapping(IO &IO, YAMLFrameData &Obj) {
309deb39130SZachary Turner   IO.mapRequired("CodeSize", Obj.CodeSize);
310deb39130SZachary Turner   IO.mapRequired("FrameFunc", Obj.FrameFunc);
311deb39130SZachary Turner   IO.mapRequired("LocalSize", Obj.LocalSize);
312deb39130SZachary Turner   IO.mapOptional("MaxStackSize", Obj.MaxStackSize);
313deb39130SZachary Turner   IO.mapOptional("ParamsSize", Obj.ParamsSize);
314deb39130SZachary Turner   IO.mapOptional("PrologSize", Obj.PrologSize);
315deb39130SZachary Turner   IO.mapOptional("RvaStart", Obj.RvaStart);
316deb39130SZachary Turner   IO.mapOptional("SavedRegsSize", Obj.SavedRegsSize);
317deb39130SZachary Turner }
318deb39130SZachary Turner 
map(IO & IO)31992dcdda6SZachary Turner void YAMLChecksumsSubsection::map(IO &IO) {
32092dcdda6SZachary Turner   IO.mapTag("!FileChecksums", true);
32192dcdda6SZachary Turner   IO.mapRequired("Checksums", Checksums);
32292dcdda6SZachary Turner }
32392dcdda6SZachary Turner 
map(IO & IO)32492dcdda6SZachary Turner void YAMLLinesSubsection::map(IO &IO) {
32592dcdda6SZachary Turner   IO.mapTag("!Lines", true);
32692dcdda6SZachary Turner   IO.mapRequired("CodeSize", Lines.CodeSize);
32792dcdda6SZachary Turner 
32892dcdda6SZachary Turner   IO.mapRequired("Flags", Lines.Flags);
32992dcdda6SZachary Turner   IO.mapRequired("RelocOffset", Lines.RelocOffset);
33092dcdda6SZachary Turner   IO.mapRequired("RelocSegment", Lines.RelocSegment);
33192dcdda6SZachary Turner   IO.mapRequired("Blocks", Lines.Blocks);
33292dcdda6SZachary Turner }
33392dcdda6SZachary Turner 
map(IO & IO)33492dcdda6SZachary Turner void YAMLInlineeLinesSubsection::map(IO &IO) {
33592dcdda6SZachary Turner   IO.mapTag("!InlineeLines", true);
33692dcdda6SZachary Turner   IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles);
33792dcdda6SZachary Turner   IO.mapRequired("Sites", InlineeLines.Sites);
33892dcdda6SZachary Turner }
33992dcdda6SZachary Turner 
map(IO & IO)340349c18f8SZachary Turner void YAMLCrossModuleExportsSubsection::map(IO &IO) {
341349c18f8SZachary Turner   IO.mapTag("!CrossModuleExports", true);
342349c18f8SZachary Turner   IO.mapOptional("Exports", Exports);
343349c18f8SZachary Turner }
344349c18f8SZachary Turner 
map(IO & IO)345349c18f8SZachary Turner void YAMLCrossModuleImportsSubsection::map(IO &IO) {
346349c18f8SZachary Turner   IO.mapTag("!CrossModuleImports", true);
347349c18f8SZachary Turner   IO.mapOptional("Imports", Imports);
348349c18f8SZachary Turner }
349349c18f8SZachary Turner 
map(IO & IO)350deb39130SZachary Turner void YAMLSymbolsSubsection::map(IO &IO) {
351deb39130SZachary Turner   IO.mapTag("!Symbols", true);
352deb39130SZachary Turner   IO.mapRequired("Records", Symbols);
353deb39130SZachary Turner }
354deb39130SZachary Turner 
map(IO & IO)355deb39130SZachary Turner void YAMLStringTableSubsection::map(IO &IO) {
356deb39130SZachary Turner   IO.mapTag("!StringTable", true);
357deb39130SZachary Turner   IO.mapRequired("Strings", Strings);
358deb39130SZachary Turner }
359deb39130SZachary Turner 
map(IO & IO)360deb39130SZachary Turner void YAMLFrameDataSubsection::map(IO &IO) {
361deb39130SZachary Turner   IO.mapTag("!FrameData", true);
362deb39130SZachary Turner   IO.mapRequired("Frames", Frames);
363deb39130SZachary Turner }
364deb39130SZachary Turner 
map(IO & IO)3653226fe95SZachary Turner void YAMLCoffSymbolRVASubsection::map(IO &IO) {
3663226fe95SZachary Turner   IO.mapTag("!COFFSymbolRVAs", true);
3673226fe95SZachary Turner   IO.mapRequired("RVAs", RVAs);
3683226fe95SZachary Turner }
3693226fe95SZachary Turner 
mapping(IO & IO,YAMLDebugSubsection & Subsection)37092dcdda6SZachary Turner void MappingTraits<YAMLDebugSubsection>::mapping(
37192dcdda6SZachary Turner     IO &IO, YAMLDebugSubsection &Subsection) {
37292dcdda6SZachary Turner   if (!IO.outputting()) {
37392dcdda6SZachary Turner     if (IO.mapTag("!FileChecksums")) {
37492dcdda6SZachary Turner       auto SS = std::make_shared<YAMLChecksumsSubsection>();
37592dcdda6SZachary Turner       Subsection.Subsection = SS;
37692dcdda6SZachary Turner     } else if (IO.mapTag("!Lines")) {
37792dcdda6SZachary Turner       Subsection.Subsection = std::make_shared<YAMLLinesSubsection>();
37892dcdda6SZachary Turner     } else if (IO.mapTag("!InlineeLines")) {
37992dcdda6SZachary Turner       Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>();
380349c18f8SZachary Turner     } else if (IO.mapTag("!CrossModuleExports")) {
381349c18f8SZachary Turner       Subsection.Subsection =
382349c18f8SZachary Turner           std::make_shared<YAMLCrossModuleExportsSubsection>();
383349c18f8SZachary Turner     } else if (IO.mapTag("!CrossModuleImports")) {
384349c18f8SZachary Turner       Subsection.Subsection =
385349c18f8SZachary Turner           std::make_shared<YAMLCrossModuleImportsSubsection>();
386deb39130SZachary Turner     } else if (IO.mapTag("!Symbols")) {
387deb39130SZachary Turner       Subsection.Subsection = std::make_shared<YAMLSymbolsSubsection>();
388deb39130SZachary Turner     } else if (IO.mapTag("!StringTable")) {
389deb39130SZachary Turner       Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>();
390deb39130SZachary Turner     } else if (IO.mapTag("!FrameData")) {
391deb39130SZachary Turner       Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>();
3923226fe95SZachary Turner     } else if (IO.mapTag("!COFFSymbolRVAs")) {
3933226fe95SZachary Turner       Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>();
39492dcdda6SZachary Turner     } else {
39592dcdda6SZachary Turner       llvm_unreachable("Unexpected subsection tag!");
39692dcdda6SZachary Turner     }
39792dcdda6SZachary Turner   }
39892dcdda6SZachary Turner   Subsection.Subsection->map(IO);
39992dcdda6SZachary Turner }
40092dcdda6SZachary Turner 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const401a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection(
402a8cfc29cSZachary Turner     BumpPtrAllocator &Allocator,
403a8cfc29cSZachary Turner     const codeview::StringsAndChecksums &SC) const {
404a8cfc29cSZachary Turner   assert(SC.hasStrings());
405a8cfc29cSZachary Turner   auto Result = std::make_shared<DebugChecksumsSubsection>(*SC.strings());
40692dcdda6SZachary Turner   for (const auto &CS : Checksums) {
40792dcdda6SZachary Turner     Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes);
40892dcdda6SZachary Turner   }
409a8cfc29cSZachary Turner   return Result;
41092dcdda6SZachary Turner }
41192dcdda6SZachary Turner 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const412a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection(
413a8cfc29cSZachary Turner     BumpPtrAllocator &Allocator,
414a8cfc29cSZachary Turner     const codeview::StringsAndChecksums &SC) const {
415a8cfc29cSZachary Turner   assert(SC.hasStrings() && SC.hasChecksums());
41692dcdda6SZachary Turner   auto Result =
417a8cfc29cSZachary Turner       std::make_shared<DebugLinesSubsection>(*SC.checksums(), *SC.strings());
41892dcdda6SZachary Turner   Result->setCodeSize(Lines.CodeSize);
41992dcdda6SZachary Turner   Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset);
42092dcdda6SZachary Turner   Result->setFlags(Lines.Flags);
42192dcdda6SZachary Turner   for (const auto &LC : Lines.Blocks) {
42292dcdda6SZachary Turner     Result->createBlock(LC.FileName);
42392dcdda6SZachary Turner     if (Result->hasColumnInfo()) {
4248dc7b982SMark de Wever       for (auto Item : zip(LC.Lines, LC.Columns)) {
42592dcdda6SZachary Turner         auto &L = std::get<0>(Item);
42692dcdda6SZachary Turner         auto &C = std::get<1>(Item);
42792dcdda6SZachary Turner         uint32_t LE = L.LineStart + L.EndDelta;
42892dcdda6SZachary Turner         Result->addLineAndColumnInfo(L.Offset,
42992dcdda6SZachary Turner                                      LineInfo(L.LineStart, LE, L.IsStatement),
43092dcdda6SZachary Turner                                      C.StartColumn, C.EndColumn);
43192dcdda6SZachary Turner       }
43292dcdda6SZachary Turner     } else {
43392dcdda6SZachary Turner       for (const auto &L : LC.Lines) {
43492dcdda6SZachary Turner         uint32_t LE = L.LineStart + L.EndDelta;
43592dcdda6SZachary Turner         Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement));
43692dcdda6SZachary Turner       }
43792dcdda6SZachary Turner     }
43892dcdda6SZachary Turner   }
439a8cfc29cSZachary Turner   return Result;
44092dcdda6SZachary Turner }
44192dcdda6SZachary Turner 
442a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const44392dcdda6SZachary Turner YAMLInlineeLinesSubsection::toCodeViewSubsection(
444a8cfc29cSZachary Turner     BumpPtrAllocator &Allocator,
445a8cfc29cSZachary Turner     const codeview::StringsAndChecksums &SC) const {
446a8cfc29cSZachary Turner   assert(SC.hasChecksums());
447a8cfc29cSZachary Turner   auto Result = std::make_shared<DebugInlineeLinesSubsection>(
448a8cfc29cSZachary Turner       *SC.checksums(), InlineeLines.HasExtraFiles);
44992dcdda6SZachary Turner 
45092dcdda6SZachary Turner   for (const auto &Site : InlineeLines.Sites) {
45192dcdda6SZachary Turner     Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName,
45292dcdda6SZachary Turner                           Site.SourceLineNum);
45392dcdda6SZachary Turner     if (!InlineeLines.HasExtraFiles)
45492dcdda6SZachary Turner       continue;
45592dcdda6SZachary Turner 
45692dcdda6SZachary Turner     for (auto EF : Site.ExtraFiles) {
45792dcdda6SZachary Turner       Result->addExtraFile(EF);
45892dcdda6SZachary Turner     }
45992dcdda6SZachary Turner   }
460a8cfc29cSZachary Turner   return Result;
46192dcdda6SZachary Turner }
46292dcdda6SZachary Turner 
463a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const464349c18f8SZachary Turner YAMLCrossModuleExportsSubsection::toCodeViewSubsection(
465a8cfc29cSZachary Turner     BumpPtrAllocator &Allocator,
466a8cfc29cSZachary Turner     const codeview::StringsAndChecksums &SC) const {
467a8cfc29cSZachary Turner   auto Result = std::make_shared<DebugCrossModuleExportsSubsection>();
468349c18f8SZachary Turner   for (const auto &M : Exports)
469349c18f8SZachary Turner     Result->addMapping(M.Local, M.Global);
470a8cfc29cSZachary Turner   return Result;
471349c18f8SZachary Turner }
472349c18f8SZachary Turner 
473a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const474349c18f8SZachary Turner YAMLCrossModuleImportsSubsection::toCodeViewSubsection(
475a8cfc29cSZachary Turner     BumpPtrAllocator &Allocator,
476a8cfc29cSZachary Turner     const codeview::StringsAndChecksums &SC) const {
477a8cfc29cSZachary Turner   assert(SC.hasStrings());
478a8cfc29cSZachary Turner 
479a8cfc29cSZachary Turner   auto Result =
480a8cfc29cSZachary Turner       std::make_shared<DebugCrossModuleImportsSubsection>(*SC.strings());
481349c18f8SZachary Turner   for (const auto &M : Imports) {
482349c18f8SZachary Turner     for (const auto Id : M.ImportIds)
483349c18f8SZachary Turner       Result->addImport(M.ModuleName, Id);
484349c18f8SZachary Turner   }
485a8cfc29cSZachary Turner   return Result;
486349c18f8SZachary Turner }
487349c18f8SZachary Turner 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const488a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection(
489a8cfc29cSZachary Turner     BumpPtrAllocator &Allocator,
490a8cfc29cSZachary Turner     const codeview::StringsAndChecksums &SC) const {
491a8cfc29cSZachary Turner   auto Result = std::make_shared<DebugSymbolsSubsection>();
492deb39130SZachary Turner   for (const auto &Sym : Symbols)
493deb39130SZachary Turner     Result->addSymbol(
494deb39130SZachary Turner         Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile));
495a8cfc29cSZachary Turner   return Result;
496deb39130SZachary Turner }
497deb39130SZachary Turner 
498a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const499deb39130SZachary Turner YAMLStringTableSubsection::toCodeViewSubsection(
500a8cfc29cSZachary Turner     BumpPtrAllocator &Allocator,
501a8cfc29cSZachary Turner     const codeview::StringsAndChecksums &SC) const {
502a8cfc29cSZachary Turner   auto Result = std::make_shared<DebugStringTableSubsection>();
503deb39130SZachary Turner   for (const auto &Str : this->Strings)
504deb39130SZachary Turner     Result->insert(Str);
505a8cfc29cSZachary Turner   return Result;
506deb39130SZachary Turner }
507deb39130SZachary Turner 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const508a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection(
509a8cfc29cSZachary Turner     BumpPtrAllocator &Allocator,
510a8cfc29cSZachary Turner     const codeview::StringsAndChecksums &SC) const {
511a8cfc29cSZachary Turner   assert(SC.hasStrings());
512a8cfc29cSZachary Turner 
51342e7cc1bSZachary Turner   auto Result = std::make_shared<DebugFrameDataSubsection>(true);
514deb39130SZachary Turner   for (const auto &YF : Frames) {
515deb39130SZachary Turner     codeview::FrameData F;
516deb39130SZachary Turner     F.CodeSize = YF.CodeSize;
517deb39130SZachary Turner     F.Flags = YF.Flags;
518deb39130SZachary Turner     F.LocalSize = YF.LocalSize;
519deb39130SZachary Turner     F.MaxStackSize = YF.MaxStackSize;
520deb39130SZachary Turner     F.ParamsSize = YF.ParamsSize;
521deb39130SZachary Turner     F.PrologSize = YF.PrologSize;
522deb39130SZachary Turner     F.RvaStart = YF.RvaStart;
523deb39130SZachary Turner     F.SavedRegsSize = YF.SavedRegsSize;
524a8cfc29cSZachary Turner     F.FrameFunc = SC.strings()->insert(YF.FrameFunc);
525deb39130SZachary Turner     Result->addFrameData(F);
526deb39130SZachary Turner   }
527a8cfc29cSZachary Turner   return Result;
528deb39130SZachary Turner }
529deb39130SZachary Turner 
530a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const5313226fe95SZachary Turner YAMLCoffSymbolRVASubsection::toCodeViewSubsection(
532a8cfc29cSZachary Turner     BumpPtrAllocator &Allocator,
533a8cfc29cSZachary Turner     const codeview::StringsAndChecksums &SC) const {
534a8cfc29cSZachary Turner   auto Result = std::make_shared<DebugSymbolRVASubsection>();
5353226fe95SZachary Turner   for (const auto &RVA : RVAs)
5363226fe95SZachary Turner     Result->addRVA(RVA);
537a8cfc29cSZachary Turner   return Result;
5383226fe95SZachary Turner }
5393226fe95SZachary Turner 
54092dcdda6SZachary Turner static Expected<SourceFileChecksumEntry>
convertOneChecksum(const DebugStringTableSubsectionRef & Strings,const FileChecksumEntry & CS)54192dcdda6SZachary Turner convertOneChecksum(const DebugStringTableSubsectionRef &Strings,
54292dcdda6SZachary Turner                    const FileChecksumEntry &CS) {
54392dcdda6SZachary Turner   auto ExpectedString = Strings.getString(CS.FileNameOffset);
54492dcdda6SZachary Turner   if (!ExpectedString)
54592dcdda6SZachary Turner     return ExpectedString.takeError();
54692dcdda6SZachary Turner 
54792dcdda6SZachary Turner   SourceFileChecksumEntry Result;
54892dcdda6SZachary Turner   Result.ChecksumBytes.Bytes = CS.Checksum;
54992dcdda6SZachary Turner   Result.Kind = CS.Kind;
55092dcdda6SZachary Turner   Result.FileName = *ExpectedString;
55192dcdda6SZachary Turner   return Result;
55292dcdda6SZachary Turner }
55392dcdda6SZachary Turner 
55492dcdda6SZachary Turner static Expected<StringRef>
getFileName(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,uint32_t FileID)55592dcdda6SZachary Turner getFileName(const DebugStringTableSubsectionRef &Strings,
55692dcdda6SZachary Turner             const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) {
55792dcdda6SZachary Turner   auto Iter = Checksums.getArray().at(FileID);
55892dcdda6SZachary Turner   if (Iter == Checksums.getArray().end())
55992dcdda6SZachary Turner     return make_error<CodeViewError>(cv_error_code::no_records);
56092dcdda6SZachary Turner   uint32_t Offset = Iter->FileNameOffset;
56192dcdda6SZachary Turner   return Strings.getString(Offset);
56292dcdda6SZachary Turner }
56392dcdda6SZachary Turner 
56492dcdda6SZachary Turner Expected<std::shared_ptr<YAMLChecksumsSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & FC)56592dcdda6SZachary Turner YAMLChecksumsSubsection::fromCodeViewSubsection(
56692dcdda6SZachary Turner     const DebugStringTableSubsectionRef &Strings,
56792dcdda6SZachary Turner     const DebugChecksumsSubsectionRef &FC) {
56892dcdda6SZachary Turner   auto Result = std::make_shared<YAMLChecksumsSubsection>();
56992dcdda6SZachary Turner 
57092dcdda6SZachary Turner   for (const auto &CS : FC) {
57192dcdda6SZachary Turner     auto ConvertedCS = convertOneChecksum(Strings, CS);
57292dcdda6SZachary Turner     if (!ConvertedCS)
57392dcdda6SZachary Turner       return ConvertedCS.takeError();
57492dcdda6SZachary Turner     Result->Checksums.push_back(*ConvertedCS);
57592dcdda6SZachary Turner   }
57692dcdda6SZachary Turner   return Result;
57792dcdda6SZachary Turner }
57892dcdda6SZachary Turner 
57992dcdda6SZachary Turner Expected<std::shared_ptr<YAMLLinesSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,const DebugLinesSubsectionRef & Lines)58092dcdda6SZachary Turner YAMLLinesSubsection::fromCodeViewSubsection(
58192dcdda6SZachary Turner     const DebugStringTableSubsectionRef &Strings,
58292dcdda6SZachary Turner     const DebugChecksumsSubsectionRef &Checksums,
58392dcdda6SZachary Turner     const DebugLinesSubsectionRef &Lines) {
58492dcdda6SZachary Turner   auto Result = std::make_shared<YAMLLinesSubsection>();
58592dcdda6SZachary Turner   Result->Lines.CodeSize = Lines.header()->CodeSize;
58692dcdda6SZachary Turner   Result->Lines.RelocOffset = Lines.header()->RelocOffset;
58792dcdda6SZachary Turner   Result->Lines.RelocSegment = Lines.header()->RelocSegment;
58892dcdda6SZachary Turner   Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags));
58992dcdda6SZachary Turner   for (const auto &L : Lines) {
59092dcdda6SZachary Turner     SourceLineBlock Block;
59192dcdda6SZachary Turner     auto EF = getFileName(Strings, Checksums, L.NameIndex);
59292dcdda6SZachary Turner     if (!EF)
59392dcdda6SZachary Turner       return EF.takeError();
59492dcdda6SZachary Turner     Block.FileName = *EF;
59592dcdda6SZachary Turner     if (Lines.hasColumnInfo()) {
59692dcdda6SZachary Turner       for (const auto &C : L.Columns) {
59792dcdda6SZachary Turner         SourceColumnEntry SCE;
59892dcdda6SZachary Turner         SCE.EndColumn = C.EndColumn;
59992dcdda6SZachary Turner         SCE.StartColumn = C.StartColumn;
60092dcdda6SZachary Turner         Block.Columns.push_back(SCE);
60192dcdda6SZachary Turner       }
60292dcdda6SZachary Turner     }
60392dcdda6SZachary Turner     for (const auto &LN : L.LineNumbers) {
60492dcdda6SZachary Turner       SourceLineEntry SLE;
60592dcdda6SZachary Turner       LineInfo LI(LN.Flags);
60692dcdda6SZachary Turner       SLE.Offset = LN.Offset;
60792dcdda6SZachary Turner       SLE.LineStart = LI.getStartLine();
60892dcdda6SZachary Turner       SLE.EndDelta = LI.getLineDelta();
60992dcdda6SZachary Turner       SLE.IsStatement = LI.isStatement();
61092dcdda6SZachary Turner       Block.Lines.push_back(SLE);
61192dcdda6SZachary Turner     }
61292dcdda6SZachary Turner     Result->Lines.Blocks.push_back(Block);
61392dcdda6SZachary Turner   }
61492dcdda6SZachary Turner   return Result;
61592dcdda6SZachary Turner }
61692dcdda6SZachary Turner 
61792dcdda6SZachary Turner Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,const DebugInlineeLinesSubsectionRef & Lines)61892dcdda6SZachary Turner YAMLInlineeLinesSubsection::fromCodeViewSubsection(
61992dcdda6SZachary Turner     const DebugStringTableSubsectionRef &Strings,
62092dcdda6SZachary Turner     const DebugChecksumsSubsectionRef &Checksums,
62192dcdda6SZachary Turner     const DebugInlineeLinesSubsectionRef &Lines) {
62292dcdda6SZachary Turner   auto Result = std::make_shared<YAMLInlineeLinesSubsection>();
62392dcdda6SZachary Turner 
62492dcdda6SZachary Turner   Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles();
62592dcdda6SZachary Turner   for (const auto &IL : Lines) {
62692dcdda6SZachary Turner     InlineeSite Site;
62792dcdda6SZachary Turner     auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID);
62892dcdda6SZachary Turner     if (!ExpF)
62992dcdda6SZachary Turner       return ExpF.takeError();
63092dcdda6SZachary Turner     Site.FileName = *ExpF;
63192dcdda6SZachary Turner     Site.Inlinee = IL.Header->Inlinee.getIndex();
63292dcdda6SZachary Turner     Site.SourceLineNum = IL.Header->SourceLineNum;
63392dcdda6SZachary Turner     if (Lines.hasExtraFiles()) {
63492dcdda6SZachary Turner       for (const auto EF : IL.ExtraFiles) {
63592dcdda6SZachary Turner         auto ExpF2 = getFileName(Strings, Checksums, EF);
63692dcdda6SZachary Turner         if (!ExpF2)
63792dcdda6SZachary Turner           return ExpF2.takeError();
63892dcdda6SZachary Turner         Site.ExtraFiles.push_back(*ExpF2);
63992dcdda6SZachary Turner       }
64092dcdda6SZachary Turner     }
64192dcdda6SZachary Turner     Result->InlineeLines.Sites.push_back(Site);
64292dcdda6SZachary Turner   }
64392dcdda6SZachary Turner   return Result;
64492dcdda6SZachary Turner }
64592dcdda6SZachary Turner 
646349c18f8SZachary Turner Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef & Exports)647349c18f8SZachary Turner YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(
648349c18f8SZachary Turner     const DebugCrossModuleExportsSubsectionRef &Exports) {
649349c18f8SZachary Turner   auto Result = std::make_shared<YAMLCrossModuleExportsSubsection>();
650349c18f8SZachary Turner   Result->Exports.assign(Exports.begin(), Exports.end());
651349c18f8SZachary Turner   return Result;
652349c18f8SZachary Turner }
653349c18f8SZachary Turner 
654349c18f8SZachary Turner Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugCrossModuleImportsSubsectionRef & Imports)655349c18f8SZachary Turner YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
656349c18f8SZachary Turner     const DebugStringTableSubsectionRef &Strings,
657349c18f8SZachary Turner     const DebugCrossModuleImportsSubsectionRef &Imports) {
658349c18f8SZachary Turner   auto Result = std::make_shared<YAMLCrossModuleImportsSubsection>();
659349c18f8SZachary Turner   for (const auto &CMI : Imports) {
660349c18f8SZachary Turner     YAMLCrossModuleImport YCMI;
661349c18f8SZachary Turner     auto ExpectedStr = Strings.getString(CMI.Header->ModuleNameOffset);
662349c18f8SZachary Turner     if (!ExpectedStr)
663349c18f8SZachary Turner       return ExpectedStr.takeError();
664349c18f8SZachary Turner     YCMI.ModuleName = *ExpectedStr;
665349c18f8SZachary Turner     YCMI.ImportIds.assign(CMI.Imports.begin(), CMI.Imports.end());
666349c18f8SZachary Turner     Result->Imports.push_back(YCMI);
667349c18f8SZachary Turner   }
668349c18f8SZachary Turner   return Result;
669349c18f8SZachary Turner }
670349c18f8SZachary Turner 
671deb39130SZachary Turner Expected<std::shared_ptr<YAMLSymbolsSubsection>>
fromCodeViewSubsection(const DebugSymbolsSubsectionRef & Symbols)672deb39130SZachary Turner YAMLSymbolsSubsection::fromCodeViewSubsection(
673deb39130SZachary Turner     const DebugSymbolsSubsectionRef &Symbols) {
674deb39130SZachary Turner   auto Result = std::make_shared<YAMLSymbolsSubsection>();
675deb39130SZachary Turner   for (const auto &Sym : Symbols) {
676deb39130SZachary Turner     auto S = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym);
677deb39130SZachary Turner     if (!S)
678deb39130SZachary Turner       return joinErrors(make_error<CodeViewError>(
679deb39130SZachary Turner                             cv_error_code::corrupt_record,
680deb39130SZachary Turner                             "Invalid CodeView Symbol Record in SymbolRecord "
681deb39130SZachary Turner                             "subsection of .debug$S while converting to YAML!"),
682deb39130SZachary Turner                         S.takeError());
683deb39130SZachary Turner 
684deb39130SZachary Turner     Result->Symbols.push_back(*S);
685deb39130SZachary Turner   }
686deb39130SZachary Turner   return Result;
687deb39130SZachary Turner }
688deb39130SZachary Turner 
689deb39130SZachary Turner Expected<std::shared_ptr<YAMLStringTableSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings)690deb39130SZachary Turner YAMLStringTableSubsection::fromCodeViewSubsection(
691deb39130SZachary Turner     const DebugStringTableSubsectionRef &Strings) {
692deb39130SZachary Turner   auto Result = std::make_shared<YAMLStringTableSubsection>();
693deb39130SZachary Turner   BinaryStreamReader Reader(Strings.getBuffer());
694deb39130SZachary Turner   StringRef S;
695deb39130SZachary Turner   // First item is a single null string, skip it.
696deb39130SZachary Turner   if (auto EC = Reader.readCString(S))
697*c55cf4afSBill Wendling     return std::move(EC);
698deb39130SZachary Turner   assert(S.empty());
699deb39130SZachary Turner   while (Reader.bytesRemaining() > 0) {
700deb39130SZachary Turner     if (auto EC = Reader.readCString(S))
701*c55cf4afSBill Wendling       return std::move(EC);
702deb39130SZachary Turner     Result->Strings.push_back(S);
703deb39130SZachary Turner   }
704deb39130SZachary Turner   return Result;
705deb39130SZachary Turner }
706deb39130SZachary Turner 
707deb39130SZachary Turner Expected<std::shared_ptr<YAMLFrameDataSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugFrameDataSubsectionRef & Frames)708deb39130SZachary Turner YAMLFrameDataSubsection::fromCodeViewSubsection(
709deb39130SZachary Turner     const DebugStringTableSubsectionRef &Strings,
710deb39130SZachary Turner     const DebugFrameDataSubsectionRef &Frames) {
711deb39130SZachary Turner   auto Result = std::make_shared<YAMLFrameDataSubsection>();
712deb39130SZachary Turner   for (const auto &F : Frames) {
713deb39130SZachary Turner     YAMLFrameData YF;
714deb39130SZachary Turner     YF.CodeSize = F.CodeSize;
715deb39130SZachary Turner     YF.Flags = F.Flags;
716deb39130SZachary Turner     YF.LocalSize = F.LocalSize;
717deb39130SZachary Turner     YF.MaxStackSize = F.MaxStackSize;
718deb39130SZachary Turner     YF.ParamsSize = F.ParamsSize;
719deb39130SZachary Turner     YF.PrologSize = F.PrologSize;
720deb39130SZachary Turner     YF.RvaStart = F.RvaStart;
721deb39130SZachary Turner     YF.SavedRegsSize = F.SavedRegsSize;
722deb39130SZachary Turner 
723deb39130SZachary Turner     auto ES = Strings.getString(F.FrameFunc);
724deb39130SZachary Turner     if (!ES)
725deb39130SZachary Turner       return joinErrors(
726deb39130SZachary Turner           make_error<CodeViewError>(
727deb39130SZachary Turner               cv_error_code::no_records,
728deb39130SZachary Turner               "Could not find string for string id while mapping FrameData!"),
729deb39130SZachary Turner           ES.takeError());
730deb39130SZachary Turner     YF.FrameFunc = *ES;
731deb39130SZachary Turner     Result->Frames.push_back(YF);
732deb39130SZachary Turner   }
733deb39130SZachary Turner   return Result;
734deb39130SZachary Turner }
735deb39130SZachary Turner 
7363226fe95SZachary Turner Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
fromCodeViewSubsection(const DebugSymbolRVASubsectionRef & Section)7373226fe95SZachary Turner YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(
7383226fe95SZachary Turner     const DebugSymbolRVASubsectionRef &Section) {
7393226fe95SZachary Turner   auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>();
7403226fe95SZachary Turner   for (const auto &RVA : Section) {
7413226fe95SZachary Turner     Result->RVAs.push_back(RVA);
7423226fe95SZachary Turner   }
7433226fe95SZachary Turner   return Result;
7443226fe95SZachary Turner }
7453226fe95SZachary Turner 
746a8cfc29cSZachary Turner Expected<std::vector<std::shared_ptr<DebugSubsection>>>
toCodeViewSubsectionList(BumpPtrAllocator & Allocator,ArrayRef<YAMLDebugSubsection> Subsections,const codeview::StringsAndChecksums & SC)747deb39130SZachary Turner llvm::CodeViewYAML::toCodeViewSubsectionList(
748deb39130SZachary Turner     BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections,
749a8cfc29cSZachary Turner     const codeview::StringsAndChecksums &SC) {
750a8cfc29cSZachary Turner   std::vector<std::shared_ptr<DebugSubsection>> Result;
75192dcdda6SZachary Turner   if (Subsections.empty())
752*c55cf4afSBill Wendling     return std::move(Result);
75392dcdda6SZachary Turner 
75492dcdda6SZachary Turner   for (const auto &SS : Subsections) {
755a8cfc29cSZachary Turner     std::shared_ptr<DebugSubsection> CVS;
756a8cfc29cSZachary Turner     CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC);
757349c18f8SZachary Turner     assert(CVS != nullptr);
75892dcdda6SZachary Turner     Result.push_back(std::move(CVS));
75992dcdda6SZachary Turner   }
760*c55cf4afSBill Wendling   return std::move(Result);
76192dcdda6SZachary Turner }
76292dcdda6SZachary Turner 
76392dcdda6SZachary Turner namespace {
76428082ab0SEugene Zelenko 
76592dcdda6SZachary Turner struct SubsectionConversionVisitor : public DebugSubsectionVisitor {
76628082ab0SEugene Zelenko   SubsectionConversionVisitor() = default;
76792dcdda6SZachary Turner 
76892dcdda6SZachary Turner   Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override;
7691bf77620SZachary Turner   Error visitLines(DebugLinesSubsectionRef &Lines,
770a8cfc29cSZachary Turner                    const StringsAndChecksumsRef &State) override;
7711bf77620SZachary Turner   Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
772a8cfc29cSZachary Turner                            const StringsAndChecksumsRef &State) override;
7731bf77620SZachary Turner   Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
774a8cfc29cSZachary Turner                           const StringsAndChecksumsRef &State) override;
7751bf77620SZachary Turner   Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums,
776a8cfc29cSZachary Turner                                 const StringsAndChecksumsRef &State) override;
7771bf77620SZachary Turner   Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees,
778a8cfc29cSZachary Turner                                 const StringsAndChecksumsRef &State) override;
779deb39130SZachary Turner   Error visitStringTable(DebugStringTableSubsectionRef &ST,
780a8cfc29cSZachary Turner                          const StringsAndChecksumsRef &State) override;
781deb39130SZachary Turner   Error visitSymbols(DebugSymbolsSubsectionRef &Symbols,
782a8cfc29cSZachary Turner                      const StringsAndChecksumsRef &State) override;
783deb39130SZachary Turner   Error visitFrameData(DebugFrameDataSubsectionRef &Symbols,
784a8cfc29cSZachary Turner                        const StringsAndChecksumsRef &State) override;
7853226fe95SZachary Turner   Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols,
786a8cfc29cSZachary Turner                             const StringsAndChecksumsRef &State) override;
78792dcdda6SZachary Turner 
78892dcdda6SZachary Turner   YAMLDebugSubsection Subsection;
78992dcdda6SZachary Turner };
79092dcdda6SZachary Turner 
79128082ab0SEugene Zelenko } // end anonymous namespace
79228082ab0SEugene Zelenko 
visitUnknown(DebugUnknownSubsectionRef & Unknown)79392dcdda6SZachary Turner Error SubsectionConversionVisitor::visitUnknown(
79492dcdda6SZachary Turner     DebugUnknownSubsectionRef &Unknown) {
79592dcdda6SZachary Turner   return make_error<CodeViewError>(cv_error_code::operation_unsupported);
79692dcdda6SZachary Turner }
79792dcdda6SZachary Turner 
visitLines(DebugLinesSubsectionRef & Lines,const StringsAndChecksumsRef & State)7981bf77620SZachary Turner Error SubsectionConversionVisitor::visitLines(
799a8cfc29cSZachary Turner     DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) {
8001bf77620SZachary Turner   auto Result = YAMLLinesSubsection::fromCodeViewSubsection(
8011bf77620SZachary Turner       State.strings(), State.checksums(), Lines);
80292dcdda6SZachary Turner   if (!Result)
80392dcdda6SZachary Turner     return Result.takeError();
80492dcdda6SZachary Turner   Subsection.Subsection = *Result;
80592dcdda6SZachary Turner   return Error::success();
80692dcdda6SZachary Turner }
80792dcdda6SZachary Turner 
visitFileChecksums(DebugChecksumsSubsectionRef & Checksums,const StringsAndChecksumsRef & State)80892dcdda6SZachary Turner Error SubsectionConversionVisitor::visitFileChecksums(
809a8cfc29cSZachary Turner     DebugChecksumsSubsectionRef &Checksums,
810a8cfc29cSZachary Turner     const StringsAndChecksumsRef &State) {
8111bf77620SZachary Turner   auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(),
8121bf77620SZachary Turner                                                                 Checksums);
81392dcdda6SZachary Turner   if (!Result)
81492dcdda6SZachary Turner     return Result.takeError();
81592dcdda6SZachary Turner   Subsection.Subsection = *Result;
81692dcdda6SZachary Turner   return Error::success();
81792dcdda6SZachary Turner }
81892dcdda6SZachary Turner 
visitInlineeLines(DebugInlineeLinesSubsectionRef & Inlinees,const StringsAndChecksumsRef & State)81992dcdda6SZachary Turner Error SubsectionConversionVisitor::visitInlineeLines(
8201bf77620SZachary Turner     DebugInlineeLinesSubsectionRef &Inlinees,
821a8cfc29cSZachary Turner     const StringsAndChecksumsRef &State) {
82292dcdda6SZachary Turner   auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection(
8231bf77620SZachary Turner       State.strings(), State.checksums(), Inlinees);
82492dcdda6SZachary Turner   if (!Result)
82592dcdda6SZachary Turner     return Result.takeError();
82692dcdda6SZachary Turner   Subsection.Subsection = *Result;
82792dcdda6SZachary Turner   return Error::success();
82892dcdda6SZachary Turner }
829349c18f8SZachary Turner 
visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef & Exports,const StringsAndChecksumsRef & State)830349c18f8SZachary Turner Error SubsectionConversionVisitor::visitCrossModuleExports(
8311bf77620SZachary Turner     DebugCrossModuleExportsSubsectionRef &Exports,
832a8cfc29cSZachary Turner     const StringsAndChecksumsRef &State) {
833349c18f8SZachary Turner   auto Result =
834349c18f8SZachary Turner       YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports);
835349c18f8SZachary Turner   if (!Result)
836349c18f8SZachary Turner     return Result.takeError();
837349c18f8SZachary Turner   Subsection.Subsection = *Result;
838349c18f8SZachary Turner   return Error::success();
839349c18f8SZachary Turner }
840349c18f8SZachary Turner 
visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef & Imports,const StringsAndChecksumsRef & State)841349c18f8SZachary Turner Error SubsectionConversionVisitor::visitCrossModuleImports(
8421bf77620SZachary Turner     DebugCrossModuleImportsSubsectionRef &Imports,
843a8cfc29cSZachary Turner     const StringsAndChecksumsRef &State) {
844349c18f8SZachary Turner   auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
8451bf77620SZachary Turner       State.strings(), Imports);
846349c18f8SZachary Turner   if (!Result)
847349c18f8SZachary Turner     return Result.takeError();
848349c18f8SZachary Turner   Subsection.Subsection = *Result;
849349c18f8SZachary Turner   return Error::success();
850349c18f8SZachary Turner }
851deb39130SZachary Turner 
visitStringTable(DebugStringTableSubsectionRef & Strings,const StringsAndChecksumsRef & State)852deb39130SZachary Turner Error SubsectionConversionVisitor::visitStringTable(
853a8cfc29cSZachary Turner     DebugStringTableSubsectionRef &Strings,
854a8cfc29cSZachary Turner     const StringsAndChecksumsRef &State) {
855deb39130SZachary Turner   auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings);
856deb39130SZachary Turner   if (!Result)
857deb39130SZachary Turner     return Result.takeError();
858deb39130SZachary Turner   Subsection.Subsection = *Result;
859deb39130SZachary Turner   return Error::success();
860deb39130SZachary Turner }
861deb39130SZachary Turner 
visitSymbols(DebugSymbolsSubsectionRef & Symbols,const StringsAndChecksumsRef & State)862deb39130SZachary Turner Error SubsectionConversionVisitor::visitSymbols(
863a8cfc29cSZachary Turner     DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) {
864deb39130SZachary Turner   auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols);
865deb39130SZachary Turner   if (!Result)
866deb39130SZachary Turner     return Result.takeError();
867deb39130SZachary Turner   Subsection.Subsection = *Result;
868deb39130SZachary Turner   return Error::success();
869deb39130SZachary Turner }
870deb39130SZachary Turner 
visitFrameData(DebugFrameDataSubsectionRef & Frames,const StringsAndChecksumsRef & State)871deb39130SZachary Turner Error SubsectionConversionVisitor::visitFrameData(
872a8cfc29cSZachary Turner     DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) {
873deb39130SZachary Turner   auto Result =
874deb39130SZachary Turner       YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames);
875deb39130SZachary Turner   if (!Result)
876deb39130SZachary Turner     return Result.takeError();
877deb39130SZachary Turner   Subsection.Subsection = *Result;
878deb39130SZachary Turner   return Error::success();
879deb39130SZachary Turner }
8803226fe95SZachary Turner 
visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef & RVAs,const StringsAndChecksumsRef & State)8813226fe95SZachary Turner Error SubsectionConversionVisitor::visitCOFFSymbolRVAs(
882a8cfc29cSZachary Turner     DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) {
8833226fe95SZachary Turner   auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs);
8843226fe95SZachary Turner   if (!Result)
8853226fe95SZachary Turner     return Result.takeError();
8863226fe95SZachary Turner   Subsection.Subsection = *Result;
8873226fe95SZachary Turner   return Error::success();
8883226fe95SZachary Turner }
88992dcdda6SZachary Turner 
890a8cfc29cSZachary Turner Expected<YAMLDebugSubsection>
fromCodeViewSubection(const StringsAndChecksumsRef & SC,const DebugSubsectionRecord & SS)891a8cfc29cSZachary Turner YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC,
89292dcdda6SZachary Turner                                            const DebugSubsectionRecord &SS) {
8931bf77620SZachary Turner   SubsectionConversionVisitor V;
894a8cfc29cSZachary Turner   if (auto EC = visitDebugSubsection(SS, V, SC))
895*c55cf4afSBill Wendling     return std::move(EC);
89692dcdda6SZachary Turner 
89792dcdda6SZachary Turner   return V.Subsection;
8981b88f4f3SZachary Turner }
899deb39130SZachary Turner 
900a8cfc29cSZachary Turner std::vector<YAMLDebugSubsection>
fromDebugS(ArrayRef<uint8_t> Data,const StringsAndChecksumsRef & SC)901a8cfc29cSZachary Turner llvm::CodeViewYAML::fromDebugS(ArrayRef<uint8_t> Data,
902a8cfc29cSZachary Turner                                const StringsAndChecksumsRef &SC) {
903a8cfc29cSZachary Turner   BinaryStreamReader Reader(Data, support::little);
904a8cfc29cSZachary Turner   uint32_t Magic;
905a8cfc29cSZachary Turner 
906a8cfc29cSZachary Turner   ExitOnError Err("Invalid .debug$S section!");
907a8cfc29cSZachary Turner   Err(Reader.readInteger(Magic));
908a8cfc29cSZachary Turner   assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!");
909a8cfc29cSZachary Turner 
910a8cfc29cSZachary Turner   DebugSubsectionArray Subsections;
911a8cfc29cSZachary Turner   Err(Reader.readArray(Subsections, Reader.bytesRemaining()));
912a8cfc29cSZachary Turner 
913a8cfc29cSZachary Turner   std::vector<YAMLDebugSubsection> Result;
914a8cfc29cSZachary Turner 
915a8cfc29cSZachary Turner   for (const auto &SS : Subsections) {
916a8cfc29cSZachary Turner     auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS));
917a8cfc29cSZachary Turner     Result.push_back(YamlSS);
918a8cfc29cSZachary Turner   }
919a8cfc29cSZachary Turner   return Result;
920a8cfc29cSZachary Turner }
921a8cfc29cSZachary Turner 
initializeStringsAndChecksums(ArrayRef<YAMLDebugSubsection> Sections,codeview::StringsAndChecksums & SC)922a8cfc29cSZachary Turner void llvm::CodeViewYAML::initializeStringsAndChecksums(
923a8cfc29cSZachary Turner     ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC) {
924a8cfc29cSZachary Turner   // String Table and Checksums subsections don't use the allocator.
925a8cfc29cSZachary Turner   BumpPtrAllocator Allocator;
926a8cfc29cSZachary Turner 
927a8cfc29cSZachary Turner   // It's possible for checksums and strings to even appear in different debug$S
928a8cfc29cSZachary Turner   // sections, so we have to make this a stateful function that can build up
929a8cfc29cSZachary Turner   // the strings and checksums field over multiple iterations.
930a8cfc29cSZachary Turner 
931a8cfc29cSZachary Turner   // File Checksums require the string table, but may become before it, so we
932a8cfc29cSZachary Turner   // have to scan for strings first, then scan for checksums again from the
933a8cfc29cSZachary Turner   // beginning.
934a8cfc29cSZachary Turner   if (!SC.hasStrings()) {
935deb39130SZachary Turner     for (const auto &SS : Sections) {
936deb39130SZachary Turner       if (SS.Subsection->Kind != DebugSubsectionKind::StringTable)
937deb39130SZachary Turner         continue;
938deb39130SZachary Turner 
939a8cfc29cSZachary Turner       auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
940a8cfc29cSZachary Turner       SC.setStrings(
941a8cfc29cSZachary Turner           std::static_pointer_cast<DebugStringTableSubsection>(Result));
942a8cfc29cSZachary Turner       break;
943deb39130SZachary Turner     }
944a8cfc29cSZachary Turner   }
945a8cfc29cSZachary Turner 
946a8cfc29cSZachary Turner   if (SC.hasStrings() && !SC.hasChecksums()) {
947a8cfc29cSZachary Turner     for (const auto &SS : Sections) {
948a8cfc29cSZachary Turner       if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums)
949a8cfc29cSZachary Turner         continue;
950a8cfc29cSZachary Turner 
951a8cfc29cSZachary Turner       auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
952a8cfc29cSZachary Turner       SC.setChecksums(
953a8cfc29cSZachary Turner           std::static_pointer_cast<DebugChecksumsSubsection>(Result));
954a8cfc29cSZachary Turner       break;
955a8cfc29cSZachary Turner     }
956a8cfc29cSZachary Turner   }
957deb39130SZachary Turner }
958