LCOV - code coverage report
Current view: top level - lib/ObjectYAML - CodeViewYAMLSymbols.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 508 853 59.6 %
Date: 2018-09-23 13:06:45 Functions: 123 224 54.9 %
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           0 : LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
      47           0 : 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         927 : void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
      78             :                                                       SymbolKind &Value) {
      79         927 :   auto SymbolNames = getSymbolTypeNames();
      80      182619 :   for (const auto &E : SymbolNames)
      81      545076 :     io.enumCase(Value, E.Name.str().c_str(), E.Value);
      82         927 : }
      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          54 : void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
      94             :                                                   CompileSym3Flags &Flags) {
      95          54 :   auto FlagNames = getCompileSym3FlagNames();
      96         702 :   for (const auto &E : FlagNames) {
      97        1296 :     io.bitSetCase(Flags, E.Name.str().c_str(),
      98         648 :                   static_cast<CompileSym3Flags>(E.Value));
      99             :   }
     100          54 : }
     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          32 : void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
     119          32 :   auto FlagNames = getLocalFlagNames();
     120         384 :   for (const auto &E : FlagNames) {
     121         704 :     io.bitSetCase(Flags, E.Name.str().c_str(),
     122         352 :                   static_cast<LocalSymFlags>(E.Value));
     123             :   }
     124          32 : }
     125             : 
     126          70 : void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
     127          70 :   auto FlagNames = getProcSymFlagNames();
     128         630 :   for (const auto &E : FlagNames) {
     129        1120 :     io.bitSetCase(Flags, E.Name.str().c_str(),
     130         560 :                   static_cast<ProcSymFlags>(E.Value));
     131             :   }
     132          70 : }
     133             : 
     134          53 : void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
     135             :     IO &io, FrameProcedureOptions &Flags) {
     136          53 :   auto FlagNames = getFrameProcSymFlagNames();
     137        1166 :   for (const auto &E : FlagNames) {
     138        2226 :     io.bitSetCase(Flags, E.Name.str().c_str(),
     139        1113 :                   static_cast<FrameProcedureOptions>(E.Value));
     140             :   }
     141          53 : }
     142             : 
     143          54 : void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
     144          54 :   auto CpuNames = getCPUTypeNames();
     145        3240 :   for (const auto &E : CpuNames) {
     146        9558 :     io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
     147             :   }
     148          54 : }
     149             : 
     150          22 : void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
     151          22 :   auto RegNames = getRegisterNames();
     152        6512 :   for (const auto &E : RegNames) {
     153       19470 :     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          15 :   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           8 :   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          29 :   static void mapping(IO &io, LocalVariableAddrRange &Range) {
     188          29 :     io.mapRequired("OffsetStart", Range.OffsetStart);
     189          29 :     io.mapRequired("ISectStart", Range.ISectStart);
     190          29 :     io.mapRequired("Range", Range.Range);
     191          29 :   }
     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         927 :   explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
     210           0 :   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             : template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
     220         925 :   explicit SymbolRecordImpl(codeview::SymbolKind K)
     221         925 :       : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
     222             : 
     223             :   void map(yaml::IO &io) override;
     224             : 
     225             :   codeview::CVSymbol
     226         410 :   toCodeViewSymbol(BumpPtrAllocator &Allocator,
     227             :                    CodeViewContainer Container) const override {
     228         410 :     return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
     229             :   }
     230           0 : 
     231             :   Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
     232           0 :     return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
     233             :   }
     234           4 : 
     235             :   mutable T Symbol;
     236           4 : };
     237             : 
     238           0 : struct UnknownSymbolRecord : public SymbolRecordBase {
     239             :   explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
     240           0 : 
     241             :   void map(yaml::IO &io) override;
     242          36 : 
     243             :   CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
     244          36 :                             CodeViewContainer Container) const override {
     245             :     RecordPrefix Prefix;
     246           0 :     uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
     247             :     Prefix.RecordKind = Kind;
     248           0 :     Prefix.RecordLen = TotalLen - 2;
     249             :     uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
     250          33 :     ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
     251             :     ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
     252          33 :     return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen));
     253             :   }
     254          47 : 
     255             :   Error fromCodeViewSymbol(CVSymbol CVS) override {
     256          47 :     this->Kind = CVS.kind();
     257             :     Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
     258           0 :     return Error::success();
     259             :   }
     260           0 : 
     261             :   std::vector<uint8_t> Data;
     262           3 : };
     263             : 
     264           3 : template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
     265             : 
     266           1 : void UnknownSymbolRecord::map(yaml::IO &io) {
     267             :   yaml::BinaryRef Binary;
     268           1 :   if (io.outputting())
     269             :     Binary = yaml::BinaryRef(Data);
     270           4 :   io.mapRequired("Data", Binary);
     271             :   if (!io.outputting()) {
     272           4 :     std::string Str;
     273             :     raw_string_ostream OS(Str);
     274           4 :     Binary.writeAsBinary(OS);
     275             :     OS.flush();
     276           4 :     Data.assign(Str.begin(), Str.end());
     277             :   }
     278          71 : }
     279             : 
     280          71 : template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
     281             :   IO.mapRequired("Parent", Symbol.Parent);
     282          30 :   IO.mapRequired("End", Symbol.End);
     283             :   IO.mapRequired("Next", Symbol.Next);
     284          30 :   IO.mapRequired("Off", Symbol.Offset);
     285             :   IO.mapRequired("Seg", Symbol.Segment);
     286           0 :   IO.mapRequired("Len", Symbol.Length);
     287             :   IO.mapRequired("Ordinal", Symbol.Thunk);
     288           0 : }
     289             : 
     290          22 : template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
     291             :   IO.mapRequired("Type", Symbol.Type);
     292          22 :   IO.mapRequired("Size", Symbol.Size);
     293             :   IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
     294           0 :   IO.mapRequired("TargetOff", Symbol.TargetOffset);
     295             :   IO.mapRequired("ThunkSection", Symbol.ThunkSection);
     296           0 :   IO.mapRequired("TargetSection", Symbol.TargetSection);
     297             : }
     298          13 : 
     299             : template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
     300          13 :   IO.mapRequired("SectionNumber", Symbol.SectionNumber);
     301             :   IO.mapRequired("Alignment", Symbol.Alignment);
     302           0 :   IO.mapRequired("Rva", Symbol.Rva);
     303             :   IO.mapRequired("Length", Symbol.Length);
     304           0 :   IO.mapRequired("Characteristics", Symbol.Characteristics);
     305             :   IO.mapRequired("Name", Symbol.Name);
     306           4 : }
     307             : 
     308           4 : template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
     309             :   IO.mapRequired("Size", Symbol.Size);
     310           1 :   IO.mapRequired("Characteristics", Symbol.Characteristics);
     311             :   IO.mapRequired("Offset", Symbol.Offset);
     312           1 :   IO.mapRequired("Segment", Symbol.Segment);
     313             :   IO.mapRequired("Name", Symbol.Name);
     314           1 : }
     315             : 
     316           1 : template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
     317             :   IO.mapRequired("Ordinal", Symbol.Ordinal);
     318           1 :   IO.mapRequired("Flags", Symbol.Flags);
     319             :   IO.mapRequired("Name", Symbol.Name);
     320           1 : }
     321             : 
     322           4 : template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
     323             :   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
     324           4 :   IO.mapOptional("PtrEnd", Symbol.End, 0U);
     325             :   IO.mapOptional("PtrNext", Symbol.Next, 0U);
     326           5 :   IO.mapRequired("CodeSize", Symbol.CodeSize);
     327             :   IO.mapRequired("DbgStart", Symbol.DbgStart);
     328           5 :   IO.mapRequired("DbgEnd", Symbol.DbgEnd);
     329             :   IO.mapRequired("FunctionType", Symbol.FunctionType);
     330           0 :   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
     331             :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     332           0 :   IO.mapRequired("Flags", Symbol.Flags);
     333             :   IO.mapRequired("DisplayName", Symbol.Name);
     334          49 : }
     335             : 
     336          49 : template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
     337             :   IO.mapRequired("Type", Symbol.Index);
     338           0 :   IO.mapRequired("Seg", Symbol.Register);
     339             :   IO.mapRequired("Name", Symbol.Name);
     340           0 : }
     341             : 
     342           0 : template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
     343             :   IO.mapRequired("Flags", Symbol.Flags);
     344           0 :   IO.mapOptional("Offset", Symbol.Offset, 0U);
     345             :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     346           0 :   IO.mapRequired("Name", Symbol.Name);
     347             : }
     348           0 : 
     349             : template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
     350          55 :   IO.mapRequired("SumName", Symbol.SumName);
     351             :   IO.mapRequired("SymOffset", Symbol.SymOffset);
     352          55 :   IO.mapRequired("Mod", Symbol.Module);
     353             :   IO.mapRequired("Name", Symbol.Name);
     354           1 : }
     355             : 
     356           1 : template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
     357             :   IO.mapRequired("Entries", Symbol.Fields);
     358           8 : }
     359             : 
     360           8 : template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
     361             :   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
     362           0 :   IO.mapOptional("PtrEnd", Symbol.End, 0U);
     363             :   IO.mapRequired("Inlinee", Symbol.Inlinee);
     364           0 :   // TODO: The binary annotations
     365             : }
     366           0 : 
     367             : template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
     368           0 :   IO.mapRequired("Type", Symbol.Type);
     369             :   IO.mapRequired("Flags", Symbol.Flags);
     370           9 : 
     371             :   IO.mapRequired("VarName", Symbol.Name);
     372           9 : }
     373             : 
     374           0 : template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
     375             :   IO.mapRequired("Program", Symbol.Program);
     376           0 :   IO.mapRequired("Range", Symbol.Range);
     377             :   IO.mapRequired("Gaps", Symbol.Gaps);
     378           0 : }
     379             : 
     380           0 : template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
     381             :   IO.mapRequired("Program", Symbol.Program);
     382           4 :   IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
     383             :   IO.mapRequired("Range", Symbol.Range);
     384           4 :   IO.mapRequired("Gaps", Symbol.Gaps);
     385             : }
     386             : 
     387         279 : template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
     388         279 :   IO.mapRequired("Register", Symbol.Hdr.Register);
     389             :   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
     390           0 :   IO.mapRequired("Range", Symbol.Range);
     391           0 :   IO.mapRequired("Gaps", Symbol.Gaps);
     392             : }
     393           0 : 
     394           0 : template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
     395             :   IO.mapRequired("Offset", Symbol.Offset);
     396           0 :   IO.mapRequired("Range", Symbol.Range);
     397           0 :   IO.mapRequired("Gaps", Symbol.Gaps);
     398             : }
     399           0 : 
     400           0 : template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
     401             :   IO.mapRequired("Register", Symbol.Hdr.Register);
     402           0 :   IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
     403           0 :   IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
     404             :   IO.mapRequired("Range", Symbol.Range);
     405           0 :   IO.mapRequired("Gaps", Symbol.Gaps);
     406           0 : }
     407             : 
     408           7 : template <>
     409           7 : void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
     410             :   IO.mapRequired("Register", Symbol.Offset);
     411           0 : }
     412           0 : 
     413             : template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
     414           4 :   IO.mapRequired("Register", Symbol.Hdr.Register);
     415           4 :   IO.mapRequired("Flags", Symbol.Hdr.Flags);
     416             :   IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
     417           0 :   IO.mapRequired("Range", Symbol.Range);
     418           0 :   IO.mapRequired("Gaps", Symbol.Gaps);
     419             : }
     420           0 : 
     421           0 : template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
     422             :   IO.mapOptional("PtrParent", Symbol.Parent, 0U);
     423           0 :   IO.mapOptional("PtrEnd", Symbol.End, 0U);
     424           0 :   IO.mapRequired("CodeSize", Symbol.CodeSize);
     425             :   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
     426           8 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     427           8 :   IO.mapRequired("BlockName", Symbol.Name);
     428             : }
     429           0 : 
     430           0 : template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
     431             :   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
     432          20 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     433          20 :   IO.mapRequired("Flags", Symbol.Flags);
     434             :   IO.mapRequired("Flags", Symbol.Flags);
     435          16 :   IO.mapRequired("DisplayName", Symbol.Name);
     436          16 : }
     437             : 
     438           4 : template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
     439           4 :   IO.mapRequired("Signature", Symbol.Signature);
     440             :   IO.mapRequired("ObjectName", Symbol.Name);
     441           0 : }
     442           0 : 
     443             : template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
     444           8 :   IO.mapRequired("Flags", Symbol.Flags);
     445           8 :   IO.mapRequired("Machine", Symbol.Machine);
     446             :   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
     447           0 :   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
     448           0 :   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
     449             :   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
     450           0 :   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
     451           0 :   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
     452             :   IO.mapRequired("Version", Symbol.Version);
     453           1 : }
     454           1 : 
     455             : template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
     456           4 :   IO.mapRequired("Flags", Symbol.Flags);
     457           4 :   IO.mapRequired("Machine", Symbol.Machine);
     458             :   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
     459           0 :   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
     460           0 :   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
     461             :   IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
     462           0 :   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
     463           0 :   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
     464             :   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
     465           0 :   IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
     466           0 :   IO.mapRequired("Version", Symbol.Version);
     467             : }
     468           6 : 
     469           6 : template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
     470             :   IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
     471         165 :   IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
     472         165 :   IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
     473             :   IO.mapRequired("BytesOfCalleeSavedRegisters",
     474           0 :                  Symbol.BytesOfCalleeSavedRegisters);
     475           0 :   IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
     476             :   IO.mapRequired("SectionIdOfExceptionHandler",
     477           0 :                  Symbol.SectionIdOfExceptionHandler);
     478           0 :   IO.mapRequired("Flags", Symbol.Flags);
     479             : }
     480           0 : 
     481           0 : template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
     482             :   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
     483           0 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     484           0 :   IO.mapRequired("Type", Symbol.Type);
     485             : }
     486           5 : 
     487           5 : template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
     488             :   IO.mapRequired("Index", Symbol.Index);
     489          12 :   IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
     490          12 :   IO.mapRequired("Flags", Symbol.Flags);
     491             :   IO.mapRequired("Name", Symbol.Name);
     492           0 : }
     493           0 : 
     494             : template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
     495          12 :   IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
     496          12 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     497             :   IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
     498           0 :   IO.mapRequired("Type", Symbol.Type);
     499           0 : }
     500             : 
     501           0 : template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
     502           0 :   IO.mapRequired("Register", Symbol.Register);
     503             :   IO.mapRequired("CookieKind", Symbol.CookieKind);
     504           7 :   IO.mapRequired("Flags", Symbol.Flags);
     505           7 : }
     506             : 
     507             : template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
     508             :   IO.mapRequired("FuncID", Symbol.Indices);
     509             : }
     510             : 
     511             : template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
     512           4 :   IO.mapRequired("Type", Symbol.Type);
     513             :   IO.mapRequired("UDTName", Symbol.Name);
     514             : }
     515             : 
     516           1 : template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
     517             :   IO.mapRequired("BuildId", Symbol.BuildId);
     518             : }
     519           1 : 
     520           1 : template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
     521           1 :   IO.mapRequired("Offset", Symbol.Offset);
     522           1 :   IO.mapRequired("Type", Symbol.Type);
     523           1 :   IO.mapRequired("VarName", Symbol.Name);
     524           2 : }
     525           2 : 
     526             : template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
     527             :   IO.mapRequired("Offset", Symbol.Offset);
     528           1 :   IO.mapRequired("Type", Symbol.Type);
     529           1 :   IO.mapRequired("Register", Symbol.Register);
     530           1 :   IO.mapRequired("VarName", Symbol.Name);
     531           1 : }
     532             : 
     533             : template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
     534             :   IO.mapRequired("Type", Symbol.Type);
     535             :   IO.mapRequired("Value", Symbol.Value);
     536             :   IO.mapRequired("Name", Symbol.Name);
     537          76 : }
     538             : 
     539           2 : template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
     540           2 :   IO.mapRequired("Type", Symbol.Type);
     541           2 :   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
     542           1 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     543             :   IO.mapRequired("DisplayName", Symbol.Name);
     544           2 : }
     545             : 
     546           1 : template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
     547           1 :   IO.mapRequired("Type", Symbol.Type);
     548             :   IO.mapOptional("Offset", Symbol.DataOffset, 0U);
     549           1 :   IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
     550             :   IO.mapRequired("DisplayName", Symbol.Name);
     551           2 : }
     552             : 
     553           1 : template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
     554           1 :   IO.mapRequired("Namespace", Symbol.Name);
     555           1 : }
     556           1 : 
     557           1 : } // end namespace detail
     558           1 : } // end namespace CodeViewYAML
     559           1 : } // end namespace llvm
     560           1 : 
     561           1 : CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
     562             :     BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
     563           5 :   return Symbol->toCodeViewSymbol(Allocator, Container);
     564           5 : }
     565           5 : 
     566           5 : namespace llvm {
     567           5 : namespace yaml {
     568           5 : 
     569           5 : template <> struct MappingTraits<SymbolRecordBase> {
     570           5 :   static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
     571             : };
     572          20 : 
     573          20 : } // end namespace yaml
     574          20 : } // end namespace llvm
     575          20 : 
     576          20 : template <typename SymbolType>
     577          20 : static inline Expected<CodeViewYAML::SymbolRecord>
     578          20 : fromCodeViewSymbolImpl(CVSymbol Symbol) {
     579          20 :   CodeViewYAML::SymbolRecord Result;
     580             : 
     581          25 :   auto Impl = std::make_shared<SymbolType>(Symbol.kind());
     582          25 :   if (auto EC = Impl->fromCodeViewSymbol(Symbol))
     583          25 :     return std::move(EC);
     584          25 :   Result.Symbol = Impl;
     585          25 :   return Result;
     586          25 : }
     587          25 : 
     588             : Expected<CodeViewYAML::SymbolRecord>
     589           0 : CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
     590           0 : #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
     591           0 :   case EnumName:                                                               \
     592           0 :     return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
     593           0 : #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
     594             :   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
     595          70 :   switch (Symbol.kind()) {
     596          70 : #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
     597          70 :   default:
     598          70 :     return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
     599          70 :   }
     600          70 :   return make_error<CodeViewError>(cv_error_code::corrupt_record);
     601          70 : }
     602          70 : 
     603          70 : template <typename ConcreteType>
     604          70 : static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
     605          70 :                                 CodeViewYAML::SymbolRecord &Obj) {
     606          70 :   if (!IO.outputting())
     607          70 :     Obj.Symbol = std::make_shared<ConcreteType>(Kind);
     608             : 
     609           0 :   IO.mapRequired(Class, *Obj.Symbol);
     610           0 : }
     611           0 : 
     612           0 : void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
     613           0 :     IO &IO, CodeViewYAML::SymbolRecord &Obj) {
     614             :   SymbolKind Kind;
     615           0 :   if (IO.outputting())
     616           0 :     Kind = Obj.Symbol->Kind;
     617           0 :   IO.mapRequired("Kind", Kind);
     618           0 : 
     619           0 : #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
     620           0 :   case EnumName:                                                               \
     621             :     mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind,     \
     622           0 :                                                      Obj);                     \
     623           0 :     break;
     624           0 : #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
     625           0 :   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
     626           0 :   switch (Kind) {
     627           0 : #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
     628             :   default:
     629           5 :     mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
     630           5 :   }
     631           5 : }

Generated by: LCOV version 1.13