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