[Lldb-commits] [lldb] r235313 - This patch implements several improvements to the

Sean Callanan scallanan at apple.com
Mon Apr 20 09:31:30 PDT 2015


Author: spyffe
Date: Mon Apr 20 11:31:29 2015
New Revision: 235313

URL: http://llvm.org/viewvc/llvm-project?rev=235313&view=rev
Log:
This patch implements several improvements to the
module-loading support for the expression parser.

- It adds support for auto-loading modules referred
  to by a compile unit.  These references are
  currently in the form of empty translation units.
  This functionality is gated by the setting

  target.auto-import-clang-modules (boolean) = false

- It improves and corrects support for loading
  macros from modules, currently by textually
  pasting all #defines into the user's expression.
  The improvements center around including only those
  modules that are relevant to the current context -
  hand-loaded modules and the modules that are imported
  from the current compile unit.

- It adds an "opt-in" mechanism for all of this
  functionality.  Modules have to be explicitly
  imported (via @import) or auto-loaded (by enabling
  the above setting) to enable any of this
  functionality.

It also adds support to the compile unit and symbol
file code to deal with empty translation units that
indicate module imports, and plumbs this through to
the CompileUnit interface.

Finally, it makes the following changes to the test
suite:

- It adds a testcase that verifies that modules are
  automatically loaded when the appropriate setting
  is enabled (lang/objc/modules-auto-import); and

- It modifies lanb/objc/modules-incomplete to test
  the case where a module #undefs something that is
  #defined in another module.

<rdar://problem/20299554>

Added:
    lldb/trunk/test/lang/objc/modules-auto-import/
    lldb/trunk/test/lang/objc/modules-auto-import/Makefile
    lldb/trunk/test/lang/objc/modules-auto-import/TestModulesAutoImport.py
    lldb/trunk/test/lang/objc/modules-auto-import/main.m
Modified:
    lldb/trunk/include/lldb/Expression/ClangModulesDeclVendor.h
    lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h
    lldb/trunk/include/lldb/Symbol/CompileUnit.h
    lldb/trunk/include/lldb/Symbol/SymbolFile.h
    lldb/trunk/include/lldb/Symbol/SymbolVendor.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/source/Expression/ClangExpressionParser.cpp
    lldb/trunk/source/Expression/ClangModulesDeclVendor.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
    lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
    lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
    lldb/trunk/source/Symbol/CompileUnit.cpp
    lldb/trunk/source/Symbol/SymbolVendor.cpp
    lldb/trunk/source/Target/Target.cpp
    lldb/trunk/test/functionalities/data-formatter/typedef_array/Makefile
    lldb/trunk/test/lang/objc/modules-incomplete/TestIncompleteModules.py
    lldb/trunk/test/lang/objc/modules-incomplete/myModule.h

Modified: lldb/trunk/include/lldb/Expression/ClangModulesDeclVendor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangModulesDeclVendor.h?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangModulesDeclVendor.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangModulesDeclVendor.h Mon Apr 20 11:31:29 2015
@@ -15,6 +15,7 @@
 #include "lldb/Symbol/DeclVendor.h"
 #include "lldb/Target/Platform.h"
 
+#include <set>
 #include <vector>
 
 namespace lldb_private
@@ -34,6 +35,10 @@ public:
     static ClangModulesDeclVendor *
     Create(Target &target);
     
+    typedef std::vector<ConstString> ModulePath;
+    typedef uintptr_t                ModuleID;
+    typedef std::vector<ModuleID>    ModuleVector;
+    
     //------------------------------------------------------------------
     /// Add a module to the list of modules to search.
     ///
@@ -41,6 +46,10 @@ public:
     ///     The path to the exact module to be loaded.  E.g., if the desired
     ///     module is std.io, then this should be { "std", "io" }.
     ///
+    /// @param[in] exported_modules
+    ///     If non-NULL, a pointer to a vector to populate with the ID of every
+    ///     module that is re-exported by the specified module.
+    ///
     /// @param[in] error_stream
     ///     A stream to populate with the output of the Clang parser when
     ///     it tries to load the module.
@@ -51,18 +60,69 @@ public:
     ///     load, then this will always return false for this ModuleImporter.
     //------------------------------------------------------------------
     virtual bool
-    AddModule(std::vector<llvm::StringRef> &path, Stream &error_stream) = 0;
+    AddModule(ModulePath &path,
+              ModuleVector *exported_modules,
+              Stream &error_stream) = 0;
     
     //------------------------------------------------------------------
-    /// Enumerate all the macros that are currently visible.
+    /// Add all modules referred to in a given compilation unit to the list
+    /// of modules to search.
+    ///
+    /// @param[in] cu
+    ///     The compilation unit to scan for imported modules.
+    ///
+    /// @param[in] exported_modules
+    ///     A vector to populate with the ID of each module loaded (directly
+    ///     and via re-exports) in this way.
+    ///
+    /// @param[in] error_stream
+    ///     A stream to populate with the output of the Clang parser when
+    ///     it tries to load the modules.
+    ///
+    /// @return
+    ///     True if all modules referred to by the compilation unit could be
+    ///     loaded; false if one could not be loaded.  If the compiler
+    ///     encountered a fatal error during a previous module
+    ///     load, then this will always return false for this ModuleImporter.
+    //------------------------------------------------------------------
+    virtual bool
+    AddModulesForCompileUnit(CompileUnit &cu,
+                             ModuleVector &exported_modules,
+                             Stream &error_stream) = 0;
+
+    //------------------------------------------------------------------
+    /// Enumerate all the macros that are defined by a given set of modules
+    /// that are already imported.
+    ///
+    /// @param[in] modules
+    ///     The unique IDs for all modules to query.  Later modules have higher
+    ///     priority, just as if you @imported them in that order.  This matters
+    ///     if module A #defines a macro and module B #undefs it.
     ///
     /// @param[in] handler
-    ///     A function that receives the text of each #define macro.
-    ///     If handler returns true, this function returns immediately,
-    ///     without calling handler again.
+    ///     A function to call with the text of each #define (including the
+    ///     #define directive).  #undef directives are not included; we simply
+    ///     elide any corresponding #define.  If this function returns true,
+    ///     we stop the iteration immediately.
     //------------------------------------------------------------------
     virtual void
-    ForEachMacro(std::function<bool (const std::string &)> handler) = 0;
+    ForEachMacro(const ModuleVector &modules,
+                 std::function<bool (const std::string &)> handler) = 0;
+    
+    //------------------------------------------------------------------
+    /// Query whether Clang supports modules for a particular language.
+    /// LLDB uses this to decide whether to try to find the modules loaded
+    /// by a gaiven compile unit.
+    ///
+    /// @param[in] language
+    ///     The language to query for.
+    ///
+    /// @return
+    ///     True if Clang has modules for the given language.
+    //------------------------------------------------------------------
+    static bool
+    LanguageSupportsClangModules (lldb::LanguageType language);
+    
 };
     
 }

Modified: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Mon Apr 20 11:31:29 2015
@@ -11,6 +11,8 @@
 #define liblldb_ClangPersistentVariables_h_
 
 #include "lldb/Expression/ClangExpressionVariable.h"
+#include "lldb/Expression/ClangModulesDeclVendor.h"
+
 #include "llvm/ADT/DenseMap.h"
 
 namespace lldb_private
@@ -63,11 +65,25 @@ public:
     clang::TypeDecl *
     GetPersistentType (const ConstString &name);
     
+    void
+    AddHandLoadedClangModule(ClangModulesDeclVendor::ModuleID module)
+    {
+        m_hand_loaded_clang_modules.push_back(module);
+    }
+    
+    const ClangModulesDeclVendor::ModuleVector &GetHandLoadedClangModules()
+    {
+        return m_hand_loaded_clang_modules;
+    }
+    
 private:
     uint32_t                                                m_next_persistent_variable_id;  ///< The counter used by GetNextResultName().
     
     typedef llvm::DenseMap<const char *, clang::TypeDecl *> PersistentTypeMap;
     PersistentTypeMap                                       m_persistent_types;             ///< The persistent types declared by the user.
+    
+    ClangModulesDeclVendor::ModuleVector                    m_hand_loaded_clang_modules;    ///< These are Clang modules we hand-loaded; these are the highest-
+                                                                                            ///< priority source for macros.
 };
 
 }

Modified: lldb/trunk/include/lldb/Symbol/CompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/CompileUnit.h?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/CompileUnit.h (original)
+++ lldb/trunk/include/lldb/Symbol/CompileUnit.h Mon Apr 20 11:31:29 2015
@@ -256,6 +256,18 @@ public:
     //------------------------------------------------------------------
     FileSpecList&
     GetSupportFiles ();
+    
+    //------------------------------------------------------------------
+    /// Get the compile unit's imported module list.
+    ///
+    /// This reports all the imports that the compile unit made,
+    /// including the current module.
+    ///
+    /// @return
+    ///     A list of imported module names.
+    //------------------------------------------------------------------
+    const std::vector<ConstString> &
+    GetImportedModules ();
 
     //------------------------------------------------------------------
     /// Get the SymbolFile plug-in user data.
@@ -400,6 +412,8 @@ protected:
     Flags m_flags; ///< Compile unit flags that help with partial parsing.
     std::vector<lldb::FunctionSP> m_functions; ///< The sparsely populated list of shared pointers to functions
                                          ///< that gets populated as functions get partially parsed.
+    std::vector<ConstString> m_imported_modules; ///< All modules, including the current module, imported by this
+                                                 ///< compile unit.
     FileSpecList m_support_files; ///< Files associated with this compile unit's line table and declarations.
     std::unique_ptr<LineTable> m_line_table_ap; ///< Line table that will get parsed on demand.
     lldb::VariableListSP m_variables; ///< Global and static variable list that will get parsed on demand.
@@ -407,11 +421,12 @@ protected:
 private:
     enum
     {
-        flagsParsedAllFunctions = (1u << 0), ///< Have we already parsed all our functions
-        flagsParsedVariables    = (1u << 1), ///< Have we already parsed globals and statics?
-        flagsParsedSupportFiles = (1u << 2), ///< Have we already parsed the support files for this compile unit?
-        flagsParsedLineTable    = (1u << 3),  ///< Have we parsed the line table already?
-        flagsParsedLanguage     = (1u << 4)   ///< Have we parsed the line table already?
+        flagsParsedAllFunctions     = (1u << 0), ///< Have we already parsed all our functions
+        flagsParsedVariables        = (1u << 1), ///< Have we already parsed globals and statics?
+        flagsParsedSupportFiles     = (1u << 2), ///< Have we already parsed the support files for this compile unit?
+        flagsParsedLineTable        = (1u << 3), ///< Have we parsed the line table already?
+        flagsParsedLanguage         = (1u << 4), ///< Have we parsed the line table already?
+        flagsParsedImportedModules  = (1u << 5)  ///< Have we parsed the imported modules already?
     };
 
     DISALLOW_COPY_AND_ASSIGN (CompileUnit);

Modified: lldb/trunk/include/lldb/Symbol/SymbolFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolFile.h?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/SymbolFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/SymbolFile.h Mon Apr 20 11:31:29 2015
@@ -124,6 +124,7 @@ public:
     virtual size_t          ParseCompileUnitFunctions (const SymbolContext& sc) = 0;
     virtual bool            ParseCompileUnitLineTable (const SymbolContext& sc) = 0;
     virtual bool            ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) = 0;
+    virtual bool            ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules) = 0;
     virtual size_t          ParseFunctionBlocks (const SymbolContext& sc) = 0;
     virtual size_t          ParseTypes (const SymbolContext& sc) = 0;
     virtual size_t          ParseVariablesForContext (const SymbolContext& sc) = 0;

Modified: lldb/trunk/include/lldb/Symbol/SymbolVendor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolVendor.h?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/SymbolVendor.h (original)
+++ lldb/trunk/include/lldb/Symbol/SymbolVendor.h Mon Apr 20 11:31:29 2015
@@ -66,6 +66,10 @@ public:
     virtual bool
     ParseCompileUnitSupportFiles (const SymbolContext& sc,
                                   FileSpecList& support_files);
+    
+    virtual bool
+    ParseImportedModules (const SymbolContext &sc,
+                          std::vector<ConstString> &imported_modules);
 
     virtual size_t
     ParseFunctionBlocks (const SymbolContext& sc);

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Mon Apr 20 11:31:29 2015
@@ -128,6 +128,9 @@ public:
     GetClangModuleSearchPaths ();
     
     bool
+    GetEnableAutoImportClangModules () const;
+    
+    bool
     GetEnableSyntheticValue () const;
     
     uint32_t

Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Mon Apr 20 11:31:29 2015
@@ -24,6 +24,7 @@
 #include "lldb/Expression/ClangExpression.h"
 #include "lldb/Expression/ClangExpressionDeclMap.h"
 #include "lldb/Expression/ClangModulesDeclVendor.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Expression/IRExecutionUnit.h"
 #include "lldb/Expression/IRDynamicChecks.h"
 #include "lldb/Expression/IRInterpreter.h"
@@ -96,12 +97,15 @@ std::string GetBuiltinIncludePath(const
 
 class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks
 {
-    ClangModulesDeclVendor  &m_decl_vendor;
-    StreamString             m_error_stream;
-    bool                     m_has_errors = false;
+    ClangModulesDeclVendor     &m_decl_vendor;
+    ClangPersistentVariables   &m_persistent_vars;
+    StreamString                m_error_stream;
+    bool                        m_has_errors = false;
 public:
-    LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor) :
-        m_decl_vendor(decl_vendor)
+    LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor,
+                              ClangPersistentVariables &persistent_vars) :
+        m_decl_vendor(decl_vendor),
+        m_persistent_vars(persistent_vars)
     {
     }
     
@@ -109,19 +113,26 @@ public:
                               ModuleIdPath path,
                               const clang::Module * /*null*/)
     {
-        std::vector<llvm::StringRef> string_path;
+        std::vector<ConstString> string_path;
         
         for (const std::pair<IdentifierInfo *, SourceLocation> &component : path)
         {
-            string_path.push_back(component.first->getName());
+            string_path.push_back(ConstString(component.first->getName()));
         }
      
         StreamString error_stream;
         
-        if (!m_decl_vendor.AddModule(string_path, m_error_stream))
+        ClangModulesDeclVendor::ModuleVector exported_modules;
+        
+        if (!m_decl_vendor.AddModule(string_path, &exported_modules, m_error_stream))
         {
             m_has_errors = true;
         }
+        
+        for (ClangModulesDeclVendor::ModuleID module : exported_modules)
+        {
+            m_persistent_vars.AddHandLoadedClangModule(module);
+        }
     }
     
     bool hasErrors()
@@ -298,7 +309,7 @@ ClangExpressionParser::ClangExpressionPa
     
     if (ClangModulesDeclVendor *decl_vendor = target_sp->GetClangModulesDeclVendor())
     {
-        std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(*decl_vendor));
+        std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(*decl_vendor, target_sp->GetPersistentVariables()));
         m_pp_callbacks = static_cast<LLDBPreprocessorCallbacks*>(pp_callbacks.get());
         m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
     }
@@ -309,10 +320,10 @@ ClangExpressionParser::ClangExpressionPa
     m_builtin_context.reset(new Builtin::Context());
 
     std::unique_ptr<clang::ASTContext> ast_context(new ASTContext(m_compiler->getLangOpts(),
-                                                                 m_compiler->getSourceManager(),
-                                                                 m_compiler->getPreprocessor().getIdentifierTable(),
-                                                                 *m_selector_table.get(),
-                                                                 *m_builtin_context.get()));
+                                                                  m_compiler->getSourceManager(),
+                                                                  m_compiler->getPreprocessor().getIdentifierTable(),
+                                                                  *m_selector_table.get(),
+                                                                  *m_builtin_context.get()));
     
     ast_context->InitBuiltinTypes(m_compiler->getTarget());
 

Modified: lldb/trunk/source/Expression/ClangModulesDeclVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangModulesDeclVendor.cpp?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangModulesDeclVendor.cpp (original)
+++ lldb/trunk/source/Expression/ClangModulesDeclVendor.cpp Mon Apr 20 11:31:29 2015
@@ -16,6 +16,7 @@
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Target/Target.h"
 
 #include "clang/Basic/TargetInfo.h"
@@ -61,9 +62,15 @@ namespace {
                                    std::unique_ptr<clang::Parser> &&parser);
         
         virtual bool
-        AddModule(std::vector<llvm::StringRef> &path,
+        AddModule(ModulePath &path,
+                  ModuleVector *exported_modules,
                   Stream &error_stream) override;
         
+        virtual bool
+        AddModulesForCompileUnit(CompileUnit &cu,
+                                 ModuleVector &exported_modules,
+                                 Stream &error_stream) override;
+        
         virtual uint32_t
         FindDecls (const ConstString &name,
                    bool append,
@@ -71,19 +78,36 @@ namespace {
                    std::vector <clang::NamedDecl*> &decls) override;
         
         virtual void
-        ForEachMacro(std::function<bool (const std::string &)> handler) override;
+        ForEachMacro(const ModuleVector &modules,
+                     std::function<bool (const std::string &)> handler) override;
         
         ~ClangModulesDeclVendorImpl();
         
     private:
+        void
+        ReportModuleExportsHelper (std::set<ClangModulesDeclVendor::ModuleID> &exports,
+                                   clang::Module *module);
+
+        void
+        ReportModuleExports (ModuleVector &exports,
+                             clang::Module *module);
+
         clang::ModuleLoadResult
         DoGetModule(clang::ModuleIdPath path, bool make_visible);
         
+        bool                                                m_enabled = false;
+        
         llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine>  m_diagnostics_engine;
         llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> m_compiler_invocation;
         std::unique_ptr<clang::CompilerInstance>            m_compiler_instance;
         std::unique_ptr<clang::Parser>                      m_parser;
         size_t                                              m_source_location_index = 0; // used to give name components fake SourceLocations
+
+        typedef std::vector<ConstString>                    ImportedModule;
+        typedef std::map<ImportedModule, clang::Module *>   ImportedModuleMap;
+        typedef std::set<ModuleID>                          ImportedModuleSet;
+        ImportedModuleMap                                   m_imported_modules;
+        ImportedModuleSet                                   m_user_imported_modules;
     };
 }
 
@@ -156,12 +180,47 @@ ClangModulesDeclVendorImpl::ClangModules
     m_diagnostics_engine(diagnostics_engine),
     m_compiler_invocation(compiler_invocation),
     m_compiler_instance(std::move(compiler_instance)),
-    m_parser(std::move(parser))
+    m_parser(std::move(parser)),
+    m_imported_modules()
+{
+}
+
+void
+ClangModulesDeclVendorImpl::ReportModuleExportsHelper (std::set<ClangModulesDeclVendor::ModuleID> &exports,
+                                                       clang::Module *module)
+{
+    if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))
+        return;
+    
+    exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module));
+    
+    llvm::SmallVector<clang::Module*, 2> sub_exports;
+    
+    module->getExportedModules(sub_exports);
+
+    for (clang::Module *module : sub_exports)
+    {
+        ReportModuleExportsHelper(exports, module);
+    }
+}
+
+void
+ClangModulesDeclVendorImpl::ReportModuleExports (ClangModulesDeclVendor::ModuleVector &exports,
+                                                 clang::Module *module)
 {
+    std::set<ClangModulesDeclVendor::ModuleID> exports_set;
+    
+    ReportModuleExportsHelper(exports_set, module);
+    
+    for (ModuleID module : exports_set)
+    {
+        exports.push_back(module);
+    }
 }
 
 bool
-ClangModulesDeclVendorImpl::AddModule(std::vector<llvm::StringRef> &path,
+ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
+                                      ModuleVector *exported_modules,
                                       Stream &error_stream)
 {
     // Fail early.
@@ -172,9 +231,31 @@ ClangModulesDeclVendorImpl::AddModule(st
         return false;
     }
     
-    if (!m_compiler_instance->getPreprocessor().getHeaderSearchInfo().lookupModule(path[0]))
+    // Check if we've already imported this module.
+    
+    std::vector<ConstString> imported_module;
+    
+    for (ConstString path_component : path)
+    {
+        imported_module.push_back(path_component);
+    }
+    
+    {
+        ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);
+        
+        if (mi != m_imported_modules.end())
+        {
+            if (exported_modules)
+            {
+                ReportModuleExports(*exported_modules, mi->second);
+            }
+            return true;
+        }
+    }
+    
+    if (!m_compiler_instance->getPreprocessor().getHeaderSearchInfo().lookupModule(path[0].GetStringRef()))
     {
-        error_stream.Printf("error: Header search couldn't locate module %s\n", path[0].str().c_str());
+        error_stream.Printf("error: Header search couldn't locate module %s\n", path[0].AsCString());
         return false;
     }
     
@@ -183,9 +264,9 @@ ClangModulesDeclVendorImpl::AddModule(st
     {
         clang::SourceManager &source_manager = m_compiler_instance->getASTContext().getSourceManager();
         
-        for (llvm::StringRef &component : path)
+        for (ConstString path_component : path)
         {
-            clang_path.push_back(std::make_pair(&m_compiler_instance->getASTContext().Idents.get(component),
+            clang_path.push_back(std::make_pair(&m_compiler_instance->getASTContext().Idents.get(path_component.GetStringRef()),
                                                 source_manager.getLocForStartOfFile(source_manager.getMainFileID()).getLocWithOffset(m_source_location_index++)));
         }
     }
@@ -199,7 +280,7 @@ ClangModulesDeclVendorImpl::AddModule(st
     if (!top_level_module)
     {
         diagnostic_consumer->DumpDiagnostics(error_stream);
-        error_stream.Printf("error: Couldn't load top-level module %s\n", path[0].str().c_str());
+        error_stream.Printf("error: Couldn't load top-level module %s\n", path[0].AsCString());
         return false;
     }
     
@@ -207,7 +288,7 @@ ClangModulesDeclVendorImpl::AddModule(st
     
     for (size_t ci = 1; ci < path.size(); ++ci)
     {
-        llvm::StringRef &component = path[ci];
+        llvm::StringRef component = path[ci].GetStringRef();
         submodule = submodule->findSubmodule(component.str());
         if (!submodule)
         {
@@ -219,7 +300,66 @@ ClangModulesDeclVendorImpl::AddModule(st
     
     clang::Module *requested_module = DoGetModule(clang_path, true);
     
-    return (requested_module != nullptr);
+    if (requested_module != nullptr)
+    {
+        if (exported_modules)
+        {
+            ReportModuleExports(*exported_modules, requested_module);
+        }
+
+        m_imported_modules[imported_module] = requested_module;
+        
+        m_enabled = true;
+        
+        return true;
+    }
+    
+    return false;
+}
+
+
+bool
+ClangModulesDeclVendor::LanguageSupportsClangModules (lldb::LanguageType language)
+{
+    switch (language)
+    {
+    default:
+        return false;
+    // C++ and friends to be added
+    case lldb::LanguageType::eLanguageTypeC:
+    case lldb::LanguageType::eLanguageTypeC11:
+    case lldb::LanguageType::eLanguageTypeC89:
+    case lldb::LanguageType::eLanguageTypeC99:
+    case lldb::LanguageType::eLanguageTypeObjC:
+        return true;
+    }
+}
+
+bool
+ClangModulesDeclVendorImpl::AddModulesForCompileUnit(CompileUnit &cu,
+                                                     ClangModulesDeclVendor::ModuleVector &exported_modules,
+                                                     Stream &error_stream)
+{
+    if (LanguageSupportsClangModules(cu.GetLanguage()))
+    {
+        std::vector<ConstString> imported_modules = cu.GetImportedModules();
+        
+        for (ConstString imported_module : imported_modules)
+        {
+            std::vector<ConstString> path;
+            
+            path.push_back(imported_module);
+            
+            if (!AddModule(path, &exported_modules, error_stream))
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+
+    return true;
 }
 
 // ClangImporter::lookupValue
@@ -230,6 +370,11 @@ ClangModulesDeclVendorImpl::FindDecls (c
                                        uint32_t max_matches,
                                        std::vector <clang::NamedDecl*> &decls)
 {
+    if (!m_enabled)
+    {
+        return 0;
+    }
+
     if (!append)
         decls.clear();
     
@@ -257,14 +402,90 @@ ClangModulesDeclVendorImpl::FindDecls (c
 }
 
 void
-ClangModulesDeclVendorImpl::ForEachMacro(std::function<bool (const std::string &)> handler)
+ClangModulesDeclVendorImpl::ForEachMacro(const ClangModulesDeclVendor::ModuleVector &modules,
+                                         std::function<bool (const std::string &)> handler)
 {
+    if (!m_enabled)
+    {
+        return;
+    }
+    
+    typedef std::map<ModuleID, ssize_t> ModulePriorityMap;
+    ModulePriorityMap module_priorities;
+    
+    ssize_t priority = 0;
+    
+    for (ModuleID module : modules)
+    {
+        module_priorities[module] = priority++;
+    }
+    
+    if (m_compiler_instance->getPreprocessor().getExternalSource())
+    {
+        m_compiler_instance->getPreprocessor().getExternalSource()->ReadDefinedMacros();
+    }
     
     for (clang::Preprocessor::macro_iterator mi = m_compiler_instance->getPreprocessor().macro_begin(),
                                              me = m_compiler_instance->getPreprocessor().macro_end();
          mi != me;
          ++mi)
     {
+        const clang::IdentifierInfo *ii = nullptr;
+        
+        {
+            if (clang::IdentifierInfoLookup *lookup = m_compiler_instance->getPreprocessor().getIdentifierTable().getExternalIdentifierLookup())
+            {
+                lookup->get(mi->first->getName());
+            }
+            if (!ii)
+            {
+                ii = mi->first;
+            }
+        }
+        
+        ssize_t found_priority = -1;
+        clang::MacroInfo *info = nullptr;
+        
+        for (clang::MacroDirective *directive = m_compiler_instance->getPreprocessor().getMacroDirectiveHistory(ii);
+             directive != nullptr;
+             directive = directive->getPrevious())
+        {
+            unsigned module_id = directive->getOwningModuleID();
+            
+            if (!module_id)
+                continue;
+            
+            clang::Module *module = m_compiler_instance->getModuleManager()->getModule(module_id);
+            
+            {
+                ModulePriorityMap::iterator pi = module_priorities.find(reinterpret_cast<ModuleID>(module));
+                
+                if (pi != module_priorities.end() && pi->second > found_priority)
+                {
+                    info = directive->getMacroInfo();
+                    found_priority = pi->second;
+                }
+            }
+            
+            clang::Module *top_level_module = module->getTopLevelModule();
+            
+            if (top_level_module != module)
+            {
+                ModulePriorityMap::iterator pi = module_priorities.find(reinterpret_cast<ModuleID>(top_level_module));
+
+                if ((pi != module_priorities.end()) && pi->second > found_priority)
+                {
+                    info = directive->getMacroInfo();
+                    found_priority = pi->second;
+                }
+            }
+        }
+        
+        if (!info)
+        {
+            continue;
+        }
+        
         if (mi->second->getKind() == clang::MacroDirective::MD_Define)
         {            
             std::string macro_expansion = "#define ";

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Mon Apr 20 11:31:29 2015
@@ -458,7 +458,35 @@ ClangUserExpression::Parse (Stream &erro
     
     if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor())
     {
-        decl_vendor->ForEachMacro([log, &prefix] (const std::string &expansion) -> bool {
+        const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = m_target->GetPersistentVariables().GetHandLoadedClangModules();
+        ClangModulesDeclVendor::ModuleVector modules_for_macros;
+        
+        for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
+        {
+            modules_for_macros.push_back(module);
+        }
+
+        if (m_target->GetEnableAutoImportClangModules())
+        {
+            if (StackFrame *frame = exe_ctx.GetFramePtr())
+            {
+                if (Block *block = frame->GetFrameBlock())
+                {
+                    SymbolContext sc;
+                    
+                    block->CalculateSymbolContext(&sc);
+                    
+                    if (sc.comp_unit)
+                    {
+                        StreamString error_stream;
+                        
+                        decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
+                    }
+                }
+            }
+        }
+        
+        decl_vendor->ForEachMacro(modules_for_macros, [log, &prefix] (const std::string &expansion) -> bool {
             prefix.append(expansion);
             prefix.append("\n");
             return false;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Mon Apr 20 11:31:29 2015
@@ -446,6 +446,31 @@ DWARFCompileUnit::BuildAddressRangeTable
         }
     }
     
+    if (debug_aranges->IsEmpty())
+    {
+        // We got nothing from the functions, maybe we have a line tables only
+        // situation. Check the line tables and build the arange table from this.
+        SymbolContext sc;
+        sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this);
+        if (sc.comp_unit)
+        {
+            LineTable *line_table = sc.comp_unit->GetLineTable();
+
+            if (line_table)
+            {
+                LineTable::FileAddressRanges file_ranges;
+                const bool append = true;
+                const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append);
+                for (uint32_t idx=0; idx<num_ranges; ++idx)
+                {
+                    const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx);
+                    debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd());
+                    printf ("0x%8.8x: [0x%16.16llx - 0x%16.16llx)\n", GetOffset(), range.GetRangeBase(), range.GetRangeEnd());
+                }
+            }
+        }
+    }
+    
     // Keep memory down by clearing DIEs if this generate function
     // caused them to be parsed
     if (clear_dies)

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon Apr 20 11:31:29 2015
@@ -27,6 +27,8 @@
 #include "llvm/Support/Casting.h"
 
 #include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/Scalar.h"
@@ -36,6 +38,8 @@
 #include "lldb/Core/Timer.h"
 #include "lldb/Core/Value.h"
 
+#include "lldb/Expression/ClangModulesDeclVendor.h"
+
 #include "lldb/Host/Host.h"
 
 #include "lldb/Symbol/Block.h"
@@ -515,6 +519,7 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectF
     m_indexed (false),
     m_is_external_ast_source (false),
     m_using_apple_tables (false),
+    m_fetched_external_modules (false),
     m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
     m_ranges(),
     m_unique_ast_type_map ()
@@ -1263,6 +1268,25 @@ SymbolFileDWARF::ParseCompileUnitSupport
     return false;
 }
 
+bool
+SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
+{
+    assert (sc.comp_unit);
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+    if (dwarf_cu)
+    {
+        if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
+        {
+            UpdateExternalModuleListIfNeeded();
+            for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules)
+            {
+                imported_modules.push_back(external_type_module.second.m_name);
+            }
+        }
+    }
+    return false;
+}
+
 struct ParseDWARFLineTableCallbackInfo
 {
     LineTable* line_table;
@@ -2845,7 +2869,60 @@ SymbolFileDWARF::GetFunction (DWARFCompi
     return false;
 }
 
-
+void
+SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
+{
+    if (m_fetched_external_modules)
+        return;
+    m_fetched_external_modules = true;
+    
+    DWARFDebugInfo * debug_info = DebugInfo();
+    debug_info->GetNumCompileUnits();
+    
+    const uint32_t num_compile_units = GetNumCompileUnits();
+    for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+    {
+        DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+        
+        const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
+        if (die && die->HasChildren() == false)
+        {
+            const uint64_t name_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_name, UINT64_MAX);
+            const uint64_t dwo_path_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_GNU_dwo_name, UINT64_MAX);
+            
+            if (name_strp != UINT64_MAX)
+            {
+                if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end())
+                {
+                    const char *name = get_debug_str_data().PeekCStr(name_strp);
+                    const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp);
+                    if (name || dwo_path)
+                    {
+                        ModuleSP module_sp;
+                        if (dwo_path)
+                        {
+                            ModuleSpec dwo_module_spec;
+                            dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
+                            dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
+                            //printf ("Loading dwo = '%s'\n", dwo_path);
+                            Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
+                        }
+                        
+                        if (dwo_path_strp != LLDB_INVALID_UID)
+                        {
+                            m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp };
+                        }
+                        else
+                        {
+                            // This hack should be removed promptly once clang emits both.
+                            m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp };
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
 
 SymbolFileDWARF::GlobalVariableMap &
 SymbolFileDWARF::GetGlobalAranges()

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Mon Apr 20 11:31:29 2015
@@ -103,6 +103,7 @@ public:
     virtual size_t          ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc);
     virtual bool            ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc);
     virtual bool            ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList& support_files);
+    virtual bool            ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules);
     virtual size_t          ParseFunctionBlocks (const lldb_private::SymbolContext& sc);
     virtual size_t          ParseTypes (const lldb_private::SymbolContext& sc);
     virtual size_t          ParseVariablesForContext (const lldb_private::SymbolContext& sc);
@@ -547,6 +548,13 @@ protected:
     FixupAddress (lldb_private::Address &addr);
 
     typedef std::set<lldb_private::Type *> TypeSet;
+    
+    typedef struct {
+        lldb_private::ConstString   m_name;
+        lldb::ModuleSP              m_module_sp;
+    } ClangModuleInfo;
+    
+    typedef std::map<uint64_t, ClangModuleInfo> ExternalTypeModuleMap;
 
     void
     GetTypes (DWARFCompileUnit* dwarf_cu,
@@ -560,6 +568,9 @@ protected:
 
     GlobalVariableMap &
     GetGlobalAranges();
+    
+    void
+    UpdateExternalModuleListIfNeeded();
 
     lldb::ModuleWP                        m_debug_map_module_wp;
     SymbolFileDWARFDebugMap *             m_debug_map_symfile;
@@ -589,6 +600,7 @@ protected:
     std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
     std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
     std::unique_ptr<GlobalVariableMap>  m_global_aranges_ap;
+    ExternalTypeModuleMap               m_external_type_modules;
     NameToDIE                           m_function_basename_index;  // All concrete functions
     NameToDIE                           m_function_fullname_index;  // All concrete functions
     NameToDIE                           m_function_method_index;    // All inlined functions
@@ -599,7 +611,8 @@ protected:
     NameToDIE                           m_namespace_index;          // All type DIE offsets
     bool                                m_indexed:1,
                                         m_is_external_ast_source:1,
-                                        m_using_apple_tables:1;
+                                        m_using_apple_tables:1,
+                                        m_fetched_external_modules:1;
     lldb_private::LazyBool              m_supports_DW_AT_APPLE_objc_complete_type;
 
     std::unique_ptr<DWARFDebugRanges>     m_ranges;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Mon Apr 20 11:31:29 2015
@@ -227,18 +227,11 @@ public:
                     
                     if (exe_objfile && exe_sym_vendor)
                     {
-                        if (oso_symfile->GetNumCompileUnits() == 1)
-                        {
-                            oso_symfile->SetDebugMapModule(exe_module_sp);
-                            // Set the ID of the symbol file DWARF to the index of the OSO
-                            // shifted left by 32 bits to provide a unique prefix for any
-                            // UserID's that get created in the symbol file.
-                            oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
-                        }
-                        else
-                        {
-                            oso_symfile->SetID (UINT64_MAX);
-                        }
+                        oso_symfile->SetDebugMapModule(exe_module_sp);
+                        // Set the ID of the symbol file DWARF to the index of the OSO
+                        // shifted left by 32 bits to provide a unique prefix for any
+                        // UserID's that get created in the symbol file.
+                        oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
                     }
                     return symbol_vendor;
                 }
@@ -743,6 +736,14 @@ SymbolFileDWARFDebugMap::ParseCompileUni
     return false;
 }
 
+bool
+SymbolFileDWARFDebugMap::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules)
+{
+    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+    if (oso_dwarf)
+        return oso_dwarf->ParseImportedModules(sc, imported_modules);
+    return false;
+}
 
 size_t
 SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h Mon Apr 20 11:31:29 2015
@@ -70,6 +70,7 @@ public:
     virtual size_t          ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc);
     virtual bool            ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc);
     virtual bool            ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files);
+    virtual bool            ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) override;
     virtual size_t          ParseFunctionBlocks (const lldb_private::SymbolContext& sc);
     virtual size_t          ParseTypes (const lldb_private::SymbolContext& sc);
     virtual size_t          ParseVariablesForContext (const lldb_private::SymbolContext& sc);

Modified: lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp Mon Apr 20 11:31:29 2015
@@ -266,6 +266,12 @@ SymbolFileSymtab::ParseCompileUnitSuppor
     return false;
 }
 
+bool
+SymbolFileSymtab::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules)
+{
+    return false;
+}
+
 size_t
 SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
 {

Modified: lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h Mon Apr 20 11:31:29 2015
@@ -65,6 +65,9 @@ public:
 
     virtual bool
     ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files);
+    
+    virtual bool
+    ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules);
 
     virtual size_t
     ParseFunctionBlocks (const lldb_private::SymbolContext& sc);

Modified: lldb/trunk/source/Symbol/CompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CompileUnit.cpp?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/CompileUnit.cpp (original)
+++ lldb/trunk/source/Symbol/CompileUnit.cpp Mon Apr 20 11:31:29 2015
@@ -436,6 +436,23 @@ CompileUnit::SetVariableList(VariableLis
     m_variables = variables;
 }
 
+const std::vector<ConstString> &
+CompileUnit::GetImportedModules ()
+{
+    if (m_imported_modules.empty() &&
+        m_flags.IsClear(flagsParsedImportedModules))
+    {
+        m_flags.Set(flagsParsedImportedModules);
+        if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor())
+        {
+            SymbolContext sc;
+            CalculateSymbolContext(&sc);
+            symbol_vendor->ParseImportedModules(sc, m_imported_modules);
+        }
+    }
+    return m_imported_modules;
+}
+
 FileSpecList&
 CompileUnit::GetSupportFiles ()
 {

Modified: lldb/trunk/source/Symbol/SymbolVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolVendor.cpp?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/SymbolVendor.cpp (original)
+++ lldb/trunk/source/Symbol/SymbolVendor.cpp Mon Apr 20 11:31:29 2015
@@ -198,6 +198,21 @@ SymbolVendor::ParseCompileUnitSupportFil
     return false;
 }
 
+bool
+SymbolVendor::ParseImportedModules (const SymbolContext &sc,
+                                    std::vector<ConstString> &imported_modules)
+{
+    ModuleSP module_sp(GetModule());
+    if (module_sp)
+    {
+        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+        if (m_sym_file_ap.get())
+            return m_sym_file_ap->ParseImportedModules(sc, imported_modules);
+    }
+    return false;
+    
+}
+
 size_t
 SymbolVendor::ParseFunctionBlocks (const SymbolContext &sc)
 {

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Mon Apr 20 11:31:29 2015
@@ -2927,6 +2927,7 @@ g_properties[] =
     { "exec-search-paths"                  , OptionValue::eTypeFileSpecList, false, 0                       , NULL, NULL, "Executable search paths to use when locating executable files whose paths don't match the local file system." },
     { "debug-file-search-paths"            , OptionValue::eTypeFileSpecList, false, 0                       , NULL, NULL, "List of directories to be searched when locating debug symbol files." },
     { "clang-module-search-paths"          , OptionValue::eTypeFileSpecList, false, 0                       , NULL, NULL, "List of directories to be searched when locating modules for Clang." },
+    { "auto-import-clang-modules"          , OptionValue::eTypeBoolean   , false, false                     , NULL, NULL, "Automatically load Clang modules referred to by the program." },
     { "max-children-count"                 , OptionValue::eTypeSInt64    , false, 256                       , NULL, NULL, "Maximum number of children to expand in any level of depth." },
     { "max-string-summary-length"          , OptionValue::eTypeSInt64    , false, 1024                      , NULL, NULL, "Maximum number of characters to show when using %s in summary strings." },
     { "max-memory-read-size"               , OptionValue::eTypeSInt64    , false, 1024                      , NULL, NULL, "Maximum number of bytes that 'memory read' will fetch before --force must be specified." },
@@ -2978,6 +2979,7 @@ enum
     ePropertyExecutableSearchPaths,
     ePropertyDebugFileSearchPaths,
     ePropertyClangModuleSearchPaths,
+    ePropertyAutoImportClangModules,
     ePropertyMaxChildrenCount,
     ePropertyMaxSummaryLength,
     ePropertyMaxMemReadSize,
@@ -3332,6 +3334,13 @@ TargetProperties::GetClangModuleSearchPa
 }
 
 bool
+TargetProperties::GetEnableAutoImportClangModules() const
+{
+    const uint32_t idx = ePropertyAutoImportClangModules;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
+bool
 TargetProperties::GetEnableSyntheticValue () const
 {
     const uint32_t idx = ePropertyEnableSynthetic;

Modified: lldb/trunk/test/functionalities/data-formatter/typedef_array/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/typedef_array/Makefile?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/typedef_array/Makefile (original)
+++ lldb/trunk/test/functionalities/data-formatter/typedef_array/Makefile Mon Apr 20 11:31:29 2015
@@ -1,4 +0,0 @@
-LEVEL = ../../../make
-CXX_SOURCES := main.cpp
-CXXFLAGS += -std=c++11
-include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/lang/objc/modules-auto-import/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/modules-auto-import/Makefile?rev=235313&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/modules-auto-import/Makefile (added)
+++ lldb/trunk/test/lang/objc/modules-auto-import/Makefile Mon Apr 20 11:31:29 2015
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+OBJC_SOURCES := main.m
+
+CFLAGS += -fmodules -gmodules -g
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/lang/objc/modules-auto-import/TestModulesAutoImport.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/modules-auto-import/TestModulesAutoImport.py?rev=235313&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/modules-auto-import/TestModulesAutoImport.py (added)
+++ lldb/trunk/test/lang/objc/modules-auto-import/TestModulesAutoImport.py Mon Apr 20 11:31:29 2015
@@ -0,0 +1,78 @@
+"""Test that importing modules in Objective-C works as expected."""
+
+import os, time
+import unittest2
+import lldb
+import platform
+import lldbutil
+
+from distutils.version import StrictVersion
+
+from lldbtest import *
+
+class ObjCModulesAutoImportTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipUnlessDarwin
+    @dsym_test
+    @unittest2.expectedFailure("rdar://problem/19991953")
+    def test_expr_with_dsym(self):
+        self.buildDsym()
+        self.expr()
+
+    @dwarf_test
+    @skipIfFreeBSD
+    @skipIfLinux
+    def test_expr_with_dwarf(self):
+        self.buildDwarf()
+        self.expr()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line number to break inside main().
+        self.line = line_number('main.m', '// Set breakpoint 0 here.')
+
+    def applies(self):
+        if platform.system() != "Darwin":
+            return False
+        if StrictVersion('12.0.0') > platform.release():
+            return False
+
+        return True
+
+    def common_setup(self):
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        # Break inside the foo function which takes a bar_ptr argument.
+        lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
+
+        # The breakpoint should have a hit count of 1.
+        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+            substrs = [' resolved, hit count = 1'])
+
+    def expr(self):
+        if not self.applies():
+            return
+
+        self.common_setup()
+
+        self.runCmd("settings set target.auto-import-clang-modules true")
+
+        self.expect("p getpid()", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["pid_t"])
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/lang/objc/modules-auto-import/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/modules-auto-import/main.m?rev=235313&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/modules-auto-import/main.m (added)
+++ lldb/trunk/test/lang/objc/modules-auto-import/main.m Mon Apr 20 11:31:29 2015
@@ -0,0 +1,7 @@
+ at import Darwin;
+
+int main()
+{
+    size_t ret = printf("Stop here\n"); // Set breakpoint 0 here.
+    return ret;
+}

Modified: lldb/trunk/test/lang/objc/modules-incomplete/TestIncompleteModules.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/modules-incomplete/TestIncompleteModules.py?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/test/lang/objc/modules-incomplete/TestIncompleteModules.py (original)
+++ lldb/trunk/test/lang/objc/modules-incomplete/TestIncompleteModules.py Mon Apr 20 11:31:29 2015
@@ -75,6 +75,12 @@ class IncompleteModulesTestCase(TestBase
         self.expect("expr [myObject privateMethod]", VARIABLES_DISPLAYED_CORRECTLY,
             substrs = ["int", "5"])
 
+        self.expect("expr MIN(2,3)", "#defined macro was found",
+            substrs = ["int", "2"])
+
+        self.expect("expr MAX(2,3)", "#undefd macro was correcltly not found",
+            error=True)
+
 if __name__ == '__main__':
     import atexit
     lldb.SBDebugger.Initialize()

Modified: lldb/trunk/test/lang/objc/modules-incomplete/myModule.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/modules-incomplete/myModule.h?rev=235313&r1=235312&r2=235313&view=diff
==============================================================================
--- lldb/trunk/test/lang/objc/modules-incomplete/myModule.h (original)
+++ lldb/trunk/test/lang/objc/modules-incomplete/myModule.h Mon Apr 20 11:31:29 2015
@@ -1,5 +1,7 @@
 @import Foundation;
 
+#undef MAX
+
 @interface MyClass : NSObject {
 };
 -(void)publicMethod;





More information about the lldb-commits mailing list