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