- //===- GSIStreamBuilder.h - PDB Publics/Globals Stream Creation -*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_DEBUGINFO_PDB_NATIVE_GSISTREAMBUILDER_H 
- #define LLVM_DEBUGINFO_PDB_NATIVE_GSISTREAMBUILDER_H 
-   
- #include "llvm/ADT/DenseSet.h" 
- #include "llvm/DebugInfo/CodeView/CVRecord.h" 
- #include "llvm/DebugInfo/CodeView/CodeView.h" 
- #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" 
- #include "llvm/DebugInfo/PDB/Native/RawConstants.h" 
- #include "llvm/Support/BinaryStreamRef.h" 
- #include "llvm/Support/Error.h" 
-   
- namespace llvm { 
- namespace codeview { 
- class ConstantSym; 
- class DataSym; 
- class ProcRefSym; 
- } // namespace codeview 
- template <typename T> struct BinaryItemTraits; 
-   
- template <> struct BinaryItemTraits<codeview::CVSymbol> { 
-   static size_t length(const codeview::CVSymbol &Item) { 
-     return Item.RecordData.size(); 
-   } 
-   static ArrayRef<uint8_t> bytes(const codeview::CVSymbol &Item) { 
-     return Item.RecordData; 
-   } 
- }; 
-   
- namespace msf { 
- class MSFBuilder; 
- struct MSFLayout; 
- } // namespace msf 
- namespace pdb { 
- struct GSIHashStreamBuilder; 
- struct BulkPublic; 
- struct SymbolDenseMapInfo; 
-   
- class GSIStreamBuilder { 
-   
- public: 
-   explicit GSIStreamBuilder(msf::MSFBuilder &Msf); 
-   ~GSIStreamBuilder(); 
-   
-   GSIStreamBuilder(const GSIStreamBuilder &) = delete; 
-   GSIStreamBuilder &operator=(const GSIStreamBuilder &) = delete; 
-   
-   Error finalizeMsfLayout(); 
-   
-   Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer); 
-   
-   uint32_t getPublicsStreamIndex() const { return PublicsStreamIndex; } 
-   uint32_t getGlobalsStreamIndex() const { return GlobalsStreamIndex; } 
-   uint32_t getRecordStreamIndex() const { return RecordStreamIndex; } 
-   
-   // Add public symbols in bulk. 
-   void addPublicSymbols(std::vector<BulkPublic> &&PublicsIn); 
-   
-   void addGlobalSymbol(const codeview::ProcRefSym &Sym); 
-   void addGlobalSymbol(const codeview::DataSym &Sym); 
-   void addGlobalSymbol(const codeview::ConstantSym &Sym); 
-   
-   // Add a pre-serialized global symbol record. The caller must ensure that the 
-   // symbol data remains alive until the global stream is committed to disk. 
-   void addGlobalSymbol(const codeview::CVSymbol &Sym); 
-   
- private: 
-   void finalizePublicBuckets(); 
-   void finalizeGlobalBuckets(uint32_t RecordZeroOffset); 
-   
-   template <typename T> void serializeAndAddGlobal(const T &Symbol); 
-   
-   uint32_t calculatePublicsHashStreamSize() const; 
-   uint32_t calculateGlobalsHashStreamSize() const; 
-   Error commitSymbolRecordStream(WritableBinaryStreamRef Stream); 
-   Error commitPublicsHashStream(WritableBinaryStreamRef Stream); 
-   Error commitGlobalsHashStream(WritableBinaryStreamRef Stream); 
-   
-   uint32_t PublicsStreamIndex = kInvalidStreamIndex; 
-   uint32_t GlobalsStreamIndex = kInvalidStreamIndex; 
-   uint32_t RecordStreamIndex = kInvalidStreamIndex; 
-   msf::MSFBuilder &Msf; 
-   std::unique_ptr<GSIHashStreamBuilder> PSH; 
-   std::unique_ptr<GSIHashStreamBuilder> GSH; 
-   
-   // List of all of the public records. These are stored unserialized so that we 
-   // can defer copying the names until we are ready to commit the PDB. 
-   std::vector<BulkPublic> Publics; 
-   
-   // List of all of the global records. 
-   std::vector<codeview::CVSymbol> Globals; 
-   
-   // Hash table for deduplicating global typedef and constant records. Only used 
-   // for globals. 
-   llvm::DenseSet<codeview::CVSymbol, SymbolDenseMapInfo> GlobalsSeen; 
- }; 
-   
- /// This struct is equivalent to codeview::PublicSym32, but it has been 
- /// optimized for size to speed up bulk serialization and sorting operations 
- /// during PDB writing. 
- struct BulkPublic { 
-   BulkPublic() : Flags(0), BucketIdx(0) {} 
-   
-   const char *Name = nullptr; 
-   uint32_t NameLen = 0; 
-   
-   // Offset of the symbol record in the publics stream. 
-   uint32_t SymOffset = 0; 
-   
-   // Section offset of the symbol in the image. 
-   uint32_t Offset = 0; 
-   
-   // Section index of the section containing the symbol. 
-   uint16_t Segment = 0; 
-   
-   // PublicSymFlags. 
-   uint16_t Flags : 4; 
-   
-   // GSI hash table bucket index. The maximum value is IPHR_HASH. 
-   uint16_t BucketIdx : 12; 
-   static_assert(IPHR_HASH <= 1 << 12, "bitfield too small"); 
-   
-   void setFlags(codeview::PublicSymFlags F) { 
-     Flags = uint32_t(F); 
-     assert(Flags == uint32_t(F) && "truncated"); 
-   } 
-   
-   void setBucketIdx(uint16_t B) { 
-     assert(B < IPHR_HASH); 
-     BucketIdx = B; 
-   } 
-   
-   StringRef getName() const { return StringRef(Name, NameLen); } 
- }; 
-   
- static_assert(sizeof(BulkPublic) <= 24, "unexpected size increase"); 
- static_assert(std::is_trivially_copyable<BulkPublic>::value, 
-               "should be trivial"); 
-   
- } // namespace pdb 
- } // namespace llvm 
-   
- #endif 
-