[Symbol] Use llvm::Expected when getting TypeSystems

Summary:
This commit achieves the following:
- Functions used to return a `TypeSystem *` return an
  `llvm::Expected<TypeSystem *>` now. This means that the result of a call
  is always checked, forcing clients to move more carefully.
- `TypeSystemMap::GetTypeSystemForLanguage` will either return an Error or a
  non-null pointer to a TypeSystem.

Reviewers: JDevlieghere, davide, compnerd

Subscribers: jdoerfert, lldb-commits

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

llvm-svn: 367360
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index a78f609..6ab45de 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -121,13 +121,6 @@
   return false;
 }
 
-static ClangASTContext &GetClangASTContext(ObjectFile &obj) {
-  TypeSystem *ts =
-      obj.GetModule()->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
-  lldbassert(ts);
-  return static_cast<ClangASTContext &>(*ts);
-}
-
 static llvm::Optional<clang::CallingConv>
 TranslateCallingConvention(llvm::codeview::CallingConvention conv) {
   using CC = llvm::codeview::CallingConvention;
@@ -209,8 +202,8 @@
   return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
 }
 
-PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index)
-    : m_index(index), m_clang(GetClangASTContext(obj)) {
+PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang)
+    : m_index(index), m_clang(clang) {
   BuildParentMap();
 }
 
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
index 593bf05..a4242e9 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -51,7 +51,7 @@
 class PdbAstBuilder {
 public:
   // Constructors and Destructors
-  PdbAstBuilder(ObjectFile &obj, PdbIndex &index);
+  PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang);
 
   lldb_private::CompilerDeclContext GetTranslationUnitDecl();
 
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 572ec7d..59ea31e 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -30,6 +30,7 @@
 #include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/Variable.h"
 #include "lldb/Symbol/VariableList.h"
+#include "lldb/Utility/Log.h"
 
 #include "llvm/DebugInfo/CodeView/CVRecord.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
@@ -321,12 +322,17 @@
   m_index->SetLoadAddress(m_obj_load_address);
   m_index->ParseSectionContribs();
 
-  TypeSystem *ts = m_obj_file->GetModule()->GetTypeSystemForLanguage(
+  auto ts_or_err = m_obj_file->GetModule()->GetTypeSystemForLanguage(
       lldb::eLanguageTypeC_plus_plus);
-  if (ts)
-    ts->SetSymbolFile(this);
-
-  m_ast = llvm::make_unique<PdbAstBuilder>(*m_obj_file, *m_index);
+  if (auto err = ts_or_err.takeError()) {
+    LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+                   std::move(err), "Failed to initialize");
+  } else {
+    ts_or_err->SetSymbolFile(this);
+    auto *clang = llvm::cast_or_null<ClangASTContext>(&ts_or_err.get());
+    lldbassert(clang);
+    m_ast = llvm::make_unique<PdbAstBuilder>(*m_obj_file, *m_index, *clang);
+  }
 }
 
 uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() {
@@ -1585,13 +1591,14 @@
   return {};
 }
 
-TypeSystem *
+llvm::Expected<TypeSystem &>
 SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
-  auto type_system =
+  auto type_system_or_err =
       m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
-  if (type_system)
-    type_system->SetSymbolFile(this);
-  return type_system;
+  if (type_system_or_err) {
+    type_system_or_err->SetSymbolFile(this);
+  }
+  return type_system_or_err;
 }
 
 ConstString SymbolFileNativePDB::GetPluginName() {
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 88bd5de..49b68ae 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -137,7 +137,8 @@
   size_t FindTypes(const std::vector<CompilerContext> &context, bool append,
                    TypeMap &types) override;
 
-  TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override;
+  llvm::Expected<TypeSystem &>
+  GetTypeSystemForLanguage(lldb::LanguageType language) override;
 
   CompilerDeclContext
   FindNamespace(ConstString name,