Home | History | Annotate | Line # | Download | only in PDB
      1 //===- PDBSymbol.h - base class for user-facing symbol types -----*- 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_PDBSYMBOL_H
     10 #define LLVM_DEBUGINFO_PDB_PDBSYMBOL_H
     11 
     12 #include "ConcreteSymbolEnumerator.h"
     13 #include "IPDBRawSymbol.h"
     14 #include "PDBExtras.h"
     15 #include "PDBTypes.h"
     16 #include "llvm/ADT/STLExtras.h"
     17 #include "llvm/Support/Casting.h"
     18 
     19 #define FORWARD_SYMBOL_METHOD(MethodName)                                      \
     20   decltype(auto) MethodName() const { return RawSymbol->MethodName(); }
     21 
     22 #define FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(ConcreteType, PrivateName, \
     23                                                     PublicName)                \
     24   decltype(auto) PublicName##Id() const {                                      \
     25     return RawSymbol->PrivateName##Id();                                       \
     26   }                                                                            \
     27   std::unique_ptr<ConcreteType> PublicName() const {                           \
     28     uint32_t Id = PublicName##Id();                                            \
     29     return getConcreteSymbolByIdHelper<ConcreteType>(Id);                      \
     30   }
     31 
     32 #define FORWARD_SYMBOL_ID_METHOD_WITH_NAME(PrivateName, PublicName)            \
     33   FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(PDBSymbol, PrivateName,          \
     34                                               PublicName)
     35 
     36 #define FORWARD_SYMBOL_ID_METHOD(MethodName)                                   \
     37   FORWARD_SYMBOL_ID_METHOD_WITH_NAME(MethodName, MethodName)
     38 
     39 namespace llvm {
     40 
     41 class StringRef;
     42 class raw_ostream;
     43 
     44 namespace pdb {
     45 class IPDBSession;
     46 
     47 #define DECLARE_PDB_SYMBOL_CONCRETE_TYPE(TagValue)                             \
     48 private:                                                                       \
     49   using PDBSymbol::PDBSymbol;                                                  \
     50   friend class PDBSymbol;                                                      \
     51                                                                                \
     52 public:                                                                        \
     53   static const PDB_SymType Tag = TagValue;                                     \
     54   static bool classof(const PDBSymbol *S) { return S->getSymTag() == Tag; }
     55 
     56 #define DECLARE_PDB_SYMBOL_CUSTOM_TYPE(Condition)                              \
     57 private:                                                                       \
     58   using PDBSymbol::PDBSymbol;                                                  \
     59   friend class PDBSymbol;                                                      \
     60                                                                                \
     61 public:                                                                        \
     62   static bool classof(const PDBSymbol *S) { return Condition; }
     63 
     64 /// PDBSymbol defines the base of the inheritance hierarchy for concrete symbol
     65 /// types (e.g. functions, executables, vtables, etc).  All concrete symbol
     66 /// types inherit from PDBSymbol and expose the exact set of methods that are
     67 /// valid for that particular symbol type, as described in the Microsoft
     68 /// reference "Lexical and Class Hierarchy of Symbol Types":
     69 /// https://msdn.microsoft.com/en-us/library/370hs6k4.aspx
     70 class PDBSymbol {
     71   static std::unique_ptr<PDBSymbol> createSymbol(const IPDBSession &PDBSession,
     72                                                  PDB_SymType Tag);
     73 
     74 protected:
     75   explicit PDBSymbol(const IPDBSession &PDBSession);
     76   PDBSymbol(PDBSymbol &&Other);
     77 
     78 public:
     79   static std::unique_ptr<PDBSymbol>
     80   create(const IPDBSession &PDBSession,
     81          std::unique_ptr<IPDBRawSymbol> RawSymbol);
     82   static std::unique_ptr<PDBSymbol> create(const IPDBSession &PDBSession,
     83                                            IPDBRawSymbol &RawSymbol);
     84 
     85   template <typename ConcreteT>
     86   static std::unique_ptr<ConcreteT>
     87   createAs(const IPDBSession &PDBSession,
     88            std::unique_ptr<IPDBRawSymbol> RawSymbol) {
     89     std::unique_ptr<PDBSymbol> S = create(PDBSession, std::move(RawSymbol));
     90     return unique_dyn_cast_or_null<ConcreteT>(std::move(S));
     91   }
     92   template <typename ConcreteT>
     93   static std::unique_ptr<ConcreteT> createAs(const IPDBSession &PDBSession,
     94                                              IPDBRawSymbol &RawSymbol) {
     95     std::unique_ptr<PDBSymbol> S = create(PDBSession, RawSymbol);
     96     return unique_dyn_cast_or_null<ConcreteT>(std::move(S));
     97   }
     98 
     99   virtual ~PDBSymbol();
    100 
    101   /// Dumps the contents of a symbol a raw_ostream.  By default this will just
    102   /// call dump() on the underlying RawSymbol, which allows us to discover
    103   /// unknown properties, but individual implementations of PDBSymbol may
    104   /// override the behavior to only dump known fields.
    105   virtual void dump(PDBSymDumper &Dumper) const = 0;
    106 
    107   /// For certain PDBSymbolTypes, dumps additional information for the type that
    108   /// normally goes on the right side of the symbol.
    109   virtual void dumpRight(PDBSymDumper &Dumper) const {}
    110 
    111   void defaultDump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowFlags,
    112                    PdbSymbolIdField RecurseFlags) const;
    113   void dumpProperties() const;
    114   void dumpChildStats() const;
    115 
    116   PDB_SymType getSymTag() const;
    117   uint32_t getSymIndexId() const;
    118 
    119   template <typename T> std::unique_ptr<T> findOneChild() const {
    120     auto Enumerator(findAllChildren<T>());
    121     if (!Enumerator)
    122       return nullptr;
    123     return Enumerator->getNext();
    124   }
    125 
    126   template <typename T>
    127   std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const {
    128     auto BaseIter = RawSymbol->findChildren(T::Tag);
    129     if (!BaseIter)
    130       return nullptr;
    131     return std::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter));
    132   }
    133   std::unique_ptr<IPDBEnumSymbols> findAllChildren(PDB_SymType Type) const;
    134   std::unique_ptr<IPDBEnumSymbols> findAllChildren() const;
    135 
    136   std::unique_ptr<IPDBEnumSymbols>
    137   findChildren(PDB_SymType Type, StringRef Name,
    138                PDB_NameSearchFlags Flags) const;
    139   std::unique_ptr<IPDBEnumSymbols> findChildrenByRVA(PDB_SymType Type,
    140                                                      StringRef Name,
    141                                                      PDB_NameSearchFlags Flags,
    142                                                      uint32_t RVA) const;
    143   std::unique_ptr<IPDBEnumSymbols> findInlineFramesByVA(uint64_t VA) const;
    144   std::unique_ptr<IPDBEnumSymbols> findInlineFramesByRVA(uint32_t RVA) const;
    145   std::unique_ptr<IPDBEnumLineNumbers>
    146   findInlineeLinesByVA(uint64_t VA, uint32_t Length) const;
    147   std::unique_ptr<IPDBEnumLineNumbers>
    148   findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const;
    149 
    150   std::string getName() const;
    151 
    152   const IPDBRawSymbol &getRawSymbol() const { return *RawSymbol; }
    153   IPDBRawSymbol &getRawSymbol() { return *RawSymbol; }
    154 
    155   const IPDBSession &getSession() const { return Session; }
    156 
    157   std::unique_ptr<IPDBEnumSymbols> getChildStats(TagStats &Stats) const;
    158 
    159 protected:
    160   std::unique_ptr<PDBSymbol> getSymbolByIdHelper(uint32_t Id) const;
    161 
    162   template <typename ConcreteType>
    163   std::unique_ptr<ConcreteType> getConcreteSymbolByIdHelper(uint32_t Id) const {
    164     return unique_dyn_cast_or_null<ConcreteType>(getSymbolByIdHelper(Id));
    165   }
    166 
    167   const IPDBSession &Session;
    168   std::unique_ptr<IPDBRawSymbol> OwnedRawSymbol;
    169   IPDBRawSymbol *RawSymbol = nullptr;
    170 };
    171 
    172 } // namespace llvm
    173 }
    174 
    175 #endif
    176