Add concrete type overloads to PDBSymbol::findChildren().
[oota-llvm.git] / include / llvm / DebugInfo / PDB / PDBSymbol.h
index b65089dd028b6ceeb46d21b2f5fc9b0f9206d9d9..9aa2da0b1f87428875550969d3ab6b0c9d5402c3 100644 (file)
 #define LLVM_DEBUGINFO_PDB_IPDBSYMBOL_H
 
 #include <memory>
+#include <unordered_map>
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 
+#include "ConcreteSymbolEnumerator.h"
 #include "IPDBRawSymbol.h"
+#include "PDBExtras.h"
 #include "PDBTypes.h"
 
 #define FORWARD_SYMBOL_METHOD(MethodName)                                      \
@@ -28,6 +31,10 @@ namespace llvm {
 class IPDBRawSymbol;
 class raw_ostream;
 
+#define DECLARE_PDB_SYMBOL_CONCRETE_TYPE(TagValue)                             \
+  static const PDB_SymType Tag = TagValue;                                     \
+  static bool classof(const PDBSymbol *S) { return S->getSymTag() == Tag; }
+
 /// PDBSymbol defines the base of the inheritance hierarchy for concrete symbol
 /// types (e.g. functions, executables, vtables, etc).  All concrete symbol
 /// types inherit from PDBSymbol and expose the exact set of methods that are
@@ -36,11 +43,11 @@ class raw_ostream;
 /// https://msdn.microsoft.com/en-us/library/370hs6k4.aspx
 class PDBSymbol {
 protected:
-  PDBSymbol(IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol);
+  PDBSymbol(const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol);
 
 public:
   static std::unique_ptr<PDBSymbol>
-  create(IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol);
+  create(const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol);
 
   virtual ~PDBSymbol();
 
@@ -48,10 +55,23 @@ public:
   /// call dump() on the underlying RawSymbol, which allows us to discover
   /// unknown properties, but individual implementations of PDBSymbol may
   /// override the behavior to only dump known fields.
-  virtual void dump(llvm::raw_ostream &OS) const;
+  virtual void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const = 0;
+  void defaultDump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const;
 
   PDB_SymType getSymTag() const;
 
+  template <typename T> std::unique_ptr<T> findOneChild() const {
+    auto Enumerator(findAllChildren<T>());
+    return Enumerator->getNext();
+  }
+
+  template <typename T>
+  std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const {
+    auto BaseIter = RawSymbol->findChildren(T::Tag);
+    return std::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter));
+  }
+
+  std::unique_ptr<IPDBEnumSymbols> findAllChildren() const;
   std::unique_ptr<IPDBEnumSymbols>
   findChildren(PDB_SymType Type, StringRef Name,
                PDB_NameSearchFlags Flags) const;
@@ -61,8 +81,13 @@ public:
                                                      uint32_t RVA) const;
   std::unique_ptr<IPDBEnumSymbols> findInlineFramesByRVA(uint32_t RVA) const;
 
+  const IPDBRawSymbol &getRawSymbol() const { return *RawSymbol; }
+  IPDBRawSymbol &getRawSymbol() { return *RawSymbol; }
+
 protected:
-  IPDBSession &Session;
+  std::unique_ptr<IPDBEnumSymbols> getChildStats(TagStats &Stats) const;
+
+  const IPDBSession &Session;
   const std::unique_ptr<IPDBRawSymbol> RawSymbol;
 };