Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //==- SymbolCache.h - Cache of native symbols and ids ------------*- 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_PDB_NATIVE_SYMBOLCACHE_H
  10. #define LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H
  11.  
  12. #include "llvm/ADT/DenseMap.h"
  13. #include "llvm/DebugInfo/CodeView/CVRecord.h"
  14. #include "llvm/DebugInfo/CodeView/CodeView.h"
  15. #include "llvm/DebugInfo/CodeView/Line.h"
  16. #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
  17. #include "llvm/DebugInfo/CodeView/TypeIndex.h"
  18. #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
  19. #include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
  20. #include "llvm/DebugInfo/PDB/PDBTypes.h"
  21.  
  22. #include <memory>
  23. #include <vector>
  24.  
  25. namespace llvm {
  26. namespace codeview {
  27. class InlineSiteSym;
  28. struct FileChecksumEntry;
  29. } // namespace codeview
  30. namespace pdb {
  31. class IPDBSourceFile;
  32. class NativeSession;
  33. class PDBSymbol;
  34. class PDBSymbolCompiland;
  35. class DbiStream;
  36.  
  37. class SymbolCache {
  38.   NativeSession &Session;
  39.   DbiStream *Dbi = nullptr;
  40.  
  41.   /// Cache of all stable symbols, indexed by SymIndexId.  Just because a
  42.   /// symbol has been parsed does not imply that it will be stable and have
  43.   /// an Id.  Id allocation is an implementation, with the only guarantee
  44.   /// being that once an Id is allocated, the symbol can be assumed to be
  45.   /// cached.
  46.   mutable std::vector<std::unique_ptr<NativeRawSymbol>> Cache;
  47.  
  48.   /// For type records from the TPI stream which have been paresd and cached,
  49.   /// stores a mapping to SymIndexId of the cached symbol.
  50.   mutable DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
  51.  
  52.   /// For field list members which have been parsed and cached, stores a mapping
  53.   /// from (IndexOfClass, MemberIndex) to the corresponding SymIndexId of the
  54.   /// cached symbol.
  55.   mutable DenseMap<std::pair<codeview::TypeIndex, uint32_t>, SymIndexId>
  56.       FieldListMembersToSymbolId;
  57.  
  58.   /// List of SymIndexIds for each compiland, indexed by compiland index as they
  59.   /// appear in the PDB file.
  60.   mutable std::vector<SymIndexId> Compilands;
  61.  
  62.   /// List of source files, indexed by unique source file index.
  63.   mutable std::vector<std::unique_ptr<NativeSourceFile>> SourceFiles;
  64.  
  65.   /// Map from string table offset to source file Id.
  66.   mutable DenseMap<uint32_t, SymIndexId> FileNameOffsetToId;
  67.  
  68.   /// Map from global symbol offset to SymIndexId.
  69.   mutable DenseMap<uint32_t, SymIndexId> GlobalOffsetToSymbolId;
  70.  
  71.   /// Map from segment and code offset to function symbols.
  72.   mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId> AddressToSymbolId;
  73.   /// Map from segment and code offset to public symbols.
  74.   mutable DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId>
  75.       AddressToPublicSymId;
  76.  
  77.   /// Map from module index and symbol table offset to SymIndexId.
  78.   mutable DenseMap<std::pair<uint16_t, uint32_t>, SymIndexId>
  79.       SymTabOffsetToSymbolId;
  80.  
  81.   struct LineTableEntry {
  82.     uint64_t Addr;
  83.     codeview::LineInfo Line;
  84.     uint32_t ColumnNumber;
  85.     uint32_t FileNameIndex;
  86.     bool IsTerminalEntry;
  87.   };
  88.  
  89.   std::vector<LineTableEntry> findLineTable(uint16_t Modi) const;
  90.   mutable DenseMap<uint16_t, std::vector<LineTableEntry>> LineTable;
  91.  
  92.   SymIndexId createSymbolPlaceholder() const {
  93.     SymIndexId Id = Cache.size();
  94.     Cache.push_back(nullptr);
  95.     return Id;
  96.   }
  97.  
  98.   template <typename ConcreteSymbolT, typename CVRecordT, typename... Args>
  99.   SymIndexId createSymbolForType(codeview::TypeIndex TI, codeview::CVType CVT,
  100.                                  Args &&...ConstructorArgs) const {
  101.     CVRecordT Record;
  102.     if (auto EC =
  103.             codeview::TypeDeserializer::deserializeAs<CVRecordT>(CVT, Record)) {
  104.       consumeError(std::move(EC));
  105.       return 0;
  106.     }
  107.  
  108.     return createSymbol<ConcreteSymbolT>(
  109.         TI, std::move(Record), std::forward<Args>(ConstructorArgs)...);
  110.   }
  111.  
  112.   SymIndexId createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
  113.                                          codeview::CVType CVT) const;
  114.  
  115.   SymIndexId createSimpleType(codeview::TypeIndex TI,
  116.                               codeview::ModifierOptions Mods) const;
  117.  
  118.   std::unique_ptr<PDBSymbol> findFunctionSymbolBySectOffset(uint32_t Sect,
  119.                                                             uint32_t Offset);
  120.   std::unique_ptr<PDBSymbol> findPublicSymbolBySectOffset(uint32_t Sect,
  121.                                                           uint32_t Offset);
  122.  
  123. public:
  124.   SymbolCache(NativeSession &Session, DbiStream *Dbi);
  125.  
  126.   template <typename ConcreteSymbolT, typename... Args>
  127.   SymIndexId createSymbol(Args &&...ConstructorArgs) const {
  128.     SymIndexId Id = Cache.size();
  129.  
  130.     // Initial construction must not access the cache, since it must be done
  131.     // atomically.
  132.     auto Result = std::make_unique<ConcreteSymbolT>(
  133.         Session, Id, std::forward<Args>(ConstructorArgs)...);
  134.     Result->SymbolId = Id;
  135.  
  136.     NativeRawSymbol *NRS = static_cast<NativeRawSymbol *>(Result.get());
  137.     Cache.push_back(std::move(Result));
  138.  
  139.     // After the item is in the cache, we can do further initialization which
  140.     // is then allowed to access the cache.
  141.     NRS->initialize();
  142.     return Id;
  143.   }
  144.  
  145.   std::unique_ptr<IPDBEnumSymbols>
  146.   createTypeEnumerator(codeview::TypeLeafKind Kind);
  147.  
  148.   std::unique_ptr<IPDBEnumSymbols>
  149.   createTypeEnumerator(std::vector<codeview::TypeLeafKind> Kinds);
  150.  
  151.   std::unique_ptr<IPDBEnumSymbols>
  152.   createGlobalsEnumerator(codeview::SymbolKind Kind);
  153.  
  154.   SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI) const;
  155.  
  156.   template <typename ConcreteSymbolT, typename... Args>
  157.   SymIndexId getOrCreateFieldListMember(codeview::TypeIndex FieldListTI,
  158.                                         uint32_t Index,
  159.                                         Args &&... ConstructorArgs) {
  160.     SymIndexId SymId = Cache.size();
  161.     std::pair<codeview::TypeIndex, uint32_t> Key{FieldListTI, Index};
  162.     auto Result = FieldListMembersToSymbolId.try_emplace(Key, SymId);
  163.     if (Result.second)
  164.       SymId =
  165.           createSymbol<ConcreteSymbolT>(std::forward<Args>(ConstructorArgs)...);
  166.     else
  167.       SymId = Result.first->second;
  168.     return SymId;
  169.   }
  170.  
  171.   SymIndexId getOrCreateGlobalSymbolByOffset(uint32_t Offset);
  172.   SymIndexId getOrCreateInlineSymbol(codeview::InlineSiteSym Sym,
  173.                                      uint64_t ParentAddr, uint16_t Modi,
  174.                                      uint32_t RecordOffset) const;
  175.  
  176.   std::unique_ptr<PDBSymbol>
  177.   findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, PDB_SymType Type);
  178.  
  179.   std::unique_ptr<IPDBEnumLineNumbers>
  180.   findLineNumbersByVA(uint64_t VA, uint32_t Length) const;
  181.  
  182.   std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index);
  183.   uint32_t getNumCompilands() const;
  184.  
  185.   std::unique_ptr<PDBSymbol> getSymbolById(SymIndexId SymbolId) const;
  186.  
  187.   NativeRawSymbol &getNativeSymbolById(SymIndexId SymbolId) const;
  188.  
  189.   template <typename ConcreteT>
  190.   ConcreteT &getNativeSymbolById(SymIndexId SymbolId) const {
  191.     return static_cast<ConcreteT &>(getNativeSymbolById(SymbolId));
  192.   }
  193.  
  194.   std::unique_ptr<IPDBSourceFile> getSourceFileById(SymIndexId FileId) const;
  195.   SymIndexId
  196.   getOrCreateSourceFile(const codeview::FileChecksumEntry &Checksum) const;
  197. };
  198.  
  199. } // namespace pdb
  200. } // namespace llvm
  201.  
  202. #endif
  203.