Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===- GlobalTypeTableBuilder.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_GLOBALTYPETABLEBUILDER_H
  10. #define LLVM_DEBUGINFO_CODEVIEW_GLOBALTYPETABLEBUILDER_H
  11.  
  12. #include "llvm/ADT/ArrayRef.h"
  13. #include "llvm/ADT/DenseMap.h"
  14. #include "llvm/ADT/SmallVector.h"
  15. #include "llvm/DebugInfo/CodeView/CVRecord.h"
  16. #include "llvm/DebugInfo/CodeView/SimpleTypeSerializer.h"
  17. #include "llvm/DebugInfo/CodeView/TypeCollection.h"
  18. #include "llvm/DebugInfo/CodeView/TypeHashing.h"
  19. #include "llvm/DebugInfo/CodeView/TypeIndex.h"
  20. #include "llvm/Support/Allocator.h"
  21. #include <cassert>
  22. #include <cstdint>
  23.  
  24. namespace llvm {
  25. namespace codeview {
  26.  
  27. class ContinuationRecordBuilder;
  28.  
  29. class GlobalTypeTableBuilder : public TypeCollection {
  30.   /// Storage for records.  These need to outlive the TypeTableBuilder.
  31.   BumpPtrAllocator &RecordStorage;
  32.  
  33.   /// A serializer that can write non-continuation leaf types.  Only used as
  34.   /// a convenience function so that we can provide an interface method to
  35.   /// write an unserialized record.
  36.   SimpleTypeSerializer SimpleSerializer;
  37.  
  38.   /// Hash table.
  39.   DenseMap<GloballyHashedType, TypeIndex> HashedRecords;
  40.  
  41.   /// Contains a list of all records indexed by TypeIndex.toArrayIndex().
  42.   SmallVector<ArrayRef<uint8_t>, 2> SeenRecords;
  43.  
  44.   /// Contains a list of all hash values indexed by TypeIndex.toArrayIndex().
  45.   SmallVector<GloballyHashedType, 2> SeenHashes;
  46.  
  47. public:
  48.   explicit GlobalTypeTableBuilder(BumpPtrAllocator &Storage);
  49.   ~GlobalTypeTableBuilder();
  50.  
  51.   // TypeCollection overrides
  52.   std::optional<TypeIndex> getFirst() override;
  53.   std::optional<TypeIndex> getNext(TypeIndex Prev) override;
  54.   CVType getType(TypeIndex Index) override;
  55.   StringRef getTypeName(TypeIndex Index) override;
  56.   bool contains(TypeIndex Index) override;
  57.   uint32_t size() override;
  58.   uint32_t capacity() override;
  59.   bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
  60.  
  61.   // public interface
  62.   void reset();
  63.   TypeIndex nextTypeIndex() const;
  64.  
  65.   BumpPtrAllocator &getAllocator() { return RecordStorage; }
  66.  
  67.   ArrayRef<ArrayRef<uint8_t>> records() const;
  68.   ArrayRef<GloballyHashedType> hashes() const;
  69.  
  70.   template <typename CreateFunc>
  71.   TypeIndex insertRecordAs(GloballyHashedType Hash, size_t RecordSize,
  72.                            CreateFunc Create) {
  73.     assert(RecordSize < UINT32_MAX && "Record too big");
  74.     assert(RecordSize % 4 == 0 &&
  75.            "RecordSize is not a multiple of 4 bytes which will cause "
  76.            "misalignment in the output TPI stream!");
  77.  
  78.     auto Result = HashedRecords.try_emplace(Hash, nextTypeIndex());
  79.  
  80.     if (LLVM_UNLIKELY(Result.second /*inserted*/ ||
  81.                       Result.first->second.isSimple())) {
  82.       uint8_t *Stable = RecordStorage.Allocate<uint8_t>(RecordSize);
  83.       MutableArrayRef<uint8_t> Data(Stable, RecordSize);
  84.       ArrayRef<uint8_t> StableRecord = Create(Data);
  85.       if (StableRecord.empty()) {
  86.         // Records with forward references into the Type stream will be deferred
  87.         // for insertion at a later time, on the second pass.
  88.         Result.first->getSecond() = TypeIndex(SimpleTypeKind::NotTranslated);
  89.         return TypeIndex(SimpleTypeKind::NotTranslated);
  90.       }
  91.       if (Result.first->second.isSimple()) {
  92.         assert(Result.first->second.getIndex() ==
  93.                (uint32_t)SimpleTypeKind::NotTranslated);
  94.         // On the second pass, update with index to remapped record. The
  95.         // (initially misbehaved) record will now come *after* other records
  96.         // resolved in the first pass, with proper *back* references in the
  97.         // stream.
  98.         Result.first->second = nextTypeIndex();
  99.       }
  100.       SeenRecords.push_back(StableRecord);
  101.       SeenHashes.push_back(Hash);
  102.     }
  103.  
  104.     return Result.first->second;
  105.   }
  106.  
  107.   TypeIndex insertRecordBytes(ArrayRef<uint8_t> Data);
  108.   TypeIndex insertRecord(ContinuationRecordBuilder &Builder);
  109.  
  110.   template <typename T> TypeIndex writeLeafType(T &Record) {
  111.     ArrayRef<uint8_t> Data = SimpleSerializer.serialize(Record);
  112.     return insertRecordBytes(Data);
  113.   }
  114. };
  115.  
  116. } // end namespace codeview
  117. } // end namespace llvm
  118.  
  119. #endif // LLVM_DEBUGINFO_CODEVIEW_GLOBALTYPETABLEBUILDER_H
  120.