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