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