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