[Lldb-commits] [lldb] r314458 - [Expression parser] Setting to enable use of ExternalASTMerger

Sean Callanan via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 28 13:20:25 PDT 2017


Author: spyffe
Date: Thu Sep 28 13:20:25 2017
New Revision: 314458

URL: http://llvm.org/viewvc/llvm-project?rev=314458&view=rev
Log:
[Expression parser] Setting to enable use of ExternalASTMerger

This setting can be enabled like this at the target level:

(lldb) settings set target.experimental.use-modern-type-lookup true

This causes several new behaviors in the Clang expression parser:

- It completely disables use of ClangASTImporter.  None are created
  at all, and all users of it are now conditionalized on its
  presence.

- It instead constructs a per-expression ExternalASTMerger, which
  exists inside Clang and contains much of the type completion
  logic that hitherto lived in ExternalASTSource,
  ClangExpressionDeclMap, and ClangASTImporter.

- The expression parser uses this Merger as a backend for copying
  and completing types.

- It also constructs a persistent ExternalASTMerger which is
  connected to the Target's persistent AST context.

This is a major chunk of LLDB functionality moved into Clang.  It
can be tested in two ways:

1. For an individual debug session, enable the setting before
   running a target.

2. For the testsuite, change the option to be default-true.  This
   is done in Target.cpp's g_experimental_properties.  The
   testsuite is not yet clean with this, so I have not committed
   that switch.

I have filed a Bugzilla for extending the testsuite to allow
custom settings for all tests:
  https://bugs.llvm.org/show_bug.cgi?id=34771

I have also filed a Bugzilla for fixing the remaining testsuite
failures with this setting enabled:
  https://bugs.llvm.org/show_bug.cgi?id=34772

Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/include/lldb/Symbol/DeclVendor.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Target/Target.cpp

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Thu Sep 28 13:20:25 2017
@@ -25,6 +25,7 @@
 
 // Other libraries and framework includes
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ExternalASTMerger.h"
 #include "clang/AST/TemplateBase.h"
 #include "llvm/ADT/SmallVector.h"
 
@@ -964,7 +965,10 @@ public:
 
   clang::DeclarationName
   GetDeclarationName(const char *name, const CompilerType &function_clang_type);
-
+  
+  virtual const clang::ExternalASTMerger::OriginMap &GetOriginMap() {
+    return m_origins;
+  }
 protected:
   //------------------------------------------------------------------
   // Classes that inherit from ClangASTContext can see and modify these
@@ -990,6 +994,7 @@ protected:
     CompleteTagDeclCallback                         m_callback_tag_decl;
     CompleteObjCInterfaceDeclCallback               m_callback_objc_decl;
     void *                                          m_callback_baton;
+    clang::ExternalASTMerger::OriginMap             m_origins;
     uint32_t                                        m_pointer_byte_size;
     bool                                            m_ast_owned;
     bool                                            m_can_evaluate_expressions;
@@ -1023,7 +1028,12 @@ public:
                                       const char *name) override;
 
   PersistentExpressionState *GetPersistentExpressionState() override;
-
+  
+  clang::ExternalASTMerger &GetMergerUnchecked();
+  
+  const clang::ExternalASTMerger::OriginMap &GetOriginMap() override {
+    return GetMergerUnchecked().GetOrigins();
+  }
 private:
   lldb::TargetWP m_target_wp;
   lldb::ClangPersistentVariablesUP m_persistent_variables; ///< These are the

Modified: lldb/trunk/include/lldb/Symbol/DeclVendor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/DeclVendor.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/DeclVendor.h (original)
+++ lldb/trunk/include/lldb/Symbol/DeclVendor.h Thu Sep 28 13:20:25 2017
@@ -13,6 +13,8 @@
 #include "lldb/Core/ClangForward.h"
 #include "lldb/lldb-defines.h"
 
+#include "clang/AST/ExternalASTMerger.h"
+
 #include <vector>
 
 namespace lldb_private {
@@ -53,6 +55,15 @@ public:
                              uint32_t max_matches,
                              std::vector<clang::NamedDecl *> &decls) = 0;
 
+  //------------------------------------------------------------------
+  /// Interface for ExternalASTMerger.  Returns an ImporterSource 
+  /// allowing type completion.
+  ///
+  /// @return
+  ///     An ImporterSource for this DeclVendor.
+  //------------------------------------------------------------------
+  virtual clang::ExternalASTMerger::ImporterSource GetImporterSource() = 0;
+
 private:
   //------------------------------------------------------------------
   // For DeclVendor only

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Thu Sep 28 13:20:25 2017
@@ -196,6 +196,8 @@ public:
 
   void SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b);
 
+  bool GetUseModernTypeLookup() const;
+
 private:
   //------------------------------------------------------------------
   // Callbacks for m_launch_info.

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp Thu Sep 28 13:20:25 2017
@@ -51,8 +51,94 @@ private:
 };
 }
 
+ClangASTSource::ClangASTSource(const lldb::TargetSP &target)
+    : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
+      m_ast_context(NULL), m_active_lexical_decls(), m_active_lookups() {
+  if (!target->GetUseModernTypeLookup()) {
+    m_ast_importer_sp = m_target->GetClangASTImporter();
+  }
+}
+
+void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context,
+                                       clang::FileManager &file_manager,
+                                       bool is_shared_context) {
+  m_ast_context = &ast_context;
+  m_file_manager = &file_manager;
+  if (m_target->GetUseModernTypeLookup()) {
+    // Configure the ExternalASTMerger.  The merger needs to be able to import
+    // types from any source that we would do lookups in, which includes the
+    // persistent AST context as well as the modules and Objective-C runtime
+    // AST contexts.
+    
+    lldbassert(!m_merger_up);
+    clang::ExternalASTMerger::ImporterTarget target = {ast_context,
+                                                       file_manager};
+    std::vector<clang::ExternalASTMerger::ImporterSource> sources;
+    for (lldb::ModuleSP module_sp : m_target->GetImages().Modules()) {
+      if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>(
+              module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC))) {
+        lldbassert(module_ast_ctx->getASTContext());
+        lldbassert(module_ast_ctx->getFileManager());
+        sources.push_back({*module_ast_ctx->getASTContext(),
+                           *module_ast_ctx->getFileManager(),
+                           module_ast_ctx->GetOriginMap()
+        });
+      }
+    }
+
+    do {
+      lldb::ProcessSP process(m_target->GetProcessSP());
+
+      if (!process)
+        break;
+
+      ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+
+      if (!language_runtime)
+        break;
+
+      DeclVendor *runtime_decl_vendor = language_runtime->GetDeclVendor();
+
+      if (!runtime_decl_vendor)
+        break;
+
+      sources.push_back(runtime_decl_vendor->GetImporterSource());
+    } while (0);
+
+    do {
+      DeclVendor *modules_decl_vendor =
+          m_target->GetClangModulesDeclVendor();
+
+      if (!modules_decl_vendor)
+        break;
+
+      sources.push_back(modules_decl_vendor->GetImporterSource());
+    } while (0);
+    
+    if (!is_shared_context) {
+      // Update the scratch AST context's merger to reflect any new sources we
+      // might have come across since the last time an expression was parsed.
+      
+      auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>(
+          m_target->GetScratchClangASTContext());
+      
+      scratch_ast_context->GetMergerUnchecked().AddSources(sources);
+
+      sources.push_back({*scratch_ast_context->getASTContext(),
+                         *scratch_ast_context->getFileManager(),
+                         scratch_ast_context->GetOriginMap()});
+    } while (0);
+
+    m_merger_up =
+        llvm::make_unique<clang::ExternalASTMerger>(target, sources);
+  } else {
+    m_ast_importer_sp->InstallMapCompleter(&ast_context, *this);
+  }
+}
+
 ClangASTSource::~ClangASTSource() {
-  m_ast_importer_sp->ForgetDestination(m_ast_context);
+  if (m_ast_importer_sp)
+    m_ast_importer_sp->ForgetDestination(m_ast_context);
 
   // We are in the process of destruction, don't create clang ast context on
   // demand
@@ -69,7 +155,7 @@ ClangASTSource::~ClangASTSource() {
   if (!scratch_ast_context)
     return;
 
-  if (m_ast_context != scratch_ast_context)
+  if (m_ast_context != scratch_ast_context && m_ast_importer_sp)
     m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context);
 }
 
@@ -203,6 +289,13 @@ void ClangASTSource::CompleteType(TagDec
   m_active_lexical_decls.insert(tag_decl);
   ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
 
+  if (!m_ast_importer_sp) {
+    if (HasMerger()) {
+      GetMergerUnchecked().CompleteType(tag_decl);
+    }
+    return;
+  }
+
   if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
     // We couldn't complete the type.  Maybe there's a definition
     // somewhere else that can be completed.
@@ -336,6 +429,22 @@ void ClangASTSource::CompleteType(clang:
     ASTDumper dumper((Decl *)interface_decl);
     dumper.ToLog(log, "      [COID] ");
   }
+  
+  if (!m_ast_importer_sp) {
+    if (HasMerger()) {
+      ObjCInterfaceDecl *complete_iface_decl =
+        GetCompleteObjCInterface(interface_decl);
+      
+      if (complete_iface_decl && (complete_iface_decl != interface_decl)) {
+        m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()});
+      }
+
+      GetMergerUnchecked().CompleteType(interface_decl);
+    } else {
+      lldbassert(!"No mechanism for completing a type!"); 
+    }
+    return;
+  }  
 
   Decl *original_decl = NULL;
   ASTContext *original_ctx = NULL;
@@ -367,7 +476,7 @@ void ClangASTSource::CompleteType(clang:
 }
 
 clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface(
-    clang::ObjCInterfaceDecl *interface_decl) {
+    const clang::ObjCInterfaceDecl *interface_decl) {
   lldb::ProcessSP process(m_target->GetProcessSP());
 
   if (!process)
@@ -411,6 +520,22 @@ void ClangASTSource::FindExternalLexical
     const DeclContext *decl_context,
     llvm::function_ref<bool(Decl::Kind)> predicate,
     llvm::SmallVectorImpl<Decl *> &decls) {
+
+  if (HasMerger()) {
+    if (auto *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_context)) {
+      ObjCInterfaceDecl *complete_iface_decl =
+         GetCompleteObjCInterface(interface_decl);
+      
+      if (complete_iface_decl && (complete_iface_decl != interface_decl)) {
+        m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()});
+      }
+    }
+    return GetMergerUnchecked().FindExternalLexicalDecls(decl_context,
+                                                         predicate,
+                                                         decls);
+  } else if (!m_ast_importer_sp)
+    return;
+
   ClangASTMetrics::RegisterLexicalQuery();
 
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -507,8 +632,7 @@ void ClangASTSource::FindExternalLexical
                       decl->getDeclKindName(), ast_dumper.GetCString());
       }
 
-      Decl *copied_decl =
-          m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl);
+      Decl *copied_decl = CopyDecl(decl);
 
       if (!copied_decl)
         continue;
@@ -568,12 +692,31 @@ void ClangASTSource::FindExternalVisible
                   name.GetCString(), context.m_decl_context->getDeclKindName());
   }
 
+  if (HasMerger() && !isa<TranslationUnitDecl>(context.m_decl_context)
+      /* possibly handle NamespaceDecls here? */) {
+    if (auto *interface_decl =
+    dyn_cast<ObjCInterfaceDecl>(context.m_decl_context)) {
+      ObjCInterfaceDecl *complete_iface_decl =
+      GetCompleteObjCInterface(interface_decl);
+      
+      if (complete_iface_decl && (complete_iface_decl != interface_decl)) {
+        GetMergerUnchecked().ForceRecordOrigin(
+            interface_decl,
+            {complete_iface_decl, &complete_iface_decl->getASTContext()});
+      }
+    }
+
+    GetMergerUnchecked().FindExternalVisibleDeclsByName(context.m_decl_context,
+                                                context.m_decl_name);
+    return; // otherwise we may need to fall back
+  }
+
   context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap);
 
   if (const NamespaceDecl *namespace_context =
           dyn_cast<NamespaceDecl>(context.m_decl_context)) {
-    ClangASTImporter::NamespaceMapSP namespace_map =
-        m_ast_importer_sp->GetNamespaceMap(namespace_context);
+    ClangASTImporter::NamespaceMapSP namespace_map =  m_ast_importer_sp ?
+        m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr;
 
     if (log && log->GetVerbose())
       log->Printf("  CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
@@ -593,7 +736,7 @@ void ClangASTSource::FindExternalVisible
 
       FindExternalVisibleDecls(context, i->first, i->second, current_id);
     }
-  } else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) {
+  } else if (isa<ObjCInterfaceDecl>(context.m_decl_context) && !HasMerger()) {
     FindObjCPropertyAndIvarDecls(context);
   } else if (!isa<TranslationUnitDecl>(context.m_decl_context)) {
     // we shouldn't be getting FindExternalVisibleDecls calls for these
@@ -677,7 +820,7 @@ void ClangASTSource::FindExternalVisible
                       module_sp->GetFileSpec().GetFilename().GetCString());
       }
     }
-  } else {
+  } else if (!HasMerger()) {
     const ModuleList &target_images = m_target->GetImages();
     std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
 
@@ -780,9 +923,7 @@ void ClangASTSource::FindExternalVisible
           if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
               llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
               llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
-            clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
-                m_ast_context, &decl_from_modules->getASTContext(),
-                decl_from_modules);
+            clang::Decl *copied_decl = CopyDecl(decl_from_modules);
             clang::NamedDecl *copied_named_decl =
                 copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
 
@@ -837,8 +978,7 @@ void ClangASTSource::FindExternalVisible
               current_id, name.GetCString());
         }
 
-        clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
-            m_ast_context, &decls[0]->getASTContext(), decls[0]);
+        clang::Decl *copied_decl = CopyDecl(decls[0]);
         clang::NamedDecl *copied_named_decl =
             copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
 
@@ -881,7 +1021,7 @@ public:
   DeclFromParser() : TaggedASTDecl<D>() {}
   DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) {}
 
-  DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
+  DeclFromUser<D> GetOrigin(ClangASTSource &source);
 };
 
 template <class D> class DeclFromUser : public TaggedASTDecl<D> {
@@ -889,32 +1029,29 @@ public:
   DeclFromUser() : TaggedASTDecl<D>() {}
   DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) {}
 
-  DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
+  DeclFromParser<D> Import(ClangASTSource &source);
 };
 
 template <class D>
-DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTImporter *importer) {
+DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTSource &source) {
   DeclFromUser<> origin_decl;
-  importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
+  source.ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
   if (origin_decl.IsInvalid())
     return DeclFromUser<D>();
   return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
 }
 
 template <class D>
-DeclFromParser<D> DeclFromUser<D>::Import(ClangASTImporter *importer,
-                                          ASTContext &dest_ctx) {
-  DeclFromParser<> parser_generic_decl(
-      importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
+DeclFromParser<D> DeclFromUser<D>::Import(ClangASTSource &source) {
+  DeclFromParser<> parser_generic_decl(source.CopyDecl(this->decl));
   if (parser_generic_decl.IsInvalid())
     return DeclFromParser<D>();
   return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
 }
 
-static bool FindObjCMethodDeclsWithOrigin(
+bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
     unsigned int current_id, NameSearchContext &context,
-    ObjCInterfaceDecl *original_interface_decl, clang::ASTContext *ast_context,
-    ClangASTImporter *ast_importer, const char *log_info) {
+    ObjCInterfaceDecl *original_interface_decl, const char *log_info) {
   const DeclarationName &decl_name(context.m_decl_name);
   clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
 
@@ -973,8 +1110,7 @@ static bool FindObjCMethodDeclsWithOrigi
     if (!result_method)
       continue;
 
-    Decl *copied_decl = ast_importer->CopyDecl(
-        ast_context, &result_method->getASTContext(), result_method);
+    Decl *copied_decl = CopyDecl(result_method);
 
     if (!copied_decl)
       continue;
@@ -1001,6 +1137,21 @@ static bool FindObjCMethodDeclsWithOrigi
 void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
+  if (HasMerger()) {
+    if (auto *interface_decl = dyn_cast<ObjCInterfaceDecl>(context.m_decl_context)) {
+      ObjCInterfaceDecl *complete_iface_decl =
+          GetCompleteObjCInterface(interface_decl);
+      
+      if (complete_iface_decl && (complete_iface_decl != context.m_decl_context)) {
+        m_merger_up->ForceRecordOrigin(interface_decl, {complete_iface_decl, &complete_iface_decl->getASTContext()});
+      }
+    }
+    
+    GetMergerUnchecked().FindExternalVisibleDeclsByName(context.m_decl_context,
+                                                        context.m_decl_name);
+    return;
+  }
+
   static unsigned int invocation_id = 0;
   unsigned int current_id = invocation_id++;
 
@@ -1027,8 +1178,7 @@ void ClangASTSource::FindObjCMethodDecls
         dyn_cast<ObjCInterfaceDecl>(original_decl);
 
     if (FindObjCMethodDeclsWithOrigin(current_id, context,
-                                      original_interface_decl, m_ast_context,
-                                      m_ast_importer_sp.get(), "at origin"))
+                                      original_interface_decl, "at origin"))
       return; // found it, no need to look any further
   } while (0);
 
@@ -1166,8 +1316,7 @@ void ClangASTSource::FindObjCMethodDecls
         continue;
 
       if (found_interface_decl->getName() == interface_decl->getName()) {
-        Decl *copied_decl = m_ast_importer_sp->CopyDecl(
-            m_ast_context, &method_decl->getASTContext(), method_decl);
+        Decl *copied_decl = CopyDecl(method_decl);
 
         if (!copied_decl)
           continue;
@@ -1216,7 +1365,6 @@ void ClangASTSource::FindObjCMethodDecls
                   static_cast<void *>(&complete_iface_decl->getASTContext()));
 
     FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl,
-                                  m_ast_context, m_ast_importer_sp.get(),
                                   "in debug info");
 
     return;
@@ -1244,8 +1392,7 @@ void ClangASTSource::FindObjCMethodDecls
         break;
 
       if (FindObjCMethodDeclsWithOrigin(
-              current_id, context, interface_decl_from_modules, m_ast_context,
-              m_ast_importer_sp.get(), "in modules"))
+              current_id, context, interface_decl_from_modules, "in modules"))
         return;
     }
   } while (0);
@@ -1284,14 +1431,12 @@ void ClangASTSource::FindObjCMethodDecls
       break;
 
     FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl,
-                                  m_ast_context, m_ast_importer_sp.get(),
                                   "in runtime");
   } while (0);
 }
 
 static bool FindObjCPropertyAndIvarDeclsWithOrigin(
-    unsigned int current_id, NameSearchContext &context,
-    clang::ASTContext &ast_context, ClangASTImporter *ast_importer,
+    unsigned int current_id, NameSearchContext &context, ClangASTSource &source,
     DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) {
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
@@ -1311,7 +1456,7 @@ static bool FindObjCPropertyAndIvarDecls
 
   if (origin_property_decl.IsValid()) {
     DeclFromParser<ObjCPropertyDecl> parser_property_decl(
-        origin_property_decl.Import(ast_importer, ast_context));
+        origin_property_decl.Import(source));
     if (parser_property_decl.IsValid()) {
       if (log) {
         ASTDumper dumper((Decl *)parser_property_decl.decl);
@@ -1329,7 +1474,7 @@ static bool FindObjCPropertyAndIvarDecls
 
   if (origin_ivar_decl.IsValid()) {
     DeclFromParser<ObjCIvarDecl> parser_ivar_decl(
-        origin_ivar_decl.Import(ast_importer, ast_context));
+        origin_ivar_decl.Import(source));
     if (parser_ivar_decl.IsValid()) {
       if (log) {
         ASTDumper dumper((Decl *)parser_ivar_decl.decl);
@@ -1354,7 +1499,7 @@ void ClangASTSource::FindObjCPropertyAnd
   DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(
       cast<ObjCInterfaceDecl>(context.m_decl_context));
   DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(
-      parser_iface_decl.GetOrigin(m_ast_importer_sp.get()));
+      parser_iface_decl.GetOrigin(*this));
 
   ConstString class_name(parser_iface_decl->getNameAsString().c_str());
 
@@ -1366,8 +1511,7 @@ void ClangASTSource::FindObjCPropertyAnd
                 context.m_decl_name.getAsString().c_str());
 
   if (FindObjCPropertyAndIvarDeclsWithOrigin(
-          current_id, context, *m_ast_context, m_ast_importer_sp.get(),
-          origin_iface_decl))
+          current_id, context, *this, origin_iface_decl))
     return;
 
   if (log)
@@ -1403,8 +1547,7 @@ void ClangASTSource::FindObjCPropertyAnd
                   static_cast<const void *>(complete_iface_decl.decl),
                   static_cast<void *>(&complete_iface_decl->getASTContext()));
 
-    FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *m_ast_context,
-                                           m_ast_importer_sp.get(),
+    FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
                                            complete_iface_decl);
 
     return;
@@ -1441,9 +1584,8 @@ void ClangASTSource::FindObjCPropertyAnd
           static_cast<const void *>(interface_decl_from_modules.decl),
           static_cast<void *>(&interface_decl_from_modules->getASTContext()));
 
-    if (FindObjCPropertyAndIvarDeclsWithOrigin(
-            current_id, context, *m_ast_context, m_ast_importer_sp.get(),
-            interface_decl_from_modules))
+    if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
+                                               interface_decl_from_modules))
       return;
   } while (0);
 
@@ -1489,8 +1631,7 @@ void ClangASTSource::FindObjCPropertyAnd
           static_cast<void *>(&interface_decl_from_runtime->getASTContext()));
 
     if (FindObjCPropertyAndIvarDeclsWithOrigin(
-            current_id, context, *m_ast_context, m_ast_importer_sp.get(),
-            interface_decl_from_runtime))
+            current_id, context, *this, interface_decl_from_runtime))
       return;
   } while (0);
 }
@@ -1501,7 +1642,7 @@ typedef llvm::DenseMap<const CXXRecordDe
 template <class D, class O>
 static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map,
                             llvm::DenseMap<const D *, O> &source_map,
-                            ClangASTImporter *importer, ASTContext &dest_ctx) {
+                            ClangASTSource &source) {
   // When importing fields into a new record, clang has a hard requirement that
   // fields be imported in field offset order.  Since they are stored in a
   // DenseMap
@@ -1522,7 +1663,7 @@ static bool ImportOffsetMap(llvm::DenseM
 
   for (const auto &item : sorted_items) {
     DeclFromUser<D> user_decl(const_cast<D *>(item.first));
-    DeclFromParser<D> parser_decl(user_decl.Import(importer, dest_ctx));
+    DeclFromParser<D> parser_decl(user_decl.Import(source));
     if (parser_decl.IsInvalid())
       return false;
     destination_map.insert(
@@ -1599,7 +1740,7 @@ bool ClangASTSource::layoutRecordType(co
 
   DeclFromParser<const RecordDecl> parser_record(record);
   DeclFromUser<const RecordDecl> origin_record(
-      parser_record.GetOrigin(m_ast_importer_sp.get()));
+      parser_record.GetOrigin(*this));
 
   if (origin_record.IsInvalid())
     return false;
@@ -1635,7 +1776,7 @@ bool ClangASTSource::layoutRecordType(co
     field_idx++;
   }
 
-  ASTContext &parser_ast_context(record->getASTContext());
+  lldbassert(&record->getASTContext() == m_ast_context);
 
   DeclFromUser<const CXXRecordDecl> origin_cxx_record(
       DynCast<const CXXRecordDecl>(origin_record));
@@ -1648,12 +1789,10 @@ bool ClangASTSource::layoutRecordType(co
       return false;
   }
 
-  if (!ImportOffsetMap(field_offsets, origin_field_offsets,
-                       m_ast_importer_sp.get(), parser_ast_context) ||
-      !ImportOffsetMap(base_offsets, origin_base_offsets,
-                       m_ast_importer_sp.get(), parser_ast_context) ||
+  if (!ImportOffsetMap(field_offsets, origin_field_offsets, *this) ||
+      !ImportOffsetMap(base_offsets, origin_base_offsets, *this) ||
       !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets,
-                       m_ast_importer_sp.get(), parser_ast_context))
+                       *this))
     return false;
 
   size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
@@ -1817,8 +1956,7 @@ NamespaceDecl *ClangASTSource::AddNamesp
   if (!src_namespace_decl)
     return nullptr;
 
-  Decl *copied_decl =
-      m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl);
+  Decl *copied_decl = CopyDecl(src_namespace_decl);
 
   if (!copied_decl)
     return nullptr;
@@ -1836,6 +1974,54 @@ NamespaceDecl *ClangASTSource::AddNamesp
   return dyn_cast<NamespaceDecl>(copied_decl);
 }
 
+clang::QualType ClangASTSource::CopyTypeWithMerger(
+    clang::ASTContext &from_context,
+    clang::ExternalASTMerger &merger,
+    clang::QualType type) {
+  if (!merger.HasImporterForOrigin(from_context)) {
+    lldbassert(!"Couldn't find the importer for a source context!");
+    return QualType();
+  }
+
+  return merger.ImporterForOrigin(from_context).Import(type);
+}
+
+clang::Decl *ClangASTSource::CopyDecl(Decl *src_decl) {
+  clang::ASTContext &from_context = src_decl->getASTContext();
+  if (m_ast_importer_sp) {
+    return m_ast_importer_sp->CopyDecl(m_ast_context, &from_context, src_decl);
+  } else if (m_merger_up) {
+    if (!m_merger_up->HasImporterForOrigin(from_context)) {
+      lldbassert(!"Couldn't find the importer for a source context!");
+      return nullptr;
+    }
+
+    return m_merger_up->ImporterForOrigin(from_context).Import(src_decl);
+  } else {
+    lldbassert("No mechanism for copying a decl!");
+    return nullptr;
+  }
+}
+
+bool ClangASTSource::ResolveDeclOrigin(const clang::Decl *decl,
+                                       clang::Decl **original_decl,
+                                       clang::ASTContext **original_ctx) {
+  if (m_ast_importer_sp) {
+    return m_ast_importer_sp->ResolveDeclOrigin(decl, original_decl,
+                                                original_ctx);
+  } else if (m_merger_up) {
+    return false; // Implement this correctly in ExternalASTMerger
+  } else {
+    // this can happen early enough that no ExternalASTSource is installed.
+    return false;
+  }
+}
+
+clang::ExternalASTMerger &ClangASTSource::GetMergerUnchecked() {
+  lldbassert(m_merger_up);
+  return *m_merger_up;
+}
+
 CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
   ClangASTContext *src_ast =
       llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
@@ -1846,9 +2032,20 @@ CompilerType ClangASTSource::GuardedCopy
 
   SetImportInProgress(true);
 
-  QualType copied_qual_type =
-      m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(),
-                                  ClangUtil::GetQualType(src_type));
+  QualType copied_qual_type;
+
+  if (m_ast_importer_sp) {
+    copied_qual_type =
+        m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(),
+                                    ClangUtil::GetQualType(src_type));
+  } else if (m_merger_up) {
+    copied_qual_type =
+        CopyTypeWithMerger(*src_ast->getASTContext(), *m_merger_up,
+                 ClangUtil::GetQualType(src_type));
+  } else {
+    lldbassert("No mechanism for copying a type!");
+    return CompilerType();
+  }
 
   SetImportInProgress(false);
 

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h Thu Sep 28 13:20:25 2017
@@ -16,6 +16,7 @@
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
 #include "lldb/Symbol/CompilerType.h"
 #include "lldb/Target/Target.h"
+#include "clang/AST/ExternalASTMerger.h"
 #include "clang/Basic/IdentifierTable.h"
 
 #include "llvm/ADT/SmallSet.h"
@@ -41,14 +42,10 @@ public:
   ///
   /// Initializes class variables.
   ///
-  /// @param[in] declMap
-  ///     A reference to the LLDB object that handles entity lookup.
+  /// @param[in] target
+  ///     A reference to the target containing debug information to use.
   //------------------------------------------------------------------
-  ClangASTSource(const lldb::TargetSP &target)
-      : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
-        m_ast_context(NULL), m_active_lexical_decls(), m_active_lookups() {
-    m_ast_importer_sp = m_target->GetClangASTImporter();
-  }
+  ClangASTSource(const lldb::TargetSP &target);
 
   //------------------------------------------------------------------
   /// Destructor
@@ -70,10 +67,9 @@ public:
   }
   void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
 
-  void InstallASTContext(clang::ASTContext *ast_context) {
-    m_ast_context = ast_context;
-    m_ast_importer_sp->InstallMapCompleter(ast_context, *this);
-  }
+  void InstallASTContext(clang::ASTContext &ast_context,
+                         clang::FileManager &file_manager,
+                         bool is_shared_context = false);
 
   //
   // APIs for ExternalASTSource
@@ -313,7 +309,7 @@ protected:
   ///     the complete interface otherwise.
   //------------------------------------------------------------------
   clang::ObjCInterfaceDecl *
-  GetCompleteObjCInterface(clang::ObjCInterfaceDecl *interface_decl);
+  GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);
 
   //------------------------------------------------------------------
   /// Find all entities matching a given name in a given module,
@@ -376,7 +372,7 @@ protected:
   //------------------------------------------------------------------
   CompilerType GuardedCopyType(const CompilerType &src_type);
 
-  
+public:
   //------------------------------------------------------------------
   /// Returns true if a name should be ignored by name lookup.
   ///
@@ -392,6 +388,73 @@ protected:
   //------------------------------------------------------------------
   bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
 
+public:
+  //------------------------------------------------------------------
+  /// Copies a single Decl into the parser's AST context.
+  ///
+  /// @param[in] src_decl
+  ///     The Decl to copy.
+  ///
+  /// @return
+  ///     A copy of the Decl in m_ast_context, or NULL if the copy failed.
+  //------------------------------------------------------------------
+  clang::Decl *CopyDecl(clang::Decl *src_decl);
+                         
+  //------------------------------------------------------------------
+  /// Copies a single Type to the target of the given ExternalASTMerger.
+  ///
+  /// @param[in] src_context
+  ///     The ASTContext containing the type.
+  ///
+  /// @param[in] merger
+  ///     The merger to use.  This isn't just *m_merger_up because it might be
+  ///     the persistent AST context's merger.
+  ///
+  /// @param[in] type
+  ///     The type to copy.
+  ///
+  /// @return
+  ///     A copy of the Type in the merger's target context.
+  //------------------------------------------------------------------
+	clang::QualType CopyTypeWithMerger(clang::ASTContext &src_context,
+                                     clang::ExternalASTMerger &merger,
+                                     clang::QualType type);
+
+  //------------------------------------------------------------------
+  /// Determined the origin of a single Decl, if it can be found.
+  ///
+  /// @param[in] decl
+  ///     The Decl whose origin is to be found.
+  ///
+  /// @param[out] original_decl
+  ///     A pointer whose target is filled in with the original Decl.
+  ///
+  /// @param[in] original_ctx
+  ///     A pointer whose target is filled in with the original's ASTContext.
+  ///
+  /// @return
+  ///     True if lookup succeeded; false otherwise.
+  //------------------------------------------------------------------
+  bool ResolveDeclOrigin(const clang::Decl *decl, clang::Decl **original_decl,
+                         clang::ASTContext **original_ctx);
+ 
+  //------------------------------------------------------------------
+  /// Returns m_merger_up.  Only call this if the target is configured to use
+  /// modern lookup,
+  //------------------------------------------------------------------
+	clang::ExternalASTMerger &GetMergerUnchecked();
+ 
+  //------------------------------------------------------------------
+  /// Returns true if there is a merger.  This only occurs if the target is
+  /// using modern lookup.
+  //------------------------------------------------------------------
+  bool HasMerger() { return (bool)m_merger_up; }
+
+protected:
+  bool FindObjCMethodDeclsWithOrigin(
+      unsigned int current_id, NameSearchContext &context,
+      clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
+
   friend struct NameSearchContext;
 
   bool m_import_in_progress;
@@ -401,7 +464,11 @@ protected:
       m_target; ///< The target to use in finding variables and types.
   clang::ASTContext
       *m_ast_context; ///< The AST context requests are coming in for.
+  clang::FileManager
+      *m_file_manager; ///< The file manager paired with the AST context.
   lldb::ClangASTImporterSP m_ast_importer_sp; ///< The target's AST importer.
+  std::unique_ptr<clang::ExternalASTMerger> m_merger_up;
+      ///< The ExternalASTMerger for this parse.
   std::set<const clang::Decl *> m_active_lexical_decls;
   std::set<const char *> m_active_lookups;
 };

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp Thu Sep 28 13:20:25 2017
@@ -48,8 +48,10 @@
 #include "lldb/lldb-private.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTImporter.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclarationName.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 
 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
 
@@ -178,6 +180,134 @@ ClangExpressionDeclMap::TargetInfo Clang
   return ret;
 }
 
+namespace {
+/// This class walks an AST and ensures that all DeclContexts defined inside the
+/// current source file are properly complete.
+///
+/// This is used to ensure that persistent types defined in the current source
+/// file migrate completely to the persistent AST context before they are
+/// reused.  If that didn't happen, it would be impoossible to complete them
+/// because their origin would be gone.
+///
+/// The stragtegy used by this class is to check the SourceLocation (to be
+/// specific, the FileID) and see if it's the FileID for the current expression.
+/// Alternate strategies could include checking whether an ExternalASTMerger,
+/// set up to not have the current context as a source, can find an original for
+/// the type.
+class Completer : public clang::RecursiveASTVisitor<Completer> {
+private:
+  clang::ASTImporter &m_exporter;             /// Used to import Decl contents
+  clang::FileID m_file;                       /// The file that's going away
+  llvm::DenseSet<clang::Decl *> m_completed;  /// Visited Decls, to avoid cycles
+
+  bool ImportAndCheckCompletable(clang::Decl *decl) {
+    (void)m_exporter.Import(decl);
+    if (m_completed.count(decl))
+      return false;
+    if (!llvm::isa<DeclContext>(decl))
+      return false;
+    const clang::SourceLocation loc = decl->getLocation();
+    if (!loc.isValid())
+      return false;
+    const clang::FileID file =
+        m_exporter.getFromContext().getSourceManager().getFileID(loc);
+    if (file != m_file)
+      return false;
+    // We are assuming the Decl was parsed in this very expression, so it should
+    // not have external storage.
+    lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage());
+    return true;
+  }
+
+  void Complete(clang::Decl *decl) {
+    m_completed.insert(decl);
+    auto *decl_context = llvm::cast<DeclContext>(decl);
+    (void)m_exporter.Import(decl);
+    m_exporter.CompleteDecl(decl);
+    for (Decl *child : decl_context->decls())
+      if (ImportAndCheckCompletable(child))
+        Complete(child);
+  }
+
+  void MaybeComplete(clang::Decl *decl) {
+    if (ImportAndCheckCompletable(decl))
+      Complete(decl);
+  }
+
+public:
+  Completer(clang::ASTImporter &exporter, clang::FileID file)
+      : m_exporter(exporter), m_file(file) {}
+  
+  // Implements the RecursiveASTVisitor's core API.  It is called on each Decl
+  // that the RecursiveASTVisitor encounters, and returns true if the traversal
+  // should continue.
+  bool VisitDecl(clang::Decl *decl) {
+    MaybeComplete(decl);
+    return true;
+  }
+};
+}
+
+static void CompleteAllDeclContexts(clang::ASTImporter &exporter,
+                                    clang::FileID file,
+                                    clang::QualType root) {
+  clang::QualType canonical_type = root.getCanonicalType();
+  if (clang::TagDecl *tag_decl = canonical_type->getAsTagDecl()) {
+    Completer(exporter, file).TraverseDecl(tag_decl);
+  } else if (auto interface_type = llvm::dyn_cast<ObjCInterfaceType>(
+                 canonical_type.getTypePtr())) {
+    Completer(exporter, file).TraverseDecl(interface_type->getDecl());
+  } else {
+    Completer(exporter, file).TraverseType(canonical_type);
+  }
+}
+
+static clang::QualType ExportAllDeclaredTypes(
+    clang::ExternalASTMerger &merger,
+    clang::ASTContext &source, clang::FileManager &source_file_manager,
+    const clang::ExternalASTMerger::OriginMap &source_origin_map,
+    clang::FileID file, clang::QualType root) {
+  clang::ExternalASTMerger::ImporterSource importer_source =
+      { source, source_file_manager, source_origin_map };
+  merger.AddSources(importer_source);
+  clang::ASTImporter &exporter = merger.ImporterForOrigin(source);
+  CompleteAllDeclContexts(exporter, file, root);
+  clang::QualType ret = exporter.Import(root);
+  merger.RemoveSources(importer_source);
+  return ret;
+}
+
+TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
+                                                ClangASTContext &source,
+                                                TypeFromParser parser_type) {
+  assert (&target == m_target->GetScratchClangASTContext());
+  assert ((TypeSystem*)&source == parser_type.GetTypeSystem());
+  assert (source.getASTContext() == m_ast_context);
+  
+  if (m_ast_importer_sp) {
+    return TypeFromUser(m_ast_importer_sp->DeportType(
+                            target.getASTContext(), source.getASTContext(),
+                            parser_type.GetOpaqueQualType()),
+                        &target);
+  } else if (m_merger_up) {
+    clang::FileID source_file =
+        source.getASTContext()->getSourceManager().getFileID(
+            source.getASTContext()->getTranslationUnitDecl()->getLocation());
+    auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>(
+        m_target->GetScratchClangASTContext());
+    clang::QualType exported_type = ExportAllDeclaredTypes(
+        scratch_ast_context->GetMergerUnchecked(),
+        *source.getASTContext(), *source.getFileManager(),
+        m_merger_up->GetOrigins(),
+        source_file,
+        clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType()));
+    return TypeFromUser(exported_type.getAsOpaquePtr(), &target);
+  } else {
+    lldbassert(!"No mechanism for deporting a type!");
+    return TypeFromUser();
+  }
+}
+
 bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
                                                    const ConstString &name,
                                                    TypeFromParser parser_type,
@@ -198,12 +328,8 @@ bool ClangExpressionDeclMap::AddPersiste
     if (target == nullptr)
       return false;
 
-    ClangASTContext *context(target->GetScratchClangASTContext());
-
-    TypeFromUser user_type(m_ast_importer_sp->DeportType(
-                               context->getASTContext(), ast->getASTContext(),
-                               parser_type.GetOpaqueQualType()),
-                           context);
+    TypeFromUser user_type =
+        DeportType(*target->GetScratchClangASTContext(), *ast, parser_type);
 
     uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
         user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
@@ -240,10 +366,7 @@ bool ClangExpressionDeclMap::AddPersiste
 
   ClangASTContext *context(target->GetScratchClangASTContext());
 
-  TypeFromUser user_type(m_ast_importer_sp->DeportType(
-                             context->getASTContext(), ast->getASTContext(),
-                             parser_type.GetOpaqueQualType()),
-                         context);
+  TypeFromUser user_type = DeportType(*context, *ast, parser_type);
 
   if (!user_type.GetOpaqueQualType()) {
     if (log)
@@ -688,16 +811,18 @@ void ClangExpressionDeclMap::FindExterna
     }
 
     ClangASTImporter::NamespaceMapSP namespace_map =
-        m_ast_importer_sp->GetNamespaceMap(namespace_context);
+        m_ast_importer_sp
+            ? m_ast_importer_sp->GetNamespaceMap(namespace_context)
+            : ClangASTImporter::NamespaceMapSP();
+
+    if (!namespace_map)
+      return;
 
     if (log && log->GetVerbose())
       log->Printf("  CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
                   current_id, static_cast<void *>(namespace_map.get()),
                   (int)namespace_map->size());
-
-    if (!namespace_map)
-      return;
-
+    
     for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
                                                   e = namespace_map->end();
          i != e; ++i) {
@@ -775,8 +900,7 @@ void ClangExpressionDeclMap::FindExterna
       if (!persistent_decl)
         break;
 
-      Decl *parser_persistent_decl = m_ast_importer_sp->CopyDecl(
-          m_ast_context, scratch_ast_context, persistent_decl);
+      Decl *parser_persistent_decl = CopyDecl(persistent_decl);
 
       if (!parser_persistent_decl)
         break;
@@ -1320,8 +1444,7 @@ void ClangExpressionDeclMap::FindExterna
         for (clang::NamedDecl *decl : decls_from_modules) {
           if (llvm::isa<clang::FunctionDecl>(decl)) {
             clang::NamedDecl *copied_decl =
-                llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(
-                    m_ast_context, &decl->getASTContext(), decl));
+                llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
             if (copied_decl) {
               context.AddNamedDecl(copied_decl);
               context.m_found.function_with_type_info = true;
@@ -1363,9 +1486,7 @@ void ClangExpressionDeclMap::FindExterna
                           current_id, name.GetCString());
             }
 
-            clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
-                m_ast_context, &decl_from_modules->getASTContext(),
-                decl_from_modules);
+            clang::Decl *copied_decl = CopyDecl(decl_from_modules);
             clang::FunctionDecl *copied_function_decl =
                 copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
                             : nullptr;
@@ -1392,9 +1513,7 @@ void ClangExpressionDeclMap::FindExterna
                           current_id, name.GetCString());
             }
 
-            clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
-                m_ast_context, &decl_from_modules->getASTContext(),
-                decl_from_modules);
+            clang::Decl *copied_decl = CopyDecl(decl_from_modules);
             clang::VarDecl *copied_var_decl =
                 copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
                             : nullptr;
@@ -1753,7 +1872,9 @@ bool ClangExpressionDeclMap::ResolveUnkn
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
   Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
 
-  ClangASTContext *scratch_ast_context = target->GetScratchClangASTContext();
+  ClangASTContextForExpressions *scratch_ast_context =
+      static_cast<ClangASTContextForExpressions*>(
+          target->GetScratchClangASTContext());
 
   for (size_t index = 0, num_entities = m_found_entities.GetSize();
        index < num_entities; ++index) {
@@ -1784,9 +1905,20 @@ bool ClangExpressionDeclMap::ResolveUnkn
           var_type.getAsOpaquePtr(),
           ClangASTContext::GetASTContext(&var_decl->getASTContext()));
 
-      lldb::opaque_compiler_type_t copied_type = m_ast_importer_sp->CopyType(
-          scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
-          var_type.getAsOpaquePtr());
+      lldb::opaque_compiler_type_t copied_type = 0;
+      if (m_ast_importer_sp) {
+        copied_type = m_ast_importer_sp->CopyType(
+            scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
+            var_type.getAsOpaquePtr());
+      } else if (HasMerger()) {
+        copied_type = CopyTypeWithMerger(
+            var_decl->getASTContext(),
+            scratch_ast_context->GetMergerUnchecked(),
+            var_type).getAsOpaquePtr();
+      } else {
+        lldbassert(!"No mechanism to copy a resolved unknown type!");
+        return false;
+      }
 
       if (!copied_type) {
         if (log)
@@ -1896,9 +2028,7 @@ void ClangExpressionDeclMap::AddOneFunct
               src_function_decl->getTemplateSpecializationInfo()->getTemplate();
           clang::FunctionTemplateDecl *copied_function_template =
               llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(
-                 m_ast_importer_sp->CopyDecl(m_ast_context,
-                                             src_ast->getASTContext(),
-                                             function_template));
+                  CopyDecl(function_template));
           if (copied_function_template) {
             if (log) {
               ASTDumper ast_dumper((clang::Decl *)copied_function_template);
@@ -1919,9 +2049,7 @@ void ClangExpressionDeclMap::AddOneFunct
         } else if (src_function_decl) {
           if (clang::FunctionDecl *copied_function_decl =
                   llvm::dyn_cast_or_null<clang::FunctionDecl>(
-                      m_ast_importer_sp->CopyDecl(m_ast_context,
-                                                  src_ast->getASTContext(),
-                                                  src_function_decl))) {
+                       CopyDecl(src_function_decl))) {
             if (log) {
               ASTDumper ast_dumper((clang::Decl *)copied_function_decl);
 

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h Thu Sep 28 13:20:25 2017
@@ -613,6 +613,23 @@ private:
   void AddThisType(NameSearchContext &context, TypeFromUser &type,
                    unsigned int current_id);
 
+  //------------------------------------------------------------------
+  /// Move a type out of the current ASTContext into another, but make sure to
+  /// export all components of the type also.
+  ///
+  /// @param[in] target
+  ///     The ClangASTContext to move to.
+  /// @param[in] source
+  ///     The ClangASTContext to move from.  This is assumed to be going away.
+  /// @param[in] parser_type
+  ///     The type as it appears in the source context.
+  ///
+  /// @return
+  ///     Returns the moved type, or an empty type if there was a problem.
+  //------------------------------------------------------------------
+  TypeFromUser DeportType(ClangASTContext &target, ClangASTContext &source,
+                          TypeFromParser parser_type);
+
   ClangASTContext *GetClangASTContext();
 };
 

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp Thu Sep 28 13:20:25 2017
@@ -526,7 +526,7 @@ ClangExpressionParser::ClangExpressionPa
   if (decl_map) {
     llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source(
         decl_map->CreateProxy());
-    decl_map->InstallASTContext(ast_context.get());
+    decl_map->InstallASTContext(*ast_context, m_compiler->getFileManager());
     ast_context->setExternalSource(ast_source);
   }
 

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp Thu Sep 28 13:20:25 2017
@@ -85,6 +85,7 @@ public:
   void ForEachMacro(const ModuleVector &modules,
                     std::function<bool(const std::string &)> handler) override;
 
+  clang::ExternalASTMerger::ImporterSource GetImporterSource() override;
 private:
   void
   ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports,
@@ -109,6 +110,7 @@ private:
   typedef std::set<ModuleID> ImportedModuleSet;
   ImportedModuleMap m_imported_modules;
   ImportedModuleSet m_user_imported_modules;
+  const clang::ExternalASTMerger::OriginMap m_origin_map;
 };
 } // anonymous namespace
 
@@ -548,6 +550,12 @@ ClangModulesDeclVendorImpl::DoGetModule(
                                          is_inclusion_directive);
 }
 
+clang::ExternalASTMerger::ImporterSource
+ClangModulesDeclVendorImpl::GetImporterSource() {
+  return {m_compiler_instance->getASTContext(),
+          m_compiler_instance->getFileManager(), m_origin_map};
+}
+
 static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";
 
 lldb_private::ClangModulesDeclVendor *

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp Thu Sep 28 13:20:25 2017
@@ -653,3 +653,11 @@ AppleObjCDeclVendor::FindDecls(const Con
 
   return ret;
 }
+
+clang::ExternalASTMerger::ImporterSource
+AppleObjCDeclVendor::GetImporterSource() {
+        return {*m_ast_ctx.getASTContext(),
+                *m_ast_ctx.getFileManager(),
+                m_ast_ctx.GetOriginMap()
+        };
+}

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h Thu Sep 28 13:20:25 2017
@@ -30,6 +30,8 @@ public:
   uint32_t FindDecls(const ConstString &name, bool append, uint32_t max_matches,
                      std::vector<clang::NamedDecl *> &decls) override;
 
+  clang::ExternalASTMerger::ImporterSource GetImporterSource() override;
+
   friend class AppleObjCExternalASTSource;
 
 private:

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Thu Sep 28 13:20:25 2017
@@ -596,8 +596,9 @@ lldb::TypeSystemSP ClangASTContext::Crea
           ast_sp->SetArchitecture(fixed_arch);
           ast_sp->m_scratch_ast_source_ap.reset(
               new ClangASTSource(target->shared_from_this()));
+          lldbassert(ast_sp->getFileManager());
           ast_sp->m_scratch_ast_source_ap->InstallASTContext(
-              ast_sp->getASTContext());
+              *ast_sp->getASTContext(), *ast_sp->getFileManager(), true);
           llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
               ast_sp->m_scratch_ast_source_ap->CreateProxy());
           ast_sp->SetExternalSource(proxy_ast_source);
@@ -10122,3 +10123,10 @@ PersistentExpressionState *
 ClangASTContextForExpressions::GetPersistentExpressionState() {
   return m_persistent_variables.get();
 }
+
+clang::ExternalASTMerger &
+ClangASTContextForExpressions::GetMergerUnchecked() {
+  lldbassert(m_scratch_ast_source_ap);
+  return m_scratch_ast_source_ap->GetMergerUnchecked();
+}
+

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=314458&r1=314457&r2=314458&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Thu Sep 28 13:20:25 2017
@@ -3645,9 +3645,11 @@ static PropertyDefinition g_experimental
      "This will fix symbol resolution when there are name collisions between "
      "ivars and local variables.  "
      "But it can make expressions run much more slowly."},
+    {"use-modern-type-lookup", OptionValue::eTypeBoolean, true, false, nullptr,
+     nullptr, "If true, use Clang's modern type lookup infrastructure."},
     {nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}};
 
-enum { ePropertyInjectLocalVars = 0 };
+enum { ePropertyInjectLocalVars = 0, ePropertyUseModernTypeLookup };
 
 class TargetExperimentalOptionValueProperties : public OptionValueProperties {
 public:
@@ -3758,6 +3760,18 @@ void TargetProperties::SetInjectLocalVar
                                             true);
 }
 
+bool TargetProperties::GetUseModernTypeLookup() const {
+  const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
+      nullptr, false, ePropertyExperimental);
+  OptionValueProperties *exp_values =
+      exp_property->GetValue()->GetAsProperties();
+  if (exp_values)
+    return exp_values->GetPropertyAtIndexAsBoolean(
+        nullptr, ePropertyUseModernTypeLookup, true);
+  else
+    return true;
+}
+
 ArchSpec TargetProperties::GetDefaultArchitecture() const {
   OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch(
       nullptr, ePropertyDefaultArch);




More information about the lldb-commits mailing list