Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- TypeDeserializer.h ---------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8.  
  9. #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
  10. #define LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
  11.  
  12. #include "llvm/ADT/ArrayRef.h"
  13. #include "llvm/ADT/STLExtras.h"
  14. #include "llvm/DebugInfo/CodeView/CodeView.h"
  15. #include "llvm/DebugInfo/CodeView/TypeRecord.h"
  16. #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
  17. #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
  18. #include "llvm/Support/BinaryByteStream.h"
  19. #include "llvm/Support/BinaryStreamReader.h"
  20. #include "llvm/Support/Error.h"
  21. #include <cassert>
  22. #include <cstdint>
  23. #include <memory>
  24.  
  25. namespace llvm {
  26. namespace codeview {
  27.  
  28. class TypeDeserializer : public TypeVisitorCallbacks {
  29.   struct MappingInfo {
  30.     explicit MappingInfo(ArrayRef<uint8_t> RecordData)
  31.         : Stream(RecordData, llvm::support::little), Reader(Stream),
  32.           Mapping(Reader) {}
  33.  
  34.     BinaryByteStream Stream;
  35.     BinaryStreamReader Reader;
  36.     TypeRecordMapping Mapping;
  37.   };
  38.  
  39. public:
  40.   TypeDeserializer() = default;
  41.  
  42.   template <typename T> static Error deserializeAs(CVType &CVT, T &Record) {
  43.     Record.Kind = static_cast<TypeRecordKind>(CVT.kind());
  44.     MappingInfo I(CVT.content());
  45.     if (auto EC = I.Mapping.visitTypeBegin(CVT))
  46.       return EC;
  47.     if (auto EC = I.Mapping.visitKnownRecord(CVT, Record))
  48.       return EC;
  49.     if (auto EC = I.Mapping.visitTypeEnd(CVT))
  50.       return EC;
  51.     return Error::success();
  52.   }
  53.  
  54.   template <typename T>
  55.   static Expected<T> deserializeAs(ArrayRef<uint8_t> Data) {
  56.     const RecordPrefix *Prefix =
  57.         reinterpret_cast<const RecordPrefix *>(Data.data());
  58.     TypeRecordKind K =
  59.         static_cast<TypeRecordKind>(uint16_t(Prefix->RecordKind));
  60.     T Record(K);
  61.     CVType CVT(Data);
  62.     if (auto EC = deserializeAs<T>(CVT, Record))
  63.       return std::move(EC);
  64.     return Record;
  65.   }
  66.  
  67.   Error visitTypeBegin(CVType &Record) override {
  68.     assert(!Mapping && "Already in a type mapping!");
  69.     Mapping = std::make_unique<MappingInfo>(Record.content());
  70.     return Mapping->Mapping.visitTypeBegin(Record);
  71.   }
  72.  
  73.   Error visitTypeBegin(CVType &Record, TypeIndex Index) override {
  74.     return visitTypeBegin(Record);
  75.   }
  76.  
  77.   Error visitTypeEnd(CVType &Record) override {
  78.     assert(Mapping && "Not in a type mapping!");
  79.     auto EC = Mapping->Mapping.visitTypeEnd(Record);
  80.     Mapping.reset();
  81.     return EC;
  82.   }
  83.  
  84. #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
  85.   Error visitKnownRecord(CVType &CVR, Name##Record &Record) override {         \
  86.     return visitKnownRecordImpl<Name##Record>(CVR, Record);                    \
  87.   }
  88. #define MEMBER_RECORD(EnumName, EnumVal, Name)
  89. #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
  90. #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
  91. #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
  92.  
  93. private:
  94.   template <typename RecordType>
  95.   Error visitKnownRecordImpl(CVType &CVR, RecordType &Record) {
  96.     return Mapping->Mapping.visitKnownRecord(CVR, Record);
  97.   }
  98.  
  99.   std::unique_ptr<MappingInfo> Mapping;
  100. };
  101.  
  102. class FieldListDeserializer : public TypeVisitorCallbacks {
  103.   struct MappingInfo {
  104.     explicit MappingInfo(BinaryStreamReader &R)
  105.         : Reader(R), Mapping(Reader), StartOffset(0) {}
  106.  
  107.     BinaryStreamReader &Reader;
  108.     TypeRecordMapping Mapping;
  109.     uint32_t StartOffset;
  110.   };
  111.  
  112. public:
  113.   explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) {
  114.     RecordPrefix Pre(static_cast<uint16_t>(TypeLeafKind::LF_FIELDLIST));
  115.     CVType FieldList(&Pre, sizeof(Pre));
  116.     consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
  117.   }
  118.  
  119.   ~FieldListDeserializer() override {
  120.     RecordPrefix Pre(static_cast<uint16_t>(TypeLeafKind::LF_FIELDLIST));
  121.     CVType FieldList(&Pre, sizeof(Pre));
  122.     consumeError(Mapping.Mapping.visitTypeEnd(FieldList));
  123.   }
  124.  
  125.   Error visitMemberBegin(CVMemberRecord &Record) override {
  126.     Mapping.StartOffset = Mapping.Reader.getOffset();
  127.     return Mapping.Mapping.visitMemberBegin(Record);
  128.   }
  129.  
  130.   Error visitMemberEnd(CVMemberRecord &Record) override {
  131.     if (auto EC = Mapping.Mapping.visitMemberEnd(Record))
  132.       return EC;
  133.     return Error::success();
  134.   }
  135.  
  136. #define TYPE_RECORD(EnumName, EnumVal, Name)
  137. #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
  138.   Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
  139.     return visitKnownMemberImpl<Name##Record>(CVR, Record);                    \
  140.   }
  141. #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
  142. #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
  143. #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
  144.  
  145. private:
  146.   template <typename RecordType>
  147.   Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
  148.     if (auto EC = Mapping.Mapping.visitKnownMember(CVR, Record))
  149.       return EC;
  150.  
  151.     uint32_t EndOffset = Mapping.Reader.getOffset();
  152.     uint32_t RecordLength = EndOffset - Mapping.StartOffset;
  153.     Mapping.Reader.setOffset(Mapping.StartOffset);
  154.     if (auto EC = Mapping.Reader.readBytes(CVR.Data, RecordLength))
  155.       return EC;
  156.     assert(Mapping.Reader.getOffset() == EndOffset);
  157.     return Error::success();
  158.   }
  159.   MappingInfo Mapping;
  160. };
  161.  
  162. } // end namespace codeview
  163. } // end namespace llvm
  164.  
  165. #endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
  166.