[DebugInfo/PDB] Adding getUndecoratedNameEx and IPDB interfaces for IDiaEnumTables and IDiaTable.

Initial changes to support debugging PE/COFF files with LLDB on Windows through DIA SDK.
There is another set of changes required on the LLDB side before this does anything.

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

llvm-svn: 318403
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
index aad4bf3..0be05e9 100644
--- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
@@ -17,11 +17,13 @@
     DIA/DIAEnumLineNumbers.cpp
     DIA/DIAEnumSourceFiles.cpp
     DIA/DIAEnumSymbols.cpp
+    DIA/DIAEnumTables.cpp
     DIA/DIAError.cpp
     DIA/DIALineNumber.cpp
     DIA/DIARawSymbol.cpp
     DIA/DIASession.cpp
     DIA/DIASourceFile.cpp
+    DIA/DIATable.cpp
     )
 
     set(LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB/DIA")
diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp
new file mode 100644
index 0000000..511b555
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp
@@ -0,0 +1,53 @@
+//===- DIAEnumTables.cpp - DIA Table Enumerator Impl ------------*- 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/DIA/DIAEnumTables.h"
+#include "llvm/DebugInfo/PDB/DIA/DIATable.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+DIAEnumTables::DIAEnumTables(
+  CComPtr<IDiaEnumTables> DiaEnumerator)
+  : Enumerator(DiaEnumerator) {}
+
+uint32_t DIAEnumTables::getChildCount() const {
+  LONG Count = 0;
+  return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0;
+}
+
+std::unique_ptr<IPDBTable>
+DIAEnumTables::getChildAtIndex(uint32_t Index) const {
+  CComPtr<IDiaTable> Item;
+  VARIANT Var;
+  Var.vt = VT_UINT;
+  Var.uintVal = Index;
+  if (S_OK != Enumerator->Item(Var, &Item))
+    return nullptr;
+
+  return std::unique_ptr<IPDBTable>(new DIATable(Item));
+}
+
+std::unique_ptr<IPDBTable> DIAEnumTables::getNext() {
+  CComPtr<IDiaTable> Item;
+  ULONG CeltFetched = 0;
+  if (S_OK != Enumerator->Next(1, &Item, &CeltFetched))
+    return nullptr;
+
+  return std::unique_ptr<IPDBTable>(new DIATable(Item));
+}
+
+void DIAEnumTables::reset() { Enumerator->Reset(); }
+
+DIAEnumTables *DIAEnumTables::clone() const {
+  CComPtr<IDiaEnumTables> EnumeratorClone;
+  if (S_OK != Enumerator->Clone(&EnumeratorClone))
+    return nullptr;
+  return new DIAEnumTables(EnumeratorClone);
+}
diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
index 4c59d2f..8e4b1f8 100644
--- a/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
@@ -439,6 +439,20 @@
   Symbol->get_dataBytes(DataSize, &DataSize, bytes.data());
 }
 
+std::string
+DIARawSymbol::getUndecoratedNameEx(PDB_UndnameFlags Flags) const {
+  CComBSTR Result16;
+  if (S_OK != Symbol->get_undecoratedNameEx((DWORD)Flags, &Result16))
+    return std::string();
+
+  const char *SrcBytes = reinterpret_cast<const char *>(Result16.m_str);
+  llvm::ArrayRef<char> SrcByteArray(SrcBytes, Result16.ByteLength());
+  std::string Result8;
+  if (!llvm::convertUTF16ToUTF8String(SrcByteArray, Result8))
+    return std::string();
+  return Result8;
+}
+
 PDB_MemberAccess DIARawSymbol::getAccess() const {
   return PrivateGetDIAValue<DWORD, PDB_MemberAccess>(Symbol,
                                                      &IDiaSymbol::get_access);
diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp
index ef9390c..b8aaebb 100644
--- a/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp
+++ b/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp
@@ -11,6 +11,7 @@
 #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
 #include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h"
 #include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAEnumTables.h"
 #include "llvm/DebugInfo/PDB/DIA/DIAError.h"
 #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
 #include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
@@ -301,3 +302,11 @@
 
   return llvm::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
 }
+
+std::unique_ptr<IPDBEnumTables> DIASession::getEnumTables() const {
+  CComPtr<IDiaEnumTables> DiaEnumerator;
+  if (S_OK != Session->getEnumTables(&DiaEnumerator))
+    return nullptr;
+
+  return llvm::make_unique<DIAEnumTables>(DiaEnumerator);
+}
diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIATable.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIATable.cpp
new file mode 100644
index 0000000..7f4d06c
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/DIA/DIATable.cpp
@@ -0,0 +1,61 @@
+//===- DIATable.cpp - DIA implementation of IPDBTable -----------*- 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/DIA/DIATable.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/ConvertUTF.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+DIATable::DIATable(CComPtr<IDiaTable> DiaTable)
+  : Table(DiaTable) {}
+
+uint32_t DIATable::getItemCount() const {
+  LONG Count = 0;
+  return (S_OK == Table->get_Count(&Count)) ? Count : 0;
+}
+
+std::string DIATable::getName() const {
+  CComBSTR Name16;
+  if (S_OK != Table->get_name(&Name16))
+    return std::string();
+
+  std::string Name8;
+  llvm::ArrayRef<char> Name16Bytes(reinterpret_cast<char *>(Name16.m_str),
+                                   Name16.ByteLength());
+  if (!llvm::convertUTF16ToUTF8String(Name16Bytes, Name8))
+    return std::string();
+  return Name8;
+}
+
+PDB_TableType DIATable::getTableType() const {
+  CComBSTR Name16;
+  if (S_OK != Table->get_name(&Name16))
+    return PDB_TableType::TableInvalid;
+
+  if (Name16 == DiaTable_Symbols)
+    return PDB_TableType::Symbols;
+  if (Name16 == DiaTable_SrcFiles)
+    return PDB_TableType::SourceFiles;
+  if (Name16 == DiaTable_Sections)
+    return PDB_TableType::SectionContribs;
+  if (Name16 == DiaTable_LineNums)
+    return PDB_TableType::LineNumbers;
+  if (Name16 == DiaTable_SegMap)
+    return PDB_TableType::Segments;
+  if (Name16 == DiaTable_InjSrc)
+    return PDB_TableType::InjectedSources;
+  if (Name16 == DiaTable_FrameData)
+    return PDB_TableType::FrameData;
+  if (Name16 == DiaTable_InputAssemblyFiles)
+    return PDB_TableType::InputAssemblyFiles;
+  if (Name16 == DiaTable_Dbg)
+    return PDB_TableType::Dbg;
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
index df3f418..d23ee0a 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
@@ -286,6 +286,11 @@
   return {};
 }
 
+std::string NativeRawSymbol::getUndecoratedNameEx(
+    PDB_UndnameFlags Flags) const {
+  return {};
+}
+
 uint32_t NativeRawSymbol::getUnmodifiedTypeId() const {
   return 0;
 }
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
index 7be4c76..b01c2b5 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -245,3 +245,7 @@
 std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
   return nullptr;
 }
+
+std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
+  return nullptr;
+}
diff --git a/llvm/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp b/llvm/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
index 541fcda..b2b03fb 100644
--- a/llvm/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
@@ -15,6 +15,7 @@
 #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
 #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
 #include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/IPDBTable.h"
 
 using namespace llvm;
 using namespace llvm::pdb;
@@ -26,3 +27,5 @@
 IPDBRawSymbol::~IPDBRawSymbol() = default;
 
 IPDBLineNumber::~IPDBLineNumber() = default;
+
+IPDBTable::~IPDBTable() = default;