[Lldb-commits] [lldb] r359538 - Instantiate 'std' templates explicitly in the expression evaluator

Raphael Isemann via lldb-commits lldb-commits at lists.llvm.org
Tue Apr 30 01:41:35 PDT 2019


Author: teemperor
Date: Tue Apr 30 01:41:35 2019
New Revision: 359538

URL: http://llvm.org/viewvc/llvm-project?rev=359538&view=rev
Log:
Instantiate 'std' templates explicitly in the expression evaluator

Summary:
This patch is a follow-up for D58125. It implements the manual instantiation and merging of 'std' templates like
`std::vector` and `std::shared_ptr` with information from the debug info AST. This (finally) allows using these classes
in the expression evaluator like every other class (i.e. things like `vec.size()` and shared_ptr debugging now works, yay!).

The main logic is the `CxxModuleHandler` which intercept the ASTImporter import process and replaces any `std` decls
by decls from the C++ module. The decls from the C++ module are "imported" by just deserializing them directly in
the expression evaluation context. This is mostly because we don't want to rely on the ASTImporter to correctly import
these declarations, but in the future we should also move to the ASTImporter for that.

This patch doesn't contain the automatic desugaring for result variables. This means that if you call for example
`size` of `std::vector` you maybe get some very verbose typedef'd type as the variable type, e.g.
`std::vector<int, std::allocator<int>>::value_type`.

This is not only unreadable, it also means that our ASTImporter has to import all these types and associated
decls into the persisent variable context. This currently usually leads to some assertion getting triggered
in Clang when the ASTImporter either makes a mistake during importing or our debug info AST is inconsitent.
The current workaround I use in the tests is to just cast the result to it's actual type (e.g. `size_t` or `int`) to prevent
the ASTImporter from having to handle all these complicated decls.

The automatic desugaring will be a future patch because I'm not happy yet with the current code for that and because
I anticipate that this will be a controversial patch.

Reviewers: aprantl, shafik, jingham, martong, serge-sans-paille

Reviewed By: martong

Subscribers: balazske, rnkovacs, mgorny, mgrang, abidh, jdoerfert, lldb-commits

Tags: #c_modules_in_lldb, #lldb

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

Added:
    lldb/trunk/include/lldb/Symbol/CxxModuleHandler.h
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/TestBasicDeque.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/TestDbgInfoContentDeque.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/TestBasicForwardList.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardList.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/TestBasicList.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/TestDbgInfoContentList.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContent.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/TestSharedPtr.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/TestUniquePtrDbgInfoContent.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/TestUniquePtr.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/TestBasicVector.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/TestBoolVector.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/TestDbgInfoContentVector.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/TestVectorOfVectors.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtr.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/TestWeakPtr.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/main.cpp
    lldb/trunk/source/Symbol/CxxModuleHandler.cpp
Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/include/lldb/Symbol/ClangASTImporter.h
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
    lldb/trunk/source/Symbol/CMakeLists.txt
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Symbol/ClangASTImporter.cpp

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=359538&r1=359537&r2=359538&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Apr 30 01:41:35 2019
@@ -104,6 +104,9 @@ public:
 
   clang::TargetInfo *getTargetInfo();
 
+  void setSema(clang::Sema *s);
+  clang::Sema *getSema() { return m_sema; }
+
   void Clear();
 
   const char *GetTargetTriple();
@@ -997,6 +1000,10 @@ protected:
     uint32_t                                        m_pointer_byte_size;
     bool                                            m_ast_owned;
     bool                                            m_can_evaluate_expressions;
+    /// The sema associated that is currently used to build this ASTContext.
+    /// May be null if we are already done parsing this ASTContext or the
+    /// ASTContext wasn't created by parsing source code.
+    clang::Sema *                                   m_sema = nullptr;
   // clang-format on
 private:
   // For ClangASTContext only

Modified: lldb/trunk/include/lldb/Symbol/ClangASTImporter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTImporter.h?rev=359538&r1=359537&r2=359538&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTImporter.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTImporter.h Tue Apr 30 01:41:35 2019
@@ -23,6 +23,7 @@
 
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
+#include "lldb/Symbol/CxxModuleHandler.h"
 #include "lldb/lldb-types.h"
 
 #include "llvm/ADT/DenseMap.h"
@@ -243,6 +244,41 @@ private:
           m_decls_to_deport(nullptr), m_decls_already_deported(nullptr),
           m_master(master), m_source_ctx(source_ctx) {}
 
+    /// Scope guard that attaches a CxxModuleHandler to a Minion and deattaches
+    /// it at the end of the scope. Supports being used multiple times on the
+    /// same Minion instance in nested scopes.
+    class CxxModuleScope {
+      /// The handler we attach to the Minion.
+      CxxModuleHandler m_handler;
+      /// The Minion we are supposed to attach the handler to.
+      Minion &m_minion;
+      /// True iff we attached the handler to the Minion.
+      bool m_valid = false;
+
+    public:
+      CxxModuleScope(Minion &minion, clang::ASTContext *dst_ctx)
+          : m_minion(minion) {
+        // If the minion doesn't have a CxxModuleHandler yet, create one
+        // and attach it.
+        if (!minion.m_std_handler) {
+          m_handler = CxxModuleHandler(minion, dst_ctx);
+          m_valid = true;
+          minion.m_std_handler = &m_handler;
+        }
+      }
+      ~CxxModuleScope() {
+        if (m_valid) {
+          // Make sure no one messed with the handler we placed.
+          assert(m_minion.m_std_handler == &m_handler);
+          m_minion.m_std_handler = nullptr;
+        }
+      }
+    };
+
+  protected:
+    llvm::Expected<clang::Decl *> ImportImpl(clang::Decl *From) override;
+
+  public:
     // A call to "InitDeportWorkQueues" puts the minion into deport mode.
     // In deport mode, every copied Decl that could require completion is
     // recorded and placed into the decls_to_deport set.
@@ -266,10 +302,16 @@ private:
 
     clang::Decl *GetOriginalDecl(clang::Decl *To) override;
 
+    /// Decls we should ignore when mapping decls back to their original
+    /// ASTContext. Used by the CxxModuleHandler to mark declarations that
+    /// were created from the 'std' C++ module to prevent that the Importer
+    /// tries to sync them with the broken equivalent in the debug info AST.
+    std::set<clang::Decl *> m_decls_to_ignore;
     std::set<clang::NamedDecl *> *m_decls_to_deport;
     std::set<clang::NamedDecl *> *m_decls_already_deported;
     ClangASTImporter &m_master;
     clang::ASTContext *m_source_ctx;
+    CxxModuleHandler *m_std_handler = nullptr;
   };
 
   typedef std::shared_ptr<Minion> MinionSP;

Added: lldb/trunk/include/lldb/Symbol/CxxModuleHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/CxxModuleHandler.h?rev=359538&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Symbol/CxxModuleHandler.h (added)
+++ lldb/trunk/include/lldb/Symbol/CxxModuleHandler.h Tue Apr 30 01:41:35 2019
@@ -0,0 +1,65 @@
+//===-- CxxModuleHandler.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CxxModuleHandler_h_
+#define liblldb_CxxModuleHandler_h_
+
+#include "clang/AST/ASTImporter.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/ADT/StringSet.h"
+
+namespace lldb_private {
+
+/// Handles importing decls into an ASTContext with an attached C++ module.
+///
+/// This class searches a C++ module (which must be attached to the target
+/// ASTContext) for an equivalent decl to the one that should be imported.
+/// If the decl that is found in the module is a suitable replacement
+/// for the decl that should be imported, the module decl will be treated as
+/// the result of the import process.
+///
+/// If the Decl that should be imported is a template specialization
+/// that doesn't exist yet in the target ASTContext (e.g. `std::vector<int>`),
+/// then this class tries to create the template specialization in the target
+/// ASTContext. This is only possible if the CxxModuleHandler can determine
+/// that instantiating this template is safe to do, e.g. because the target
+/// decl is a container class from the STL.
+class CxxModuleHandler {
+  /// The ASTImporter that should be used to import any Decls which aren't
+  /// directly handled by this class itself.
+  clang::ASTImporter *m_importer = nullptr;
+
+  /// The Sema instance of the target ASTContext.
+  clang::Sema *m_sema = nullptr;
+
+  /// List of template names this class currently supports. These are the
+  /// template names inside the 'std' namespace such as 'vector' or 'list'.
+  llvm::StringSet<> m_supported_templates;
+
+  /// Tries to manually instantiate the given foreign template in the target
+  /// context (designated by m_sema).
+  llvm::Optional<clang::Decl *> tryInstantiateStdTemplate(clang::Decl *d);
+
+public:
+  CxxModuleHandler() = default;
+  CxxModuleHandler(clang::ASTImporter &importer, clang::ASTContext *target);
+
+  /// Attempts to import the given decl into the target ASTContext by
+  /// deserializing it from the 'std' module. This function returns a Decl if a
+  /// Decl has been deserialized from the 'std' module. Otherwise this function
+  /// returns nothing.
+  llvm::Optional<clang::Decl *> Import(clang::Decl *d);
+
+  /// Returns true iff this instance is capable of importing any declarations
+  /// in the target ASTContext.
+  bool isValid() const { return m_sema != nullptr; }
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CxxModuleHandler_h_

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/TestBasicDeque.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/TestBasicDeque.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/TestBasicDeque.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/TestBasicDeque.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,41 @@
+"""
+Test basic std::list functionality.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestBasicDeque(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $0 = 3'])
+        self.expect("expr (int)a.front()", substrs=['(int) $1 = 3'])
+        self.expect("expr (int)a.back()", substrs=['(int) $2 = 2'])
+
+        self.expect("expr std::sort(a.begin(), a.end())")
+        self.expect("expr (int)a.front()", substrs=['(int) $3 = 1'])
+        self.expect("expr (int)a.back()", substrs=['(int) $4 = 3'])
+
+        self.expect("expr std::reverse(a.begin(), a.end())")
+        self.expect("expr (int)a.front()", substrs=['(int) $5 = 3'])
+        self.expect("expr (int)a.back()", substrs=['(int) $6 = 1'])
+
+        self.expect("expr (int)(*a.begin())", substrs=['(int) $7 = 3'])
+        self.expect("expr (int)(*a.rbegin())", substrs=['(int) $8 = 1'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-basic/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,6 @@
+#include <deque>
+
+int main(int argc, char **argv) {
+  std::deque<int> a = {3, 1, 2};
+  return 0; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/TestDbgInfoContentDeque.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/TestDbgInfoContentDeque.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/TestDbgInfoContentDeque.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/TestDbgInfoContentDeque.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,37 @@
+"""
+Test std::deque functionality with a decl from dbg info as content.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestDbgInfoContentDeque(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $0 = 3'])
+        self.expect("expr (int)a.front()->a", substrs=['(int) $1 = 3'])
+        self.expect("expr (int)a.back()->a", substrs=['(int) $2 = 2'])
+
+        self.expect("expr std::reverse(a.begin(), a.end())")
+        self.expect("expr (int)a.front()->a", substrs=['(int) $3 = 2'])
+        self.expect("expr (int)a.back()->a", substrs=['(int) $4 = 3'])
+
+        self.expect("expr (int)(a.begin()->a)", substrs=['(int) $5 = 2'])
+        self.expect("expr (int)(a.rbegin()->a)", substrs=['(int) $6 = 3'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/deque-dbg-info-content/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,10 @@
+#include <deque>
+
+struct Foo {
+  int a;
+};
+
+int main(int argc, char **argv) {
+  std::deque<Foo> a = {{3}, {1}, {2}};
+  return 0; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/TestBasicForwardList.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/TestBasicForwardList.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/TestBasicForwardList.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/TestBasicForwardList.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,34 @@
+"""
+Test basic std::forward_list functionality.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestBasicList(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (size_t)std::distance(a.begin(), a.end())", substrs=['(size_t) $0 = 3'])
+        self.expect("expr (int)a.front()", substrs=['(int) $1 = 3'])
+
+        self.expect("expr a.sort()")
+        self.expect("expr (int)a.front()", substrs=['(int) $2 = 1'])
+
+        self.expect("expr (int)(*a.begin())", substrs=['(int) $3 = 1'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-basic/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,6 @@
+#include <forward_list>
+
+int main(int argc, char **argv) {
+  std::forward_list<int> a = {3, 1, 2};
+  return 0; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardList.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardList.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardList.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/TestDbgInfoContentForwardList.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,31 @@
+"""
+Test std::forward_list functionality with a decl from debug info as content.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestDbgInfoContentForwardList(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (size_t)std::distance(a.begin(), a.end())", substrs=['(size_t) $0 = 3'])
+        self.expect("expr (int)a.front()->a", substrs=['(int) $1 = 3'])
+
+        self.expect("expr (int)(a.begin()->a)", substrs=['(int) $2 = 3'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/forward_list-dbg-info-content/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,10 @@
+#include <forward_list>
+
+struct Foo {
+  int a;
+};
+
+int main(int argc, char **argv) {
+  std::forward_list<Foo> a = {{3}, {1}, {2}};
+  return 0; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/TestBasicList.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/TestBasicList.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/TestBasicList.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/TestBasicList.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,41 @@
+"""
+Test basic std::list functionality.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestBasicList(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $0 = 3'])
+        self.expect("expr (int)a.front()", substrs=['(int) $1 = 3'])
+        self.expect("expr (int)a.back()", substrs=['(int) $2 = 2'])
+
+        self.expect("expr a.sort()")
+        self.expect("expr (int)a.front()", substrs=['(int) $3 = 1'])
+        self.expect("expr (int)a.back()", substrs=['(int) $4 = 3'])
+
+        self.expect("expr std::reverse(a.begin(), a.end())")
+        self.expect("expr (int)a.front()", substrs=['(int) $5 = 3'])
+        self.expect("expr (int)a.back()", substrs=['(int) $6 = 1'])
+
+        self.expect("expr (int)(*a.begin())", substrs=['(int) $7 = 3'])
+        self.expect("expr (int)(*a.rbegin())", substrs=['(int) $8 = 1'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-basic/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,6 @@
+#include <list>
+
+int main(int argc, char **argv) {
+  std::list<int> a = {3, 1, 2};
+  return 0; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/TestDbgInfoContentList.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/TestDbgInfoContentList.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/TestDbgInfoContentList.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/TestDbgInfoContentList.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,38 @@
+"""
+Test basic std::list functionality but with a declaration from
+the debug info (the Foo struct) as content.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestDbgInfoContentList(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $0 = 3'])
+        self.expect("expr (int)a.front().a", substrs=['(int) $1 = 3'])
+        self.expect("expr (int)a.back().a", substrs=['(int) $2 = 2'])
+
+        self.expect("expr std::reverse(a.begin(), a.end())")
+        self.expect("expr (int)a.front().a", substrs=['(int) $3 = 2'])
+        self.expect("expr (int)a.back().a", substrs=['(int) $4 = 3'])
+
+        self.expect("expr (int)(a.begin()->a)", substrs=['(int) $5 = 2'])
+        self.expect("expr (int)(a.rbegin()->a)", substrs=['(int) $6 = 3'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/list-dbg-info-content/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,10 @@
+#include <list>
+
+struct Foo {
+  int a;
+};
+
+int main(int argc, char **argv) {
+  std::list<Foo> a = {{3}, {1}, {2}};
+  return 0; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContent.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContent.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContent.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/TestSharedPtrDbgInfoContent.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,33 @@
+"""
+Test std::shared_ptr functionality with a class from debug info as content.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestSharedPtr(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (int)s->a", substrs=['(int) $0 = 3'])
+        self.expect("expr (int)(s->a = 5)", substrs=['(int) $1 = 5'])
+        self.expect("expr (int)s->a", substrs=['(int) $2 = 5'])
+        self.expect("expr (bool)s", substrs=['(bool) $3 = true'])
+        self.expect("expr s.reset()")
+        self.expect("expr (bool)s", substrs=['(bool) $4 = false'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr-dbg-info-content/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,11 @@
+#include <memory>
+
+struct Foo {
+  int a;
+};
+
+int main(int argc, char **argv) {
+  std::shared_ptr<Foo> s(new Foo);
+  s->a = 3;
+  return s->a; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/TestSharedPtr.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/TestSharedPtr.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/TestSharedPtr.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/TestSharedPtr.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,33 @@
+"""
+Test basic std::shared_ptr functionality.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestSharedPtr(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (int)*s", substrs=['(int) $0 = 3'])
+        self.expect("expr (int)(*s = 5)", substrs=['(int) $1 = 5'])
+        self.expect("expr (int)*s", substrs=['(int) $2 = 5'])
+        self.expect("expr (bool)s", substrs=['(bool) $3 = true'])
+        self.expect("expr s.reset()")
+        self.expect("expr (bool)s", substrs=['(bool) $4 = false'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/shared_ptr/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,7 @@
+#include <memory>
+
+int main(int argc, char **argv) {
+  std::shared_ptr<int> s(new int);
+  *s = 3;
+  return *s; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/TestUniquePtrDbgInfoContent.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/TestUniquePtrDbgInfoContent.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/TestUniquePtrDbgInfoContent.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/TestUniquePtrDbgInfoContent.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,33 @@
+"""
+Test std::unique_ptr functionality with a decl from debug info as content.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestUniquePtrDbgInfoContent(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (int)s->a", substrs=['(int) $0 = 3'])
+        self.expect("expr (int)(s->a = 5)", substrs=['(int) $1 = 5'])
+        self.expect("expr (int)s->a", substrs=['(int) $2 = 5'])
+        self.expect("expr (bool)s", substrs=['(bool) $3 = true'])
+        self.expect("expr s.reset()")
+        self.expect("expr (bool)s", substrs=['(bool) $4 = false'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr-dbg-info-content/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,11 @@
+#include <memory>
+
+struct Foo {
+  int a;
+};
+
+int main(int argc, char **argv) {
+  std::shared_ptr<Foo> s(new Foo);
+  s->a = 3;
+  return s->a; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/TestUniquePtr.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/TestUniquePtr.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/TestUniquePtr.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/TestUniquePtr.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,33 @@
+"""
+Test basic std::unique_ptr functionality.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestUniquePtr(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (int)*s", substrs=['(int) $0 = 3'])
+        self.expect("expr (int)(*s = 5)", substrs=['(int) $1 = 5'])
+        self.expect("expr (int)*s", substrs=['(int) $2 = 5'])
+        self.expect("expr (bool)s", substrs=['(bool) $3 = true'])
+        self.expect("expr s.reset()")
+        self.expect("expr (bool)s", substrs=['(bool) $4 = false'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/unique_ptr/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,7 @@
+#include <memory>
+
+int main(int argc, char **argv) {
+  std::shared_ptr<int> s(new int);
+  *s = 3;
+  return *s; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/TestBasicVector.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/TestBasicVector.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/TestBasicVector.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/TestBasicVector.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,57 @@
+"""
+Test basic std::vector functionality.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestBasicVector(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $0 = 3'])
+        self.expect("expr (int)a.front()", substrs=['(int) $1 = 3'])
+        self.expect("expr (int)a[1]", substrs=['(int) $2 = 1'])
+        self.expect("expr (int)a.back()", substrs=['(int) $3 = 2'])
+
+        self.expect("expr std::sort(a.begin(), a.end())")
+        self.expect("expr (int)a.front()", substrs=['(int) $4 = 1'])
+        self.expect("expr (int)a[1]", substrs=['(int) $5 = 2'])
+        self.expect("expr (int)a.back()", substrs=['(int) $6 = 3'])
+
+        self.expect("expr std::reverse(a.begin(), a.end())")
+        self.expect("expr (int)a.front()", substrs=['(int) $7 = 3'])
+        self.expect("expr (int)a[1]", substrs=['(int) $8 = 2'])
+        self.expect("expr (int)a.back()", substrs=['(int) $9 = 1'])
+
+        self.expect("expr (int)(*a.begin())", substrs=['(int) $10 = 3'])
+        self.expect("expr (int)(*a.rbegin())", substrs=['(int) $11 = 1'])
+
+        self.expect("expr a.pop_back()")
+        self.expect("expr (int)a.back()", substrs=['(int) $12 = 2'])
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $13 = 2'])
+
+        self.expect("expr (int)a.at(0)", substrs=['(int) $14 = 3'])
+
+        self.expect("expr a.push_back(4)")
+        self.expect("expr (int)a.back()", substrs=['(int) $15 = 4'])
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $16 = 3'])
+
+        self.expect("expr a.emplace_back(5)")
+        self.expect("expr (int)a.back()", substrs=['(int) $17 = 5'])
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $18 = 4'])

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-basic/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,6 @@
+#include <vector>
+
+int main(int argc, char **argv) {
+  std::vector<int> a = {3, 1, 2};
+  return 0; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/TestBoolVector.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/TestBoolVector.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/TestBoolVector.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/TestBoolVector.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,34 @@
+"""
+Test basic std::vector<bool> functionality.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestBoolVector(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $0 = 4'])
+        self.expect("expr (bool)a.front()", substrs=['(bool) $1 = false'])
+        self.expect("expr (bool)a[1]", substrs=['(bool) $2 = true'])
+        self.expect("expr (bool)a.back()", substrs=['(bool) $3 = true'])
+
+        self.expect("expr (bool)(*a.begin())", substrs=['(bool) $4 = false'])
+        self.expect("expr (bool)(*a.rbegin())", substrs=['(bool) $5 = true'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-bool/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,6 @@
+#include <vector>
+
+int main(int argc, char **argv) {
+  std::vector<bool> a = {0, 1, 0, 1};
+  return 0; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/TestDbgInfoContentVector.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/TestDbgInfoContentVector.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/TestDbgInfoContentVector.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/TestDbgInfoContentVector.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,47 @@
+"""
+Test basic std::vector functionality but with a declaration from
+the debug info (the Foo struct) as content.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestDbgInfoContentVector(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $0 = 3'])
+        self.expect("expr (int)a.front().a", substrs=['(int) $1 = 3'])
+        self.expect("expr (int)a[1].a", substrs=['(int) $2 = 1'])
+        self.expect("expr (int)a.back().a", substrs=['(int) $3 = 2'])
+
+        self.expect("expr std::reverse(a.begin(), a.end())")
+        self.expect("expr (int)a.front().a", substrs=['(int) $4 = 2'])
+
+        self.expect("expr (int)(a.begin()->a)", substrs=['(int) $5 = 2'])
+        self.expect("expr (int)(a.rbegin()->a)", substrs=['(int) $6 = 3'])
+
+        self.expect("expr a.pop_back()")
+        self.expect("expr (int)a.back().a", substrs=['(int) $7 = 1'])
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $8 = 2'])
+
+        self.expect("expr (int)a.at(0).a", substrs=['(int) $9 = 2'])
+
+        self.expect("expr a.push_back({4})")
+        self.expect("expr (int)a.back().a", substrs=['(int) $10 = 4'])
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $11 = 3'])

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-dbg-info-content/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,10 @@
+#include <vector>
+
+struct Foo {
+  int a;
+};
+
+int main(int argc, char **argv) {
+  std::vector<Foo> a = {{3}, {1}, {2}};
+  return 0; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/TestVectorOfVectors.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/TestVectorOfVectors.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/TestVectorOfVectors.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/TestVectorOfVectors.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,30 @@
+"""
+Test std::vector functionality when it's contents are vectors.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestVectorOfVectors(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (size_t)a.size()", substrs=['(size_t) $0 = 2'])
+        self.expect("expr (int)a.front().front()", substrs=['(int) $1 = 1'])
+        self.expect("expr (int)a[1][1]", substrs=['(int) $2 = 2'])
+        self.expect("expr (int)a.back().at(0)", substrs=['(int) $3 = 3'])

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/vector-of-vectors/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,6 @@
+#include <vector>
+
+int main(int argc, char **argv) {
+  std::vector<std::vector<int> > a = {{1, 2, 3}, {3, 2, 1}};
+  return 0; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtr.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtr.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtr.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/TestDbgInfoContentWeakPtr.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,33 @@
+"""
+Test std::weak_ptr functionality with a decl from debug info as content.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestDbgInfoContentWeakPtr(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (int)w.lock()->a", substrs=['(int) $0 = 3'])
+        self.expect("expr (int)(w.lock()->a = 5)", substrs=['(int) $1 = 5'])
+        self.expect("expr (int)w.lock()->a", substrs=['(int) $2 = 5'])
+        self.expect("expr w.use_count()", substrs=['(long) $3 = 1'])
+        self.expect("expr w.reset()")
+        self.expect("expr w.use_count()", substrs=['(long) $4 = 0'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr-dbg-info-content/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,12 @@
+#include <memory>
+
+struct Foo {
+  int a;
+};
+
+int main(int argc, char **argv) {
+  std::shared_ptr<Foo> s(new Foo);
+  s->a = 3;
+  std::weak_ptr<Foo> w = s;
+  return s->a; // Set break point at this line.
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/Makefile?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/Makefile Tue Apr 30 01:41:35 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+USE_LIBCPP := 1
+CXXFLAGS += $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/TestWeakPtr.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/TestWeakPtr.py?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/TestWeakPtr.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/TestWeakPtr.py Tue Apr 30 01:41:35 2019
@@ -0,0 +1,33 @@
+"""
+Test basic std::weak_ptr functionality.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestSharedPtr(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # FIXME: This should work on more setups, so remove these
+    # skipIf's in the future.
+    @add_test_categories(["libc++"])
+    @skipIf(compiler=no_match("clang"))
+    @skipIf(oslist=no_match(["linux"]))
+    @skipIf(debug_info=no_match(["dwarf"]))
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+
+        self.expect("expr (int)*w.lock()", substrs=['(int) $0 = 3'])
+        self.expect("expr (int)(*w.lock() = 5)", substrs=['(int) $1 = 5'])
+        self.expect("expr (int)*w.lock()", substrs=['(int) $2 = 5'])
+        self.expect("expr w.use_count()", substrs=['(long) $3 = 1'])
+        self.expect("expr w.reset()")
+        self.expect("expr w.use_count()", substrs=['(long) $4 = 0'])
+

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/main.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/import-std-module/weak_ptr/main.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,8 @@
+#include <memory>
+
+int main(int argc, char **argv) {
+  std::shared_ptr<int> s(new int);
+  *s = 3;
+  std::weak_ptr<int> w = s;
+  return *s; // Set break point at this line.
+}

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=359538&r1=359537&r2=359538&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp Tue Apr 30 01:41:35 2019
@@ -761,6 +761,10 @@ void ClangASTSource::FindExternalVisible
   }
 }
 
+clang::Sema *ClangASTSource::getSema() {
+  return ClangASTContext::GetASTContext(m_ast_context)->getSema();
+}
+
 bool ClangASTSource::IgnoreName(const ConstString name,
                                 bool ignore_all_dollar_names) {
   static const ConstString id_name("id");

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=359538&r1=359537&r2=359538&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h Tue Apr 30 01:41:35 2019
@@ -193,6 +193,8 @@ public:
   ///     The NameSearchContext to use when filing results.
   virtual void FindExternalVisibleDecls(NameSearchContext &context);
 
+  clang::Sema *getSema();
+
   void SetImportInProgress(bool import_in_progress) {
     m_import_in_progress = import_in_progress;
   }

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=359538&r1=359537&r2=359538&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp Tue Apr 30 01:41:35 2019
@@ -967,8 +967,10 @@ ClangExpressionParser::ParseInternal(Dia
                                *Consumer, TU_Complete, completion_consumer));
   m_compiler->setASTConsumer(std::move(Consumer));
 
-  if (ast_context.getLangOpts().Modules)
+  if (ast_context.getLangOpts().Modules) {
     m_compiler->createModuleManager();
+    m_ast_context->setSema(&m_compiler->getSema());
+  }
 
   ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap();
   if (decl_map) {
@@ -1005,6 +1007,10 @@ ClangExpressionParser::ParseInternal(Dia
         &m_compiler->getSema());
     ParseAST(m_compiler->getSema(), false, false);
   }
+
+  // Make sure we have no pointer to the Sema we are about to destroy.
+  if (ast_context.getLangOpts().Modules)
+    m_ast_context->setSema(nullptr);
   // Destroy the Sema. This is necessary because we want to emulate the
   // original behavior of ParseAST (which also destroys the Sema after parsing).
   m_compiler->setSema(nullptr);

Modified: lldb/trunk/source/Symbol/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CMakeLists.txt?rev=359538&r1=359537&r2=359538&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/CMakeLists.txt (original)
+++ lldb/trunk/source/Symbol/CMakeLists.txt Tue Apr 30 01:41:35 2019
@@ -27,6 +27,7 @@ add_lldb_library(lldbSymbol
   LocateSymbolFile.cpp
   ObjectFile.cpp
   PostfixExpression.cpp
+  CxxModuleHandler.cpp
   Symbol.cpp
   SymbolContext.cpp
   SymbolFile.cpp

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=359538&r1=359537&r2=359538&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Apr 30 01:41:35 2019
@@ -52,6 +52,7 @@
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Frontend/FrontendOptions.h"
 #include "clang/Frontend/LangStandard.h"
+#include "clang/Sema/Sema.h"
 
 #ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
 #undef NDEBUG
@@ -792,6 +793,12 @@ void ClangASTContext::Clear() {
   m_pointer_byte_size = 0;
 }
 
+void ClangASTContext::setSema(Sema *s) {
+  // Ensure that the new sema actually belongs to our ASTContext.
+  assert(s == nullptr || &s->getASTContext() == m_ast_up.get());
+  m_sema = s;
+}
+
 const char *ClangASTContext::GetTargetTriple() {
   return m_target_triple.c_str();
 }

Modified: lldb/trunk/source/Symbol/ClangASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTImporter.cpp?rev=359538&r1=359537&r2=359538&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTImporter.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTImporter.cpp Tue Apr 30 01:41:35 2019
@@ -16,6 +16,8 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Sema.h"
 #include "llvm/Support/raw_ostream.h"
 
 #include <memory>
@@ -58,6 +60,8 @@ clang::QualType ClangASTImporter::CopyTy
                                            clang::QualType type) {
   MinionSP minion_sp(GetMinion(dst_ast, src_ast));
 
+  Minion::CxxModuleScope std_scope(*minion_sp, dst_ast);
+
   if (minion_sp)
     return minion_sp->Import(type);
 
@@ -99,6 +103,8 @@ clang::Decl *ClangASTImporter::CopyDecl(
 
   minion_sp = GetMinion(dst_ast, src_ast);
 
+  Minion::CxxModuleScope std_scope(*minion_sp, dst_ast);
+
   if (minion_sp) {
     clang::Decl *result = minion_sp->Import(decl);
 
@@ -557,6 +563,7 @@ bool ClangASTImporter::CompleteTagDecl(c
 
   MinionSP minion_sp(GetMinion(&decl->getASTContext(), decl_origin.ctx));
 
+  Minion::CxxModuleScope std_scope(*minion_sp, &decl->getASTContext());
   if (minion_sp)
     minion_sp->ImportDefinitionTo(decl, decl_origin.decl);
 
@@ -624,6 +631,8 @@ bool ClangASTImporter::CompleteAndFetchC
 
     MinionSP minion_sp(GetMinion(&tag_decl->getASTContext(), decl_origin.ctx));
 
+    Minion::CxxModuleScope std_scope(*minion_sp, &tag_decl->getASTContext());
+
     TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl);
 
     for (Decl *origin_child_decl : origin_tag_decl->decls()) {
@@ -816,6 +825,23 @@ void ClangASTImporter::ForgetSource(clan
 
 ClangASTImporter::MapCompleter::~MapCompleter() { return; }
 
+llvm::Expected<Decl *> ClangASTImporter::Minion::ImportImpl(Decl *From) {
+  if (m_std_handler) {
+    llvm::Optional<Decl *> D = m_std_handler->Import(From);
+    if (D) {
+      // Make sure we don't use this decl later to map it back to it's original
+      // decl. The decl the CxxModuleHandler created has nothing to do with
+      // the one from debug info, and linking those two would just cause the
+      // ASTImporter to try 'updating' the module decl with the minimal one from
+      // the debug info.
+      m_decls_to_ignore.insert(*D);
+      return *D;
+    }
+  }
+
+  return ASTImporter::ImportImpl(From);
+}
+
 void ClangASTImporter::Minion::InitDeportWorkQueues(
     std::set<clang::NamedDecl *> *decls_to_deport,
     std::set<clang::NamedDecl *> *decls_already_deported) {
@@ -943,6 +969,11 @@ void ClangASTImporter::Minion::Imported(
 
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
+  // Some decls shouldn't be tracked here because they were not created by
+  // copying 'from' to 'to'. Just exit early for those.
+  if (m_decls_to_ignore.find(to) != m_decls_to_ignore.end())
+    return clang::ASTImporter::Imported(from, to);
+
   lldb::user_id_t user_id = LLDB_INVALID_UID;
   ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
   if (metadata)

Added: lldb/trunk/source/Symbol/CxxModuleHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CxxModuleHandler.cpp?rev=359538&view=auto
==============================================================================
--- lldb/trunk/source/Symbol/CxxModuleHandler.cpp (added)
+++ lldb/trunk/source/Symbol/CxxModuleHandler.cpp Tue Apr 30 01:41:35 2019
@@ -0,0 +1,278 @@
+//===-- CxxModuleHandler.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/CxxModuleHandler.h"
+
+#include "lldb/Symbol/ClangASTContext.h"
+#include "clang/Sema/Lookup.h"
+#include "llvm/Support/Error.h"
+
+using namespace lldb_private;
+using namespace clang;
+
+CxxModuleHandler::CxxModuleHandler(ASTImporter &importer, ASTContext *target)
+    : m_importer(&importer),
+      m_sema(ClangASTContext::GetASTContext(target)->getSema()) {
+
+  std::initializer_list<const char *> supported_names = {
+      // containers
+      "vector",
+      "list",
+      "forward_list",
+      "deque",
+      // pointers
+      "shared_ptr",
+      "unique_ptr",
+      "weak_ptr",
+      // utility
+      "allocator",
+  };
+  m_supported_templates.insert(supported_names.begin(), supported_names.end());
+}
+
+/// Builds a list of scopes that point into the given context.
+///
+/// \param sema The sema that will be using the scopes.
+/// \param ctxt The context that the scope should look into.
+/// \param result A list of scopes. The scopes need to be freed by the caller
+///               (except the TUScope which is owned by the sema).
+static void makeScopes(Sema &sema, DeclContext *ctxt,
+                       std::vector<Scope *> &result) {
+  // FIXME: The result should be a list of unique_ptrs, but the TUScope makes
+  // this currently impossible as it's owned by the Sema.
+
+  if (auto parent = ctxt->getParent()) {
+    makeScopes(sema, parent, result);
+
+    Scope *scope =
+        new Scope(result.back(), Scope::DeclScope, sema.getDiagnostics());
+    scope->setEntity(ctxt);
+    result.push_back(scope);
+  } else
+    result.push_back(sema.TUScope);
+}
+
+/// Uses the Sema to look up the given name in the given DeclContext.
+static std::unique_ptr<LookupResult>
+emulateLookupInCtxt(Sema &sema, llvm::StringRef name, DeclContext *ctxt) {
+  IdentifierInfo &ident = sema.getASTContext().Idents.get(name);
+
+  std::unique_ptr<LookupResult> lookup_result;
+  lookup_result.reset(new LookupResult(sema, DeclarationName(&ident),
+                                       SourceLocation(),
+                                       Sema::LookupOrdinaryName));
+
+  // Usually during parsing we already encountered the scopes we would use. But
+  // here don't have these scopes so we have to emulate the behavior of the
+  // Sema during parsing.
+  std::vector<Scope *> scopes;
+  makeScopes(sema, ctxt, scopes);
+
+  // Now actually perform the lookup with the sema.
+  sema.LookupName(*lookup_result, scopes.back());
+
+  // Delete all the allocated scopes beside the translation unit scope (which
+  // has depth 0).
+  for (Scope *s : scopes)
+    if (s->getDepth() != 0)
+      delete s;
+
+  return lookup_result;
+}
+
+/// Error class for handling problems when finding a certain DeclContext.
+struct MissingDeclContext : public llvm::ErrorInfo<MissingDeclContext> {
+
+  static char ID;
+
+  MissingDeclContext(DeclContext *context, std::string error)
+      : m_context(context), m_error(error) {}
+
+  DeclContext *m_context;
+  std::string m_error;
+
+  void log(llvm::raw_ostream &OS) const override {
+    OS << llvm::formatv("error when reconstructing context of kind {0}:{1}",
+                        m_context->getDeclKindName(), m_error);
+  }
+
+  std::error_code convertToErrorCode() const override {
+    return llvm::inconvertibleErrorCode();
+  }
+};
+
+char MissingDeclContext::ID = 0;
+
+/// Given a foreign decl context, this function finds the equivalent local
+/// decl context in the ASTContext of the given Sema. Potentially deserializes
+/// decls from the 'std' module if necessary.
+static llvm::Expected<DeclContext *>
+getEqualLocalDeclContext(Sema &sema, DeclContext *foreign_ctxt) {
+
+  // Inline namespaces don't matter for lookups, so let's skip them.
+  while (foreign_ctxt && foreign_ctxt->isInlineNamespace())
+    foreign_ctxt = foreign_ctxt->getParent();
+
+  // If the foreign context is the TU, we just return the local TU.
+  if (foreign_ctxt->isTranslationUnit())
+    return sema.getASTContext().getTranslationUnitDecl();
+
+  // Recursively find/build the parent DeclContext.
+  llvm::Expected<DeclContext *> parent =
+      getEqualLocalDeclContext(sema, foreign_ctxt->getParent());
+  if (!parent)
+    return parent;
+
+  // We currently only support building namespaces.
+  if (foreign_ctxt->isNamespace()) {
+    NamedDecl *ns = llvm::dyn_cast<NamedDecl>(foreign_ctxt);
+    llvm::StringRef ns_name = ns->getName();
+
+    auto lookup_result = emulateLookupInCtxt(sema, ns_name, *parent);
+    for (NamedDecl *named_decl : *lookup_result) {
+      if (DeclContext *DC = llvm::dyn_cast<DeclContext>(named_decl))
+        return DC->getPrimaryContext();
+    }
+    return llvm::make_error<MissingDeclContext>(
+        foreign_ctxt,
+        "Couldn't find namespace " + ns->getQualifiedNameAsString());
+  }
+
+  return llvm::make_error<MissingDeclContext>(foreign_ctxt, "Unknown context ");
+}
+
+/// Returns true iff tryInstantiateStdTemplate supports instantiating a template
+/// with the given template arguments.
+static bool templateArgsAreSupported(ArrayRef<TemplateArgument> a) {
+  for (const TemplateArgument &arg : a) {
+    switch (arg.getKind()) {
+    case TemplateArgument::Type:
+    case TemplateArgument::Integral:
+      break;
+    default:
+      // TemplateArgument kind hasn't been handled yet.
+      return false;
+    }
+  }
+  return true;
+}
+
+/// Constructor function for Clang declarations. Ensures that the created
+/// declaration is registered with the ASTImporter.
+template <typename T, typename... Args>
+T *createDecl(ASTImporter &importer, Decl *from_d, Args &&... args) {
+  T *to_d = T::Create(std::forward<Args>(args)...);
+  importer.RegisterImportedDecl(from_d, to_d);
+  return to_d;
+}
+
+llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
+  // If we don't have a template to instiantiate, then there is nothing to do.
+  auto td = dyn_cast<ClassTemplateSpecializationDecl>(d);
+  if (!td)
+    return {};
+
+  // We only care about templates in the std namespace.
+  if (!td->getDeclContext()->isStdNamespace())
+    return {};
+
+  // We have a whitelist of supported template names.
+  if (m_supported_templates.find(td->getName()) == m_supported_templates.end())
+    return {};
+
+  // Early check if we even support instantiating this template. We do this
+  // before we import anything into the target AST.
+  auto &foreign_args = td->getTemplateInstantiationArgs();
+  if (!templateArgsAreSupported(foreign_args.asArray()))
+    return {};
+
+  // Find the local DeclContext that corresponds to the DeclContext of our
+  // decl we want to import.
+  auto to_context = getEqualLocalDeclContext(*m_sema, td->getDeclContext());
+  if (!to_context)
+    return {};
+
+  // Look up the template in our local context.
+  std::unique_ptr<LookupResult> lookup =
+      emulateLookupInCtxt(*m_sema, td->getName(), *to_context);
+
+  ClassTemplateDecl *new_class_template = nullptr;
+  for (auto LD : *lookup) {
+    if ((new_class_template = dyn_cast<ClassTemplateDecl>(LD)))
+      break;
+  }
+  if (!new_class_template)
+    return {};
+
+  // Import the foreign template arguments.
+  llvm::SmallVector<TemplateArgument, 4> imported_args;
+
+  // If this logic is changed, also update templateArgsAreSupported.
+  for (const TemplateArgument &arg : foreign_args.asArray()) {
+    switch (arg.getKind()) {
+    case TemplateArgument::Type: {
+      llvm::Expected<QualType> type = m_importer->Import_New(arg.getAsType());
+      if (!type) {
+        llvm::consumeError(type.takeError());
+        return {};
+      }
+      imported_args.push_back(TemplateArgument(*type));
+      break;
+    }
+    case TemplateArgument::Integral: {
+      llvm::APSInt integral = arg.getAsIntegral();
+      llvm::Expected<QualType> type =
+          m_importer->Import_New(arg.getIntegralType());
+      if (!type) {
+        llvm::consumeError(type.takeError());
+        return {};
+      }
+      imported_args.push_back(
+          TemplateArgument(d->getASTContext(), integral, *type));
+      break;
+    }
+    default:
+      assert(false && "templateArgsAreSupported not updated?");
+    }
+  }
+
+  // Find the class template specialization declaration that
+  // corresponds to these arguments.
+  void *InsertPos = nullptr;
+  ClassTemplateSpecializationDecl *result =
+      new_class_template->findSpecialization(imported_args, InsertPos);
+
+  if (result) {
+    // We found an existing specialization in the module that fits our arguments
+    // so we can treat it as the result and register it with the ASTImporter.
+    m_importer->RegisterImportedDecl(d, result);
+    return result;
+  }
+
+  // Instantiate the template.
+  result = createDecl<ClassTemplateSpecializationDecl>(
+      *m_importer, d, m_sema->getASTContext(),
+      new_class_template->getTemplatedDecl()->getTagKind(),
+      new_class_template->getDeclContext(),
+      new_class_template->getTemplatedDecl()->getLocation(),
+      new_class_template->getLocation(), new_class_template, imported_args,
+      nullptr);
+
+  new_class_template->AddSpecialization(result, InsertPos);
+  if (new_class_template->isOutOfLine())
+    result->setLexicalDeclContext(
+        new_class_template->getLexicalDeclContext());
+  return result;
+}
+
+llvm::Optional<Decl *> CxxModuleHandler::Import(Decl *d) {
+  if (!isValid())
+    return {};
+
+  return tryInstantiateStdTemplate(d);
+}




More information about the lldb-commits mailing list