[PDB] Enable NativeSession to create symbols for built-in types on demand
authorAdrian McCarthy <amccarth@google.com>
Wed, 12 Jul 2017 19:38:11 +0000 (19:38 +0000)
committerAdrian McCarthy <amccarth@google.com>
Wed, 12 Jul 2017 19:38:11 +0000 (19:38 +0000)
Summary:
There is a reserved range of type indexes for built-in types (like integers).
This will create a symbol for a built-in type if the caller askes for one by
type index.  This is also plumbing for being able to recall symbols by type
index in general, but user-defined types will come in subsequent patches.

Reviewers: rnk, zturner

Subscribers: mgorny, hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D35163

llvm-svn: 307834

12 files changed:
llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
llvm/include/llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h [new file with mode: 0644]
llvm/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h
llvm/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h
llvm/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h
llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h
llvm/lib/DebugInfo/PDB/CMakeLists.txt
llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp [new file with mode: 0644]
llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp

index 10d51c2..e0c2226 100644 (file)
 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
 #define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H
 
+#include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/Support/Endian.h"
 #include <cassert>
 #include <cinttypes>
+#include <functional>
 
 namespace llvm {
 
@@ -265,6 +267,23 @@ struct TypeIndexOffset {
 void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI,
                     TypeCollection &Types);
 }
-}
+
+template <> struct DenseMapInfo<codeview::TypeIndex> {
+  static inline codeview::TypeIndex getEmptyKey() {
+    return codeview::TypeIndex{DenseMapInfo<uint32_t>::getEmptyKey()};
+  }
+  static inline codeview::TypeIndex getTombstoneKey() {
+    return codeview::TypeIndex{DenseMapInfo<uint32_t>::getTombstoneKey()};
+  }
+  static unsigned getHashValue(const codeview::TypeIndex &TI) {
+    return DenseMapInfo<uint32_t>::getHashValue(TI.getIndex());
+  }
+  static bool isEqual(const codeview::TypeIndex &LHS,
+                      const codeview::TypeIndex &RHS) {
+    return LHS == RHS;
+  }
+};
+
+} // namespace llvm
 
 #endif
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h
new file mode 100644 (file)
index 0000000..fc55296
--- /dev/null
@@ -0,0 +1,49 @@
+//===- NativeBuiltinSymbol.h -------------------------------------- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEBUILTINSYMBOL_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEBUILTINSYMBOL_H
+
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+
+namespace llvm {
+namespace pdb {
+
+class NativeSession;
+
+class NativeBuiltinSymbol : public NativeRawSymbol {
+public:
+  NativeBuiltinSymbol(NativeSession &PDBSession, SymIndexId Id,
+                      PDB_BuiltinType T, uint64_t L);
+  ~NativeBuiltinSymbol() override;
+
+  virtual std::unique_ptr<NativeRawSymbol> clone() const override;
+
+  void dump(raw_ostream &OS, int Indent) const override;
+
+  PDB_SymType NativeBuiltinSymbol::getSymTag() const override;
+
+  PDB_BuiltinType getBuiltinType() const override;
+  bool isConstType() const override;
+  uint64_t getLength() const override;
+  bool isUnalignedType() const override;
+  bool isVolatileType() const override;
+
+protected:
+  NativeSession &Session;
+  PDB_BuiltinType Type;
+  uint64_t Length;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif
index 1687737..bd5c09e 100644 (file)
@@ -18,7 +18,7 @@ namespace pdb {
 
 class NativeCompilandSymbol : public NativeRawSymbol {
 public:
-  NativeCompilandSymbol(NativeSession &Session, uint32_t SymbolId,
+  NativeCompilandSymbol(NativeSession &Session, SymIndexId SymbolId,
                         DbiModuleDescriptor MI);
 
   std::unique_ptr<NativeRawSymbol> clone() const override;
index 15bac78..ddb7f81 100644 (file)
@@ -18,7 +18,7 @@ namespace pdb {
 
 class NativeExeSymbol : public NativeRawSymbol {
 public:
-  NativeExeSymbol(NativeSession &Session, uint32_t SymbolId);
+  NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId);
 
   std::unique_ptr<NativeRawSymbol> clone() const override;
 
index a24a972..66a9eae 100644 (file)
@@ -19,9 +19,11 @@ namespace pdb {
 
 class NativeSession;
 
+typedef uint32_t SymIndexId;
+
 class NativeRawSymbol : public IPDBRawSymbol {
 public:
-  NativeRawSymbol(NativeSession &PDBSession, uint32_t SymbolId);
+  NativeRawSymbol(NativeSession &PDBSession, SymIndexId SymbolId);
 
   virtual std::unique_ptr<NativeRawSymbol> clone() const = 0;
 
@@ -205,7 +207,7 @@ public:
 
 protected:
   NativeSession &Session;
-  uint32_t SymbolId;
+  SymIndexId SymbolId;
 };
 
 } // end namespace pdb
index dd40874..b16ce23 100644 (file)
 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVESESSION_H
 #define LLVM_DEBUGINFO_PDB_NATIVE_NATIVESESSION_H
 
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
 #include "llvm/DebugInfo/PDB/IPDBSession.h"
 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h"
 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Error.h"
@@ -35,6 +39,8 @@ public:
   std::unique_ptr<PDBSymbolCompiland>
   createCompilandSymbol(DbiModuleDescriptor MI);
 
+  SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI);
+
   uint64_t getLoadAddress() const override;
   void setLoadAddress(uint64_t Address) override;
   std::unique_ptr<PDBSymbolExe> getGlobalScope() override;
@@ -77,6 +83,7 @@ private:
   std::unique_ptr<PDBFile> Pdb;
   std::unique_ptr<BumpPtrAllocator> Allocator;
   std::vector<std::unique_ptr<NativeRawSymbol>> SymbolCache;
+  DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
 };
 }
 }
index 524fdf1..ff01c94 100644 (file)
@@ -41,6 +41,7 @@ add_pdb_impl_folder(Native
   Native/InfoStream.cpp
   Native/InfoStreamBuilder.cpp
   Native/ModuleDebugStream.cpp
+  Native/NativeBuiltinSymbol.cpp
   Native/NativeCompilandSymbol.cpp
   Native/NativeEnumModules.cpp
   Native/NativeExeSymbol.cpp
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp
new file mode 100644 (file)
index 0000000..bd57fbd
--- /dev/null
@@ -0,0 +1,48 @@
+//===- NativeBuiltinSymbol.cpp ------------------------------------ C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h"
+
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+namespace llvm {
+namespace pdb {
+
+NativeBuiltinSymbol::NativeBuiltinSymbol(NativeSession &PDBSession,
+                                         SymIndexId Id, PDB_BuiltinType T,
+                                         uint64_t L)
+    : NativeRawSymbol(PDBSession, Id), Session(PDBSession), Type(T), Length(L) {
+}
+
+NativeBuiltinSymbol::~NativeBuiltinSymbol() {}
+
+std::unique_ptr<NativeRawSymbol> NativeBuiltinSymbol::clone() const {
+  return std::make_unique<NativeBuiltinSymbol>(Session, SymbolId, Type, Length);
+}
+
+void NativeBuiltinSymbol::dump(raw_ostream &OS, int Indent) const {
+  // TODO:  Apparently nothing needs this yet.
+}
+
+PDB_SymType NativeBuiltinSymbol::getSymTag() const {
+  return PDB_SymType::BuiltinType;
+}
+
+PDB_BuiltinType NativeBuiltinSymbol::getBuiltinType() const { return Type; }
+
+bool NativeBuiltinSymbol::isConstType() const { return false; }
+
+uint64_t NativeBuiltinSymbol::getLength() const { return Length; }
+
+bool NativeBuiltinSymbol::isUnalignedType() const { return false; }
+
+bool NativeBuiltinSymbol::isVolatileType() const { return false; }
+
+} // namespace pdb
+} // namespace llvm
index 180c169..7132a99 100644 (file)
@@ -15,7 +15,7 @@ namespace llvm {
 namespace pdb {
 
 NativeCompilandSymbol::NativeCompilandSymbol(NativeSession &Session,
-                                             uint32_t SymbolId,
+                                             SymIndexId SymbolId,
                                              DbiModuleDescriptor MI)
     : NativeRawSymbol(Session, SymbolId), Module(MI) {}
 
index 6206155..cb0830f 100644 (file)
@@ -18,7 +18,7 @@
 namespace llvm {
 namespace pdb {
 
-NativeExeSymbol::NativeExeSymbol(NativeSession &Session, uint32_t SymbolId)
+NativeExeSymbol::NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId)
     : NativeRawSymbol(Session, SymbolId), File(Session.getPDBFile()) {}
 
 std::unique_ptr<NativeRawSymbol> NativeExeSymbol::clone() const {
index b4f5c96..92612bc 100644 (file)
@@ -13,7 +13,7 @@
 using namespace llvm;
 using namespace llvm::pdb;
 
-NativeRawSymbol::NativeRawSymbol(NativeSession &PDBSession, uint32_t SymbolId)
+NativeRawSymbol::NativeRawSymbol(NativeSession &PDBSession, SymIndexId SymbolId)
     : Session(PDBSession), SymbolId(SymbolId) {}
 
 void NativeRawSymbol::dump(raw_ostream &OS, int Indent) const {}
index 93d43d9..cb41756 100644 (file)
 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
 
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/PDB/GenericError.h"
 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
 #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h"
 #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
 #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
@@ -33,6 +35,28 @@ using namespace llvm;
 using namespace llvm::msf;
 using namespace llvm::pdb;
 
+namespace {
+// Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
+// to instantiate a NativeBuiltinSymbol for that type.
+static const struct {
+  codeview::SimpleTypeKind Kind;
+  PDB_BuiltinType Type;
+  uint32_t Size;
+} BuiltinTypes[] = {
+    {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
+    {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
+    {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
+    {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
+    {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
+    {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
+    {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
+    {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
+    {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1}
+    // This table can be grown as necessary, but these are the only types we've
+    // needed so far.
+};
+} // namespace
+
 NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
                              std::unique_ptr<BumpPtrAllocator> Allocator)
     : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {}
@@ -71,19 +95,49 @@ Error NativeSession::createFromExe(StringRef Path,
 
 std::unique_ptr<PDBSymbolCompiland>
 NativeSession::createCompilandSymbol(DbiModuleDescriptor MI) {
-  const auto Id = static_cast<uint32_t>(SymbolCache.size());
+  const auto Id = static_cast<SymIndexId>(SymbolCache.size());
   SymbolCache.push_back(
       llvm::make_unique<NativeCompilandSymbol>(*this, Id, MI));
   return llvm::make_unique<PDBSymbolCompiland>(
       *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
 }
 
+SymIndexId NativeSession::findSymbolByTypeIndex(codeview::TypeIndex Index) {
+  // First see if it's already in our cache.
+  const auto Entry = TypeIndexToSymbolId.find(Index);
+  if (Entry != TypeIndexToSymbolId.end())
+    return Entry->second;
+
+  // Symbols for built-in types are created on the fly.
+  if (Index.isSimple()) {
+    // FIXME:  We will eventually need to handle pointers to other simple types,
+    // which are still simple types in the world of CodeView TypeIndexes.
+    if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
+      return 0;
+    const auto Kind = Index.getSimpleKind();
+    const auto It = std::find_if(
+        std::begin(BuiltinTypes), std::end(BuiltinTypes),
+        [Kind](const auto &Builtin) { return Builtin.Kind == Kind; });
+    if (It == std::end(BuiltinTypes))
+      return 0;
+    SymIndexId Id = SymbolCache.size();
+    SymbolCache.emplace_back(
+        std::make_unique<NativeBuiltinSymbol>(*this, Id, It->Type, It->Size));
+    TypeIndexToSymbolId[Index] = Id;
+    return Id;
+  }
+
+  // TODO:  Look up PDB type by type index
+
+  return 0;
+}
+
 uint64_t NativeSession::getLoadAddress() const { return 0; }
 
 void NativeSession::setLoadAddress(uint64_t Address) {}
 
 std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
-  const auto Id = static_cast<uint32_t>(SymbolCache.size());
+  const auto Id = static_cast<SymIndexId>(SymbolCache.size());
   SymbolCache.push_back(llvm::make_unique<NativeExeSymbol>(*this, Id));
   auto RawSymbol = SymbolCache[Id]->clone();
   auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));