Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:40

0001 //===- SymbolDeserializer.h -------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLDESERIALIZER_H
0010 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDESERIALIZER_H
0011 
0012 #include "llvm/ADT/ArrayRef.h"
0013 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
0014 #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
0015 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
0016 #include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h"
0017 #include "llvm/Support/BinaryByteStream.h"
0018 #include "llvm/Support/BinaryStreamReader.h"
0019 #include "llvm/Support/Error.h"
0020 
0021 namespace llvm {
0022 namespace codeview {
0023 class SymbolVisitorDelegate;
0024 class SymbolDeserializer : public SymbolVisitorCallbacks {
0025   struct MappingInfo {
0026     MappingInfo(ArrayRef<uint8_t> RecordData, CodeViewContainer Container)
0027         : Stream(RecordData, llvm::endianness::little), Reader(Stream),
0028           Mapping(Reader, Container) {}
0029 
0030     BinaryByteStream Stream;
0031     BinaryStreamReader Reader;
0032     SymbolRecordMapping Mapping;
0033   };
0034 
0035 public:
0036   template <typename T> static Error deserializeAs(CVSymbol Symbol, T &Record) {
0037     // If we're just deserializing one record, then don't worry about alignment
0038     // as there's nothing that comes after.
0039     SymbolDeserializer S(nullptr, CodeViewContainer::ObjectFile);
0040     if (auto EC = S.visitSymbolBegin(Symbol))
0041       return EC;
0042     if (auto EC = S.visitKnownRecord(Symbol, Record))
0043       return EC;
0044     if (auto EC = S.visitSymbolEnd(Symbol))
0045       return EC;
0046     return Error::success();
0047   }
0048   template <typename T> static Expected<T> deserializeAs(CVSymbol Symbol) {
0049     T Record(static_cast<SymbolRecordKind>(Symbol.kind()));
0050     if (auto EC = deserializeAs<T>(Symbol, Record))
0051       return std::move(EC);
0052     return Record;
0053   }
0054 
0055   explicit SymbolDeserializer(SymbolVisitorDelegate *Delegate,
0056                               CodeViewContainer Container)
0057       : Delegate(Delegate), Container(Container) {}
0058 
0059   Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override {
0060     return visitSymbolBegin(Record);
0061   }
0062 
0063   Error visitSymbolBegin(CVSymbol &Record) override {
0064     assert(!Mapping && "Already in a symbol mapping!");
0065     Mapping = std::make_unique<MappingInfo>(Record.content(), Container);
0066     return Mapping->Mapping.visitSymbolBegin(Record);
0067   }
0068   Error visitSymbolEnd(CVSymbol &Record) override {
0069     assert(Mapping && "Not in a symbol mapping!");
0070     auto EC = Mapping->Mapping.visitSymbolEnd(Record);
0071     Mapping.reset();
0072     return EC;
0073   }
0074 
0075 #define SYMBOL_RECORD(EnumName, EnumVal, Name)                                 \
0076   Error visitKnownRecord(CVSymbol &CVR, Name &Record) override {               \
0077     return visitKnownRecordImpl(CVR, Record);                                  \
0078   }
0079 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
0080 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
0081 
0082 private:
0083   template <typename T> Error visitKnownRecordImpl(CVSymbol &CVR, T &Record) {
0084 
0085     Record.RecordOffset =
0086         Delegate ? Delegate->getRecordOffset(Mapping->Reader) : 0;
0087     if (auto EC = Mapping->Mapping.visitKnownRecord(CVR, Record))
0088       return EC;
0089     return Error::success();
0090   }
0091 
0092   SymbolVisitorDelegate *Delegate;
0093   CodeViewContainer Container;
0094   std::unique_ptr<MappingInfo> Mapping;
0095 };
0096 }
0097 }
0098 
0099 #endif