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

Generated by: LCOV version 1.13