LCOV - code coverage report
Current view: top level - lib/ObjectYAML - CodeViewYAMLSymbols.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 261 372 70.2 %
Date: 2018-06-17 00:07:59 Functions: 144 293 49.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
       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             : // This file defines classes for handling the YAML representation of CodeView
      11             : // Debug Info.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
      16             : #include "llvm/ADT/ArrayRef.h"
      17             : #include "llvm/ADT/StringRef.h"
      18             : #include "llvm/DebugInfo/CodeView/CodeView.h"
      19             : #include "llvm/DebugInfo/CodeView/CodeViewError.h"
      20             : #include "llvm/DebugInfo/CodeView/EnumTables.h"
      21             : #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
      22             : #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
      23             : #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
      24             : #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
      25             : #include "llvm/DebugInfo/CodeView/TypeIndex.h"
      26             : #include "llvm/ObjectYAML/YAML.h"
      27             : #include "llvm/Support/Allocator.h"
      28             : #include "llvm/Support/Error.h"
      29             : #include "llvm/Support/YAMLTraits.h"
      30             : #include <algorithm>
      31             : #include <cstdint>
      32             : #include <cstring>
      33             : #include <string>
      34             : #include <vector>
      35             : 
      36             : using namespace llvm;
      37             : using namespace llvm::codeview;
      38             : using namespace llvm::CodeViewYAML;
      39             : using namespace llvm::CodeViewYAML::detail;
      40             : using namespace llvm::yaml;
      41             : 
      42             : LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
      43             : LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
      44             : 
      45             : // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
      46             : LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
      47             : LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
      48             : 
      49             : LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
      50             : LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
      51             : 
      52             : LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
      53             : LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
      54             : LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
      55             : LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
      56             : LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
      57             : LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
      58             : LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
      59             : LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
      60             : LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
      61             : LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
      62             : LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
      63             : 
      64             : LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
      65             : 
      66             : LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
      67             : 
      68           0 : StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
      69           0 :   return ScalarTraits<StringRef>::input(S, V, T.value);
      70             : }
      71             : 
      72           0 : void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
      73             :                                     raw_ostream &R) {
      74           0 :   ScalarTraits<StringRef>::output(T.value, V, R);
      75           0 : }
      76             : 
      77         878 : void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
      78             :                                                       SymbolKind &Value) {
      79         878 :   auto SymbolNames = getSymbolTypeNames();
      80      345054 :   for (const auto &E : SymbolNames)
      81      516264 :     io.enumCase(Value, E.Name.str().c_str(), E.Value);
      82         878 : }
      83             : 
      84           0 : void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
      85             :                                                   CompileSym2Flags &Flags) {
      86           0 :   auto FlagNames = getCompileSym2FlagNames();
      87           0 :   for (const auto &E : FlagNames) {
      88           0 :     io.bitSetCase(Flags, E.Name.str().c_str(),
      89           0 :                   static_cast<CompileSym2Flags>(E.Value));
      90             :   }
      91           0 : }
      92             : 
      93          48 : void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
      94             :                                                   CompileSym3Flags &Flags) {
      95          48 :   auto FlagNames = getCompileSym3FlagNames();
      96        1200 :   for (const auto &E : FlagNames) {
      97        1152 :     io.bitSetCase(Flags, E.Name.str().c_str(),
      98         576 :                   static_cast<CompileSym3Flags>(E.Value));
      99             :   }
     100          48 : }
     101             : 
     102           0 : void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
     103           0 :   auto FlagNames = getExportSymFlagNames();
     104           0 :   for (const auto &E : FlagNames) {
     105           0 :     io.bitSetCase(Flags, E.Name.str().c_str(),
     106           0 :                   static_cast<ExportFlags>(E.Value));
     107             :   }
     108           0 : }
     109             : 
     110           0 : void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
     111           0 :   auto FlagNames = getProcSymFlagNames();
     112           0 :   for (const auto &E : FlagNames) {
     113           0 :     io.bitSetCase(Flags, E.Name.str().c_str(),
     114           0 :                   static_cast<PublicSymFlags>(E.Value));
     115             :   }
     116           0 : }
     117             : 
     118          28 : void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
     119          28 :   auto FlagNames = getLocalFlagNames();
     120         644 :   for (const auto &E : FlagNames) {
     121         616 :     io.bitSetCase(Flags, E.Name.str().c_str(),
     122         308 :                   static_cast<LocalSymFlags>(E.Value));
     123             :   }
     124          28 : }
     125             : 
     126          60 : void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
     127          60 :   auto FlagNames = getProcSymFlagNames();
     128        1020 :   for (const auto &E : FlagNames) {
     129         960 :     io.bitSetCase(Flags, E.Name.str().c_str(),
     130         480 :                   static_cast<ProcSymFlags>(E.Value));
     131             :   }
     132          60 : }
     133             : 
     134          48 : void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
     135             :     IO &io, FrameProcedureOptions &Flags) {
     136          48 :   auto FlagNames = getFrameProcSymFlagNames();
     137        1872 :   for (const auto &E : FlagNames) {
     138        1824 :     io.bitSetCase(Flags, E.Name.str().c_str(),
     139         912 :                   static_cast<FrameProcedureOptions>(E.Value));
     140             :   }
     141          48 : }
     142             : 
     143          48 : void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
     144          48 :   auto CpuNames = getCPUTypeNames();
     145        5712 :   for (const auto &E : CpuNames) {
     146        8496 :     io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
     147             :   }
     148          48 : }
     149             : 
     150          22 : void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
     151          22 :   auto RegNames = getRegisterNames();
     152        9834 :   for (const auto &E : RegNames) {
     153       14718 :     io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
     154             :   }
     155          22 :   io.enumFallback<Hex16>(Reg);
     156          22 : }
     157             : 
     158           5 : void ScalarEnumerationTraits<TrampolineType>::enumeration(
     159             :     IO &io, TrampolineType &Tramp) {
     160           5 :   auto TrampNames = getTrampolineNames();
     161          25 :   for (const auto &E : TrampNames) {
     162          20 :     io.enumCase(Tramp, E.Name.str().c_str(),
     163          10 :                 static_cast<TrampolineType>(E.Value));
     164             :   }
     165           5 : }
     166             : 
     167           1 : void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
     168             :                                                         ThunkOrdinal &Ord) {
     169           1 :   auto ThunkNames = getThunkOrdinalNames();
     170          15 :   for (const auto &E : ThunkNames) {
     171          21 :     io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
     172             :   }
     173           1 : }
     174             : 
     175           0 : void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
     176             :     IO &io, FrameCookieKind &FC) {
     177           0 :   auto ThunkNames = getFrameCookieKindNames();
     178           0 :   for (const auto &E : ThunkNames) {
     179           0 :     io.enumCase(FC, E.Name.str().c_str(),
     180           0 :                 static_cast<FrameCookieKind>(E.Value));
     181             :   }
     182           0 : }
     183             : 
     184             : namespace llvm {
     185             : namespace yaml {
     186             : template <> struct MappingTraits<LocalVariableAddrRange> {
     187          25 :   static void mapping(IO &io, LocalVariableAddrRange &Range) {
     188          25 :     io.mapRequired("OffsetStart", Range.OffsetStart);
     189          25 :     io.mapRequired("ISectStart", Range.ISectStart);
     190          25 :     io.mapRequired("Range", Range.Range);
     191          25 :   }
     192             : };
     193             : template <> struct MappingTraits<LocalVariableAddrGap> {
     194           1 :   static void mapping(IO &io, LocalVariableAddrGap &Gap) {
     195           1 :     io.mapRequired("GapStartOffset", Gap.GapStartOffset);
     196           1 :     io.mapRequired("Range", Gap.Range);
     197           1 :   }
     198             : };
     199             : } // namespace yaml
     200             : } // namespace llvm
     201             : 
     202             : namespace llvm {
     203             : namespace CodeViewYAML {
     204             : namespace detail {
     205             : 
     206             : struct SymbolRecordBase {
     207             :   codeview::SymbolKind Kind;
     208             : 
     209         878 :   explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
     210             :   virtual ~SymbolRecordBase() = default;
     211             : 
     212             :   virtual void map(yaml::IO &io) = 0;
     213             :   virtual codeview::CVSymbol
     214             :   toCodeViewSymbol(BumpPtrAllocator &Allocator,
     215             :                    CodeViewContainer Container) const = 0;
     216             :   virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
     217             : };
     218             : 
     219         911 : template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
     220         876 :   explicit SymbolRecordImpl(codeview::SymbolKind K)
     221         876 :       : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
     222             : 
     223             :   void map(yaml::IO &io) override;
     224             : 
     225             :   codeview::CVSymbol
     226         369 :   toCodeViewSymbol(BumpPtrAllocator &Allocator,
     227             :                    CodeViewContainer Container) const override {
     228         369 :     return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
     229             :   }
     230             : 
     231         279 :   Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
     232         558 :     return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
     233             :   }
     234             : 
     235             :   mutable T Symbol;
     236             : };
     237             : 
     238           4 : struct UnknownSymbolRecord : public SymbolRecordBase {
     239           4 :   explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
     240             : 
     241             :   void map(yaml::IO &io) override;
     242             : 
     243           1 :   CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
     244             :                             CodeViewContainer Container) const override {
     245             :     RecordPrefix Prefix;
     246           2 :     uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
     247           1 :     Prefix.RecordKind = Kind;
     248           1 :     Prefix.RecordLen = TotalLen - 2;
     249           1 :     uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
     250           1 :     ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
     251           2 :     ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
     252           2 :     return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen));
     253             :   }
     254             : 
     255           1 :   Error fromCodeViewSymbol(CVSymbol CVS) override {
     256           1 :     this->Kind = CVS.kind();
     257           2 :     Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
     258           1 :     return Error::success();
     259             :   }
     260             : 
     261             :   std::vector<uint8_t> Data;
     262             : };
     263             : 
     264          66 : template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
     265             : 
     266           2 : void UnknownSymbolRecord::map(yaml::IO &io) {
     267           2 :   yaml::BinaryRef Binary;
     268           2 :   if (io.outputting())
     269           1 :     Binary = yaml::BinaryRef(Data);
     270             :   io.mapRequired("Data", Binary);
     271           2 :   if (!io.outputting()) {
     272             :     std::string Str;
     273           1 :     raw_string_ostream OS(Str);
     274           1 :     Binary.writeAsBinary(OS);
     275             :     OS.flush();
     276           1 :     Data.assign(Str.begin(), Str.end());
     277             :   }
     278           2 : }
     279             : 
     280           1 : template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
     281           1 :   IO.mapRequired("Parent", Symbol.Parent);
     282           1 :   IO.mapRequired("End", Symbol.End);
     283           1 :   IO.mapRequired("Next", Symbol.Next);
     284           1 :   IO.mapRequired("Off", Symbol.Offset);
     285           1 :   IO.mapRequired("Seg", Symbol.Segment);
     286           1 :   IO.mapRequired("Len", Symbol.Length);
     287           1 :   IO.mapRequired("Ordinal", Symbol.Thunk);
     288           1 : }
     289             : 
     290           5 : template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
     291           5 :   IO.mapRequired("Type", Symbol.Type);
     292           5 :   IO.mapRequired("Size", Symbol.Size);
     293           5 :   IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
     294           5 :   IO.mapRequired("TargetOff", Symbol.TargetOffset);
     295           5 :   IO.mapRequired("ThunkSection", Symbol.ThunkSection);
     296           5 :   IO.mapRequired("TargetSection", Symbol.TargetSection);
     297           5 : }
     298             : 
     299          20 : template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
     300          20 :   IO.mapRequired("SectionNumber", Symbol.SectionNumber);
     301          20 :   IO.mapRequired("Alignment", Symbol.Alignment);
     302          20 :   IO.mapRequired("Rva", Symbol.Rva);
     303          20 :   IO.mapRequired("Length", Symbol.Length);
     304          20 :   IO.mapRequired("Characteristics", Symbol.Characteristics);
     305          20 :   IO.mapRequired("Name", Symbol.Name);
     306          20 : }
     307             : 
     308          25 : template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
     309          25 :   IO.mapRequired("Size", Symbol.Size);
     310          25 :   IO.mapRequired("Characteristics", Symbol.Characteristics);
     311          25 :   IO.mapRequired("Offset", Symbol.Offset);
     312          25 :   IO.mapRequired("Segment", Symbol.Segment);
     313          25 :   IO.mapRequired("Name", Symbol.Name);
     314          25 : }
     315             : 
     316           0 : template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
     317           0 :   IO.mapRequired("Ordinal", Symbol.Ordinal);
     318           0 :   IO.mapRequired("Flags", Symbol.Flags);
     319           0 :   IO.mapRequired("Name", Symbol.Name);
     320           0 : }
     321             : 
     322          60 : template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
     323         120 :   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
     324         120 :   IO.mapOptional("PtrEnd", Symbol.End, 0U);
     325         120 :   IO.mapOptional("PtrNext", Symbol.Next, 0U);
     326          60 :   IO.mapRequired("CodeSize", Symbol.CodeSize);
     327          60 :   IO.mapRequired("DbgStart", Symbol.DbgStart);
     328          60 :   IO.mapRequired("DbgEnd", Symbol.DbgEnd);
     329          60 :   IO.mapRequired("FunctionType", Symbol.FunctionType);
     330         120 :   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
     331         120 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     332          60 :   IO.mapRequired("Flags", Symbol.Flags);
     333          60 :   IO.mapRequired("DisplayName", Symbol.Name);
     334          60 : }
     335             : 
     336           0 : template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
     337           0 :   IO.mapRequired("Type", Symbol.Index);
     338           0 :   IO.mapRequired("Seg", Symbol.Register);
     339           0 :   IO.mapRequired("Name", Symbol.Name);
     340           0 : }
     341             : 
     342           0 : template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
     343           0 :   IO.mapRequired("Flags", Symbol.Flags);
     344           0 :   IO.mapOptional("Offset", Symbol.Offset, 0U);
     345           0 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     346           0 :   IO.mapRequired("Name", Symbol.Name);
     347           0 : }
     348             : 
     349           0 : template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
     350           0 :   IO.mapRequired("SumName", Symbol.SumName);
     351           0 :   IO.mapRequired("SymOffset", Symbol.SymOffset);
     352           0 :   IO.mapRequired("Mod", Symbol.Module);
     353           0 :   IO.mapRequired("Name", Symbol.Name);
     354           0 : }
     355             : 
     356           5 : template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
     357           5 :   IO.mapRequired("Entries", Symbol.Fields);
     358           5 : }
     359             : 
     360           1 : template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
     361           2 :   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
     362           2 :   IO.mapOptional("PtrEnd", Symbol.End, 0U);
     363           1 :   IO.mapRequired("Inlinee", Symbol.Inlinee);
     364             :   // TODO: The binary annotations
     365           1 : }
     366             : 
     367          25 : template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
     368          25 :   IO.mapRequired("Type", Symbol.Type);
     369          25 :   IO.mapRequired("Flags", Symbol.Flags);
     370             : 
     371          25 :   IO.mapRequired("VarName", Symbol.Name);
     372          25 : }
     373             : 
     374           0 : template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
     375           0 :   IO.mapRequired("Program", Symbol.Program);
     376           0 :   IO.mapRequired("Range", Symbol.Range);
     377           0 :   IO.mapRequired("Gaps", Symbol.Gaps);
     378           0 : }
     379             : 
     380           0 : template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
     381           0 :   IO.mapRequired("Program", Symbol.Program);
     382           0 :   IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
     383           0 :   IO.mapRequired("Range", Symbol.Range);
     384           0 :   IO.mapRequired("Gaps", Symbol.Gaps);
     385           0 : }
     386             : 
     387           9 : template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
     388           9 :   IO.mapRequired("Register", Symbol.Hdr.Register);
     389           9 :   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
     390           9 :   IO.mapRequired("Range", Symbol.Range);
     391           9 :   IO.mapRequired("Gaps", Symbol.Gaps);
     392           9 : }
     393             : 
     394           0 : template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
     395           0 :   IO.mapRequired("Offset", Symbol.Offset);
     396           0 :   IO.mapRequired("Range", Symbol.Range);
     397           0 :   IO.mapRequired("Gaps", Symbol.Gaps);
     398           0 : }
     399             : 
     400           0 : template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
     401           0 :   IO.mapRequired("Register", Symbol.Hdr.Register);
     402           0 :   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
     403           0 :   IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
     404           0 :   IO.mapRequired("Range", Symbol.Range);
     405           0 :   IO.mapRequired("Gaps", Symbol.Gaps);
     406           0 : }
     407             : 
     408             : template <>
     409           4 : void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
     410           4 :   IO.mapRequired("Register", Symbol.Offset);
     411           4 : }
     412             : 
     413          16 : template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
     414          16 :   IO.mapRequired("Register", Symbol.Hdr.Register);
     415          16 :   IO.mapRequired("Flags", Symbol.Hdr.Flags);
     416          16 :   IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
     417          16 :   IO.mapRequired("Range", Symbol.Range);
     418          16 :   IO.mapRequired("Gaps", Symbol.Gaps);
     419          16 : }
     420             : 
     421           4 : template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
     422           8 :   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
     423           8 :   IO.mapOptional("PtrEnd", Symbol.End, 0U);
     424           4 :   IO.mapRequired("CodeSize", Symbol.CodeSize);
     425           8 :   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
     426           8 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     427           4 :   IO.mapRequired("BlockName", Symbol.Name);
     428           4 : }
     429             : 
     430           0 : template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
     431           0 :   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
     432           0 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     433           0 :   IO.mapRequired("Flags", Symbol.Flags);
     434             :   IO.mapRequired("Flags", Symbol.Flags);
     435           0 :   IO.mapRequired("DisplayName", Symbol.Name);
     436           0 : }
     437             : 
     438          46 : template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
     439          46 :   IO.mapRequired("Signature", Symbol.Signature);
     440          46 :   IO.mapRequired("ObjectName", Symbol.Name);
     441          46 : }
     442             : 
     443           0 : template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
     444           0 :   IO.mapRequired("Flags", Symbol.Flags);
     445           0 :   IO.mapRequired("Machine", Symbol.Machine);
     446           0 :   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
     447           0 :   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
     448           0 :   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
     449           0 :   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
     450           0 :   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
     451           0 :   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
     452           0 :   IO.mapRequired("Version", Symbol.Version);
     453           0 : }
     454             : 
     455          48 : template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
     456          48 :   IO.mapRequired("Flags", Symbol.Flags);
     457          48 :   IO.mapRequired("Machine", Symbol.Machine);
     458          48 :   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
     459          48 :   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
     460          48 :   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
     461          48 :   IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
     462          48 :   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
     463          48 :   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
     464          48 :   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
     465          48 :   IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
     466          48 :   IO.mapRequired("Version", Symbol.Version);
     467          48 : }
     468             : 
     469          48 : template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
     470          48 :   IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
     471          48 :   IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
     472          48 :   IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
     473          48 :   IO.mapRequired("BytesOfCalleeSavedRegisters",
     474             :                  Symbol.BytesOfCalleeSavedRegisters);
     475          48 :   IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
     476          48 :   IO.mapRequired("SectionIdOfExceptionHandler",
     477             :                  Symbol.SectionIdOfExceptionHandler);
     478          48 :   IO.mapRequired("Flags", Symbol.Flags);
     479          48 : }
     480             : 
     481           0 : template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
     482           0 :   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
     483           0 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     484           0 :   IO.mapRequired("Type", Symbol.Type);
     485           0 : }
     486             : 
     487           3 : template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
     488           3 :   IO.mapRequired("Index", Symbol.Index);
     489           3 :   IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
     490           3 :   IO.mapRequired("Flags", Symbol.Flags);
     491           3 :   IO.mapRequired("Name", Symbol.Name);
     492           3 : }
     493             : 
     494           1 : template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
     495           2 :   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
     496           2 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     497           1 :   IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
     498           1 :   IO.mapRequired("Type", Symbol.Type);
     499           1 : }
     500             : 
     501           0 : template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
     502           0 :   IO.mapRequired("Register", Symbol.Register);
     503           0 :   IO.mapRequired("CookieKind", Symbol.CookieKind);
     504           0 :   IO.mapRequired("Flags", Symbol.Flags);
     505           0 : }
     506             : 
     507           4 : template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
     508           4 :   IO.mapRequired("FuncID", Symbol.Indices);
     509           4 : }
     510             : 
     511         405 : template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
     512         405 :   IO.mapRequired("Type", Symbol.Type);
     513         405 :   IO.mapRequired("UDTName", Symbol.Name);
     514         405 : }
     515             : 
     516          36 : template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
     517          36 :   IO.mapRequired("BuildId", Symbol.BuildId);
     518          36 : }
     519             : 
     520           0 : template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
     521           0 :   IO.mapRequired("Offset", Symbol.Offset);
     522           0 :   IO.mapRequired("Type", Symbol.Type);
     523           0 :   IO.mapRequired("VarName", Symbol.Name);
     524           0 : }
     525             : 
     526          22 : template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
     527          22 :   IO.mapRequired("Offset", Symbol.Offset);
     528          22 :   IO.mapRequired("Type", Symbol.Type);
     529          22 :   IO.mapRequired("Register", Symbol.Register);
     530          22 :   IO.mapRequired("VarName", Symbol.Name);
     531          22 : }
     532             : 
     533           0 : template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
     534           0 :   IO.mapRequired("Type", Symbol.Type);
     535           0 :   IO.mapRequired("Value", Symbol.Value);
     536           0 :   IO.mapRequired("Name", Symbol.Name);
     537           0 : }
     538             : 
     539          21 : template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
     540          21 :   IO.mapRequired("Type", Symbol.Type);
     541          42 :   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
     542          42 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     543          21 :   IO.mapRequired("DisplayName", Symbol.Name);
     544          21 : }
     545             : 
     546           1 : template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
     547           1 :   IO.mapRequired("Type", Symbol.Type);
     548           2 :   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
     549           2 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     550           1 :   IO.mapRequired("DisplayName", Symbol.Name);
     551           1 : }
     552             : 
     553             : } // end namespace detail
     554             : } // end namespace CodeViewYAML
     555             : } // end namespace llvm
     556             : 
     557         370 : CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
     558             :     BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
     559         370 :   return Symbol->toCodeViewSymbol(Allocator, Container);
     560             : }
     561             : 
     562             : namespace llvm {
     563             : namespace yaml {
     564             : 
     565             : template <> struct MappingTraits<SymbolRecordBase> {
     566         878 :   static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
     567             : };
     568             : 
     569             : } // end namespace yaml
     570             : } // end namespace llvm
     571             : 
     572             : template <typename SymbolType>
     573             : static inline Expected<CodeViewYAML::SymbolRecord>
     574         280 : fromCodeViewSymbolImpl(CVSymbol Symbol) {
     575         280 :   CodeViewYAML::SymbolRecord Result;
     576             : 
     577         560 :   auto Impl = std::make_shared<SymbolType>(Symbol.kind());
     578         840 :   if (auto EC = Impl->fromCodeViewSymbol(Symbol))
     579             :     return std::move(EC);
     580             :   Result.Symbol = Impl;
     581             :   return Result;
     582             : }
     583             : 
     584             : Expected<CodeViewYAML::SymbolRecord>
     585         280 : CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
     586             : #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
     587             :   case EnumName:                                                               \
     588             :     return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
     589             : #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
     590             :   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
     591         280 :   switch (Symbol.kind()) {
     592             : #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
     593             :   default:
     594           1 :     return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
     595             :   }
     596             :   return make_error<CodeViewError>(cv_error_code::corrupt_record);
     597             : }
     598             : 
     599             : template <typename ConcreteType>
     600         878 : static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
     601             :                                 CodeViewYAML::SymbolRecord &Obj) {
     602         878 :   if (!IO.outputting())
     603         598 :     Obj.Symbol = std::make_shared<ConcreteType>(Kind);
     604             : 
     605             :   IO.mapRequired(Class, *Obj.Symbol);
     606         878 : }
     607             : 
     608         878 : void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
     609             :     IO &IO, CodeViewYAML::SymbolRecord &Obj) {
     610             :   SymbolKind Kind;
     611         878 :   if (IO.outputting())
     612         280 :     Kind = Obj.Symbol->Kind;
     613             :   IO.mapRequired("Kind", Kind);
     614             : 
     615             : #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
     616             :   case EnumName:                                                               \
     617             :     mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind,     \
     618             :                                                      Obj);                     \
     619             :     break;
     620             : #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
     621             :   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
     622         878 :   switch (Kind) {
     623             : #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
     624           2 :   default:
     625           2 :     mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
     626             :   }
     627         878 : }

Generated by: LCOV version 1.13