<div dir="ltr">The source code is the inferior for TestDataFormatterSynthVal (<a href="https://github.com/llvm-mirror/lldb/blob/fc6c6b9f1aa893b7fd1bd04ae9f05ff3f82d63c2/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/main.cpp" target="_blank">https://github.com/llvm-mirror/lldb/blob/fc6c6b9f1aa893b7fd1bd04ae9f05ff3f82d63c2/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/main.cpp</a>) what doesn't refer to anything in the std namespace and have no using directives either.<div><br><div class="gmail_quote"><div dir="ltr">On Wed, Dec 2, 2015 at 7:01 PM Greg Clayton <<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">So the question is why is "S" being found in "std" when we are essentially looking for "::S"?? Do we have a "using namespace std;" in the source? We recently added support for using all of the using directives in the user code so it might be doing a  "using namespace std;" into the expression due to the source file having it...<br>
<br>
> On Dec 2, 2015, at 3:52 AM, Tamas Berghammer <<a href="mailto:tberghammer@google.com" target="_blank">tberghammer@google.com</a>> wrote:<br>
><br>
> Hi Greg,<br>
><br>
> I reverted this CL as it regressed TestDataFormatterSynthVal.py on the Linux buildbot.<br>
><br>
> The problem is that when we evaluate the "expression struct S { myInt theInt{12}; }; S()" command then the return type is displayed as "std::S" instead of displaying it as the type defined on the command line.<br>
><br>
> The definition for the conflicting type ("target modul lookup -t S -A"):<br>
> /usr/lib/x86_64-linux-gnu/libstdc++.so.6:<br>
> id = {0x0021550c}, name = "std::S", byte-size = 8, decl = string-inst.cc:43, compiler_type = "typedef std::S"<br>
>      typedef 'std::S': id = {0x00213434}, name = "basic_string<char, std::char_traits<char>, std::allocator<char> >", qualified = "std::basic_string<char, std::char_traits<char>, std::allocator<char> >", byte-size = 8, decl = basic_string.h:112, compiler_type = "class basic_string {<br>
> <Members omitted, I can send it to you if you need them><br>
> }<br>
><br>
> If I change the name of the type we define in the expression to something not conflicting with a type name in the std namespace then it works fine but it should work even in case of conflicting types as they are leave in different namespaces and it also worked before your change.<br>
><br>
> Currently I don't fully understand your change but please let me know if I can help you to figure out why the test is failing on Linux.<br>
><br>
> Thanks,<br>
> Tamas<br>
><br>
> On Wed, Dec 2, 2015 at 12:46 AM Greg Clayton via lldb-commits <<a href="mailto:lldb-commits@lists.llvm.org" target="_blank">lldb-commits@lists.llvm.org</a>> wrote:<br>
> Author: gclayton<br>
> Date: Tue Dec  1 18:43:32 2015<br>
> New Revision: 254476<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=254476&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=254476&view=rev</a><br>
> Log:<br>
> Added support for -gmodule debugging when debug info is left in the .o files on Darwin.<br>
><br>
> This is done by finding the types that are forward declarations that come from a module, and loading that module's debug info in a separate lldb_private::Module, and copying the type over into the current module using a ClangASTImporter object. ClangASTImporter objects are already used to copy types from on clang::ASTContext to another for expressions so the type copying code has been around for a while.<br>
><br>
> A new FindTypes variant was added to SymbolVendor and SymbolFile:<br>
><br>
> size_t<br>
> SymbolVendor::FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types);<br>
><br>
> size_t<br>
> SymbolVendor::FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types);<br>
><br>
> The CompilerContext is a way to represent the exact context of a type and pass it through an agnostic API boundary so that we can find that exact context elsewhere in another file. This was required here because we can have a module that has submodules, both of which have a "foo" type.<br>
><br>
> I am not able to add tests for this yet as we currently don't build our C/C++/ObjC binaries with the clang binary that we build. There are some driver issues where it can't find the header files for the C and C++ standard library which makes compiling these tests hard. We can't also guarantee that if we are building with clang that it supporst the exact format of -gmodule debugging that we are trying to test. We have had other versions of clang that had a different implementation of -gmodule debugging that we are no longer supporting, so we can't enable tests if we are building with clang without compiling something and looking at the structure of the DWARF that was generated to ensure that it is the format we can actually use.<br>
><br>
><br>
> Modified:<br>
>     lldb/trunk/include/lldb/Symbol/ClangASTContext.h<br>
>     lldb/trunk/include/lldb/Symbol/ClangASTImporter.h<br>
>     lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h<br>
>     lldb/trunk/include/lldb/Symbol/SymbolFile.h<br>
>     lldb/trunk/include/lldb/Symbol/SymbolVendor.h<br>
>     lldb/trunk/include/lldb/Symbol/Type.h<br>
>     lldb/trunk/include/lldb/lldb-forward.h<br>
>     lldb/trunk/include/lldb/lldb-private-enumerations.h<br>
>     lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py<br>
>     lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h<br>
>     lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp<br>
>     lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h<br>
>     lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp<br>
>     lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h<br>
>     lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp<br>
>     lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h<br>
>     lldb/trunk/source/Symbol/ClangASTContext.cpp<br>
>     lldb/trunk/source/Symbol/ClangASTImporter.cpp<br>
>     lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp<br>
>     lldb/trunk/source/Symbol/SymbolFile.cpp<br>
>     lldb/trunk/source/Symbol/SymbolVendor.cpp<br>
>     lldb/trunk/source/Symbol/Type.cpp<br>
><br>
> Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)<br>
> +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Dec  1 18:43:32 2015<br>
> @@ -1006,10 +1006,18 @@ public:<br>
>                                 lldb::AccessType access,<br>
>                                 bool is_artificial);<br>
><br>
> -    bool<br>
> +    static bool<br>
>      SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool has_extern);<br>
><br>
> -<br>
> +<br>
> +    static bool<br>
> +    CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer);<br>
> +<br>
> +    static bool<br>
> +    Import (const CompilerType &type, lldb_private::ClangASTImporter &importer);<br>
> +<br>
> +    static bool<br>
> +    GetHasExternalStorage (const CompilerType &type);<br>
>      //------------------------------------------------------------------<br>
>      // Tag Declarations<br>
>      //------------------------------------------------------------------<br>
> @@ -1092,13 +1100,19 @@ public:<br>
><br>
>      void<br>
>      DumpTypeDescription (lldb::opaque_compiler_type_t type, Stream *s) override;<br>
> -<br>
> +<br>
> +    static void<br>
> +    DumpTypeName (const CompilerType &type);<br>
> +<br>
>      static clang::EnumDecl *<br>
>      GetAsEnumDecl (const CompilerType& type);<br>
><br>
>      static clang::RecordDecl *<br>
>      GetAsRecordDecl (const CompilerType& type);<br>
> -<br>
> +<br>
> +    static clang::TagDecl *<br>
> +    GetAsTagDecl (const CompilerType& type);<br>
> +<br>
>      clang::CXXRecordDecl *<br>
>      GetAsCXXRecordDecl (lldb::opaque_compiler_type_t type);<br>
><br>
> @@ -1109,9 +1123,12 @@ public:<br>
>      GetQualType (const CompilerType& type)<br>
>      {<br>
>          // Make sure we have a clang type before making a clang::QualType<br>
> -        ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());<br>
> -        if (ast)<br>
> -            return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType());<br>
> +        if (type.GetOpaqueQualType())<br>
> +        {<br>
> +            ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());<br>
> +            if (ast)<br>
> +                return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType());<br>
> +        }<br>
>          return clang::QualType();<br>
>      }<br>
><br>
><br>
> Modified: lldb/trunk/include/lldb/Symbol/ClangASTImporter.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTImporter.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTImporter.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/include/lldb/Symbol/ClangASTImporter.h (original)<br>
> +++ lldb/trunk/include/lldb/Symbol/ClangASTImporter.h Tue Dec  1 18:43:32 2015<br>
> @@ -107,7 +107,11 @@ public:<br>
>      CopyType (clang::ASTContext *dst_ctx,<br>
>                clang::ASTContext *src_ctx,<br>
>                lldb::opaque_compiler_type_t type);<br>
> -<br>
> +<br>
> +    CompilerType<br>
> +    CopyType (ClangASTContext &dst,<br>
> +              const CompilerType &src_type);<br>
> +<br>
>      clang::Decl *<br>
>      CopyDecl (clang::ASTContext *dst_ctx,<br>
>                clang::ASTContext *src_ctx,<br>
> @@ -134,7 +138,10 @@ public:<br>
><br>
>      bool<br>
>      CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl);<br>
> -<br>
> +<br>
> +    bool<br>
> +    CompleteAndFetchChildren (clang::QualType type);<br>
> +<br>
>      bool<br>
>      RequireCompleteType (clang::QualType type);<br>
><br>
><br>
> Modified: lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h (original)<br>
> +++ lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h Tue Dec  1 18:43:32 2015<br>
> @@ -97,6 +97,11 @@ public:<br>
>      {<br>
>      }<br>
><br>
> +    void<br>
> +    FindExternalLexicalDecls(const clang::DeclContext *DC,<br>
> +                             llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,<br>
> +                             llvm::SmallVectorImpl<clang::Decl *> &Result) override;<br>
> +<br>
>      bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName decl_name) override;<br>
><br>
>      void CompleteType(clang::TagDecl *tag_decl) override;<br>
><br>
> Modified: lldb/trunk/include/lldb/Symbol/SymbolFile.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolFile.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolFile.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/include/lldb/Symbol/SymbolFile.h (original)<br>
> +++ lldb/trunk/include/lldb/Symbol/SymbolFile.h Tue Dec  1 18:43:32 2015<br>
> @@ -15,7 +15,6 @@<br>
>  #include "lldb/Symbol/CompilerType.h"<br>
>  #include "lldb/Symbol/CompilerDecl.h"<br>
>  #include "lldb/Symbol/CompilerDeclContext.h"<br>
> -<br>
>  #include "lldb/Symbol/Type.h"<br>
><br>
>  namespace lldb_private {<br>
> @@ -142,6 +141,8 @@ public:<br>
>      virtual uint32_t        FindFunctions (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list);<br>
>      virtual uint32_t        FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list);<br>
>      virtual uint32_t        FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types);<br>
> +    virtual size_t          FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types);<br>
> +<br>
>  //  virtual uint32_t        FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) = 0;<br>
>      virtual TypeList *      GetTypeList ();<br>
>      virtual size_t          GetTypes (lldb_private::SymbolContextScope *sc_scope,<br>
><br>
> Modified: lldb/trunk/include/lldb/Symbol/SymbolVendor.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolVendor.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolVendor.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/include/lldb/Symbol/SymbolVendor.h (original)<br>
> +++ lldb/trunk/include/lldb/Symbol/SymbolVendor.h Tue Dec  1 18:43:32 2015<br>
> @@ -128,6 +128,9 @@ public:<br>
>                 size_t max_matches,<br>
>                 TypeMap& types);<br>
><br>
> +    virtual size_t<br>
> +    FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types);<br>
> +<br>
>      virtual CompilerDeclContext<br>
>      FindNamespace (const SymbolContext& sc,<br>
>                     const ConstString &name,<br>
><br>
> Modified: lldb/trunk/include/lldb/Symbol/Type.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/include/lldb/Symbol/Type.h (original)<br>
> +++ lldb/trunk/include/lldb/Symbol/Type.h Tue Dec  1 18:43:32 2015<br>
> @@ -24,6 +24,31 @@<br>
><br>
>  namespace lldb_private {<br>
><br>
> +//----------------------------------------------------------------------<br>
> +// CompilerContext allows an array of these items to be passed to<br>
> +// perform detailed lookups in SymbolVendor and SymbolFile functions.<br>
> +//----------------------------------------------------------------------<br>
> +struct CompilerContext<br>
> +{<br>
> +    CompilerContext (CompilerContextKind t, const ConstString &n) :<br>
> +        type(t),<br>
> +        name(n)<br>
> +    {<br>
> +    }<br>
> +<br>
> +    bool<br>
> +    operator == (const CompilerContext &rhs) const<br>
> +    {<br>
> +        return type == rhs.type && name == <a href="http://rhs.name" rel="noreferrer" target="_blank">rhs.name</a>;<br>
> +    }<br>
> +<br>
> +    void<br>
> +    Dump () const;<br>
> +<br>
> +    CompilerContextKind type;<br>
> +    ConstString name;<br>
> +};<br>
> +<br>
>  class SymbolFileType :<br>
>      public std::enable_shared_from_this<SymbolFileType>,<br>
>      public UserID<br>
> @@ -35,6 +60,9 @@ class SymbolFileType :<br>
>          {<br>
>          }<br>
><br>
> +        SymbolFileType (SymbolFile &symbol_file, const lldb::TypeSP &type_sp);<br>
> +<br>
> +<br>
>          ~SymbolFileType ()<br>
>          {<br>
>          }<br>
><br>
> Modified: lldb/trunk/include/lldb/lldb-forward.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/include/lldb/lldb-forward.h (original)<br>
> +++ lldb/trunk/include/lldb/lldb-forward.h Tue Dec  1 18:43:32 2015<br>
> @@ -62,6 +62,7 @@ class   CommandObject;<br>
>  class   CommandReturnObject;<br>
>  class   Communication;<br>
>  class   CompactUnwindInfo;<br>
> +struct  CompilerContext;<br>
>  class   CompilerDecl;<br>
>  class   CompilerDeclContext;<br>
>  class   CompilerType;<br>
><br>
> Modified: lldb/trunk/include/lldb/lldb-private-enumerations.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-enumerations.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-enumerations.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/include/lldb/lldb-private-enumerations.h (original)<br>
> +++ lldb/trunk/include/lldb/lldb-private-enumerations.h Tue Dec  1 18:43:32 2015<br>
> @@ -241,6 +241,25 @@ enum class TypeValidatorResult : bool {<br>
>      Success = true,<br>
>      Failure = false<br>
>  };<br>
> +<br>
> +//----------------------------------------------------------------------<br>
> +// Enumerations that can be used to specify scopes types when looking up<br>
> +// types.<br>
> +//----------------------------------------------------------------------<br>
> +enum class CompilerContextKind<br>
> +{<br>
> +    Invalid = 0,<br>
> +    TranslationUnit,<br>
> +    Module,<br>
> +    Namespace,<br>
> +    Class,<br>
> +    Structure,<br>
> +    Union,<br>
> +    Function,<br>
> +    Variable,<br>
> +    Enumeration,<br>
> +    Typedef<br>
> +};<br>
><br>
>  } // namespace lldb_private<br>
><br>
><br>
> Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py (original)<br>
> +++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py Tue Dec  1 18:43:32 2015<br>
> @@ -14,11 +14,11 @@ class TestCppIncompleteTypes(TestBase):<br>
><br>
>          value_f = frame.EvaluateExpression("f")<br>
>          self.assertTrue(value_f.IsValid(), "'expr f' results in a valid SBValue object")<br>
> -        self.assertFalse(value_f.GetError().Success(), "'expr f' results in an error, but LLDB does not crash")<br>
> +        self.assertTrue(value_f.GetError().Success(), "'expr f' is successful")<br>
><br>
>          value_a = frame.EvaluateExpression("a")<br>
>          self.assertTrue(value_a.IsValid(), "'expr a' results in a valid SBValue object")<br>
> -        self.assertFalse(value_a.GetError().Success(), "'expr a' results in an error, but LLDB does not crash")<br>
> +        self.assertTrue(value_a.GetError().Success(), "'expr a' is successful")<br>
><br>
>      @skipIfGcc<br>
>      @skipIfWindows # Clang on Windows asserts in external record layout in this case.<br>
><br>
> Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h (original)<br>
> +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h Tue Dec  1 18:43:32 2015<br>
> @@ -33,6 +33,18 @@ public:<br>
>                              const DWARFDIE &die) = 0;<br>
><br>
>      virtual bool<br>
> +    CanCompleteType (const lldb_private::CompilerType &compiler_type)<br>
> +    {<br>
> +        return false;<br>
> +    }<br>
> +<br>
> +    virtual bool<br>
> +    CompleteType (const lldb_private::CompilerType &compiler_type)<br>
> +    {<br>
> +        return false;<br>
> +    }<br>
> +<br>
> +    virtual bool<br>
>      CompleteTypeFromDWARF (const DWARFDIE &die,<br>
>                             lldb_private::Type *type,<br>
>                             lldb_private::CompilerType &compiler_type) = 0;<br>
><br>
> Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original)<br>
> +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Tue Dec  1 18:43:32 2015<br>
> @@ -24,11 +24,14 @@<br>
>  #include "lldb/Core/StreamString.h"<br>
>  #include "lldb/Core/Value.h"<br>
>  #include "lldb/Host/Host.h"<br>
> +#include "lldb/Symbol/ClangASTImporter.h"<br>
>  #include "lldb/Symbol/ClangExternalASTSourceCommon.h"<br>
>  #include "lldb/Symbol/CompileUnit.h"<br>
>  #include "lldb/Symbol/Function.h"<br>
>  #include "lldb/Symbol/ObjectFile.h"<br>
> +#include "lldb/Symbol/SymbolVendor.h"<br>
>  #include "lldb/Symbol/TypeList.h"<br>
> +#include "lldb/Symbol/TypeMap.h"<br>
>  #include "lldb/Target/Language.h"<br>
>  #include "Plugins/Language/ObjC/ObjCLanguage.h"<br>
><br>
> @@ -114,6 +117,78 @@ struct BitfieldInfo<br>
>      }<br>
>  };<br>
><br>
> +<br>
> +ClangASTImporter &<br>
> +DWARFASTParserClang::GetClangASTImporter()<br>
> +{<br>
> +    if (!m_clang_ast_importer_ap)<br>
> +    {<br>
> +        m_clang_ast_importer_ap.reset (new ClangASTImporter);<br>
> +    }<br>
> +    return *m_clang_ast_importer_ap;<br>
> +}<br>
> +<br>
> +<br>
> +TypeSP<br>
> +DWARFASTParserClang::ParseTypeFromDWO (const DWARFDIE &die, Log *log)<br>
> +{<br>
> +    ModuleSP dwo_module_sp = die.GetContainingDWOModule();<br>
> +    if (dwo_module_sp)<br>
> +    {<br>
> +        // This type comes from an external DWO module<br>
> +        std::vector<CompilerContext> dwo_context;<br>
> +        die.GetDWOContext(dwo_context);<br>
> +        TypeMap dwo_types;<br>
> +        if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, dwo_types))<br>
> +        {<br>
> +            const size_t num_dwo_types = dwo_types.GetSize();<br>
> +            if (num_dwo_types == 1)<br>
> +            {<br>
> +                // We found a real definition for this type elsewhere<br>
> +                // so lets use it and cache the fact that we found<br>
> +                // a complete type for this die<br>
> +                TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0);<br>
> +                if (dwo_type_sp)<br>
> +                {<br>
> +                    lldb_private::CompilerType dwo_type = dwo_type_sp->GetForwardCompilerType();<br>
> +<br>
> +                    lldb_private::CompilerType type = GetClangASTImporter().CopyType (m_ast, dwo_type);<br>
> +<br>
> +                    //printf ("copied_qual_type: ast = %p, clang_type = %p, name = '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(), external_type->GetName().GetCString());<br>
> +                    if (type)<br>
> +                    {<br>
> +                        SymbolFileDWARF *dwarf = die.GetDWARF();<br>
> +                        TypeSP type_sp (new Type (die.GetID(),<br>
> +                                                  dwarf,<br>
> +                                                  dwo_type_sp->GetName(),<br>
> +                                                  dwo_type_sp->GetByteSize(),<br>
> +                                                  NULL,<br>
> +                                                  LLDB_INVALID_UID,<br>
> +                                                  Type::eEncodingInvalid,<br>
> +                                                  &dwo_type_sp->GetDeclaration(),<br>
> +                                                  type,<br>
> +                                                  Type::eResolveStateForward));<br>
> +<br>
> +                        dwarf->GetTypeList()->Insert(type_sp);<br>
> +                        dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();<br>
> +                        clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);<br>
> +                        if (tag_decl)<br>
> +                            LinkDeclContextToDIE(tag_decl, die);<br>
> +                        else<br>
> +                        {<br>
> +                            clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);<br>
> +                            if (defn_decl_ctx)<br>
> +                                LinkDeclContextToDIE(defn_decl_ctx, die);<br>
> +                        }<br>
> +                        return type_sp;<br>
> +                    }<br>
> +                }<br>
> +            }<br>
> +        }<br>
> +    }<br>
> +    return TypeSP();<br>
> +}<br>
> +<br>
>  TypeSP<br>
>  DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,<br>
>                                           const DWARFDIE &die,<br>
> @@ -487,15 +562,15 @@ DWARFASTParserClang::ParseTypeFromDWARF<br>
>                              if (dwarf->GetUniqueDWARFASTTypeMap().Find(type_name_const_str, die, decl,<br>
>                                                                         byte_size_valid ? byte_size : -1,<br>
>                                                                         *unique_ast_entry_ap))<br>
> -                        {<br>
> -                            type_sp = unique_ast_entry_ap->m_type_sp;<br>
> -                            if (type_sp)<br>
>                              {<br>
> -                            dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();<br>
> -                            return type_sp;<br>
> +                                type_sp = unique_ast_entry_ap->m_type_sp;<br>
> +                                if (type_sp)<br>
> +                                {<br>
> +                                    dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();<br>
> +                                    return type_sp;<br>
> +                                }<br>
>                              }<br>
>                          }<br>
> -                        }<br>
>                      }<br>
><br>
>                      DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);<br>
> @@ -600,6 +675,11 @@ DWARFASTParserClang::ParseTypeFromDWARF<br>
>                                                                               type_name_cstr);<br>
>                          }<br>
><br>
> +                        // See if the type comes from a DWO module and if so, track down that type.<br>
> +                        type_sp = ParseTypeFromDWO(die, log);<br>
> +                        if (type_sp)<br>
> +                            return type_sp;<br>
> +<br>
>                          DWARFDeclContext die_decl_ctx;<br>
>                          die.GetDWARFDeclContext(die_decl_ctx);<br>
><br>
> @@ -833,7 +913,7 @@ DWARFASTParserClang::ParseTypeFromDWARF<br>
>                                      case DW_AT_type:            encoding_form = form_value; break;<br>
>                                      case DW_AT_byte_size:       byte_size = form_value.Unsigned(); break;<br>
>                                      case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;<br>
> -                                    case DW_AT_declaration:     break; //is_forward_declaration = form_value.Boolean(); break;<br>
> +                                    case DW_AT_declaration:     is_forward_declaration = form_value.Boolean(); break;<br>
>                                      case DW_AT_allocated:<br>
>                                      case DW_AT_associated:<br>
>                                      case DW_AT_bit_stride:<br>
> @@ -850,6 +930,54 @@ DWARFASTParserClang::ParseTypeFromDWARF<br>
>                              }<br>
>                          }<br>
><br>
> +                        if (is_forward_declaration)<br>
> +                        {<br>
> +                            type_sp = ParseTypeFromDWO(die, log);<br>
> +                            if (type_sp)<br>
> +                                return type_sp;<br>
> +<br>
> +                            DWARFDeclContext die_decl_ctx;<br>
> +                            die.GetDWARFDeclContext(die_decl_ctx);<br>
> +<br>
> +                            type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);<br>
> +<br>
> +                            if (!type_sp)<br>
> +                            {<br>
> +                                SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();<br>
> +                                if (debug_map_symfile)<br>
> +                                {<br>
> +                                    // We weren't able to find a full declaration in<br>
> +                                    // this DWARF, see if we have a declaration anywhere<br>
> +                                    // else...<br>
> +                                    type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);<br>
> +                                }<br>
> +                            }<br>
> +<br>
> +                            if (type_sp)<br>
> +                            {<br>
> +                                if (log)<br>
> +                                {<br>
> +                                    dwarf->GetObjectFile()->GetModule()->LogMessage (log,<br>
> +                                                                                     "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64,<br>
> +                                                                                     static_cast<void*>(this),<br>
> +                                                                                     die.GetOffset(),<br>
> +                                                                                     DW_TAG_value_to_name(tag),<br>
> +                                                                                     type_name_cstr,<br>
> +                                                                                     type_sp->GetID());<br>
> +                                }<br>
> +<br>
> +                                // We found a real definition for this type elsewhere<br>
> +                                // so lets use it and cache the fact that we found<br>
> +                                // a complete type for this die<br>
> +                                dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();<br>
> +                                clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(<br>
> +                                                                                                    dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID())));<br>
> +                                if (defn_decl_ctx)<br>
> +                                    LinkDeclContextToDIE(defn_decl_ctx, die);<br>
> +                                return type_sp;<br>
> +                            }<br>
> +<br>
> +                        }<br>
>                          DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);<br>
><br>
>                          CompilerType enumerator_clang_type;<br>
> @@ -1130,7 +1258,7 @@ DWARFASTParserClang::ParseTypeFromDWARF<br>
>                                  if (class_type)<br>
>                                  {<br>
>                                      bool alternate_defn = false;<br>
> -                                    if (class_type->GetID() != decl_ctx_die.GetID())<br>
> +                                    if (class_type->GetID() != decl_ctx_die.GetID() || decl_ctx_die.GetContainingDWOModuleDIE())<br>
>                                      {<br>
>                                          alternate_defn = true;<br>
><br>
> @@ -1798,6 +1926,33 @@ DWARFASTParserClang::ParseTemplateParame<br>
>  }<br>
><br>
>  bool<br>
> +DWARFASTParserClang::CanCompleteType (const lldb_private::CompilerType &compiler_type)<br>
> +{<br>
> +    if (m_clang_ast_importer_ap)<br>
> +        return ClangASTContext::CanImport(compiler_type, GetClangASTImporter());<br>
> +    else<br>
> +        return false;<br>
> +}<br>
> +<br>
> +bool<br>
> +DWARFASTParserClang::CompleteType (const lldb_private::CompilerType &compiler_type)<br>
> +{<br>
> +    if (CanCompleteType(compiler_type))<br>
> +    {<br>
> +        if (ClangASTContext::Import(compiler_type, GetClangASTImporter()))<br>
> +        {<br>
> +            ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);<br>
> +            return true;<br>
> +        }<br>
> +        else<br>
> +        {<br>
> +            ClangASTContext::SetHasExternalStorage (compiler_type.GetOpaqueQualType(), false);<br>
> +        }<br>
> +    }<br>
> +    return false;<br>
> +}<br>
> +<br>
> +bool<br>
>  DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,<br>
>                                              lldb_private::Type *type,<br>
>                                              CompilerType &clang_type)<br>
> @@ -1868,25 +2023,17 @@ DWARFASTParserClang::CompleteTypeFromDWA<br>
>                      DWARFDIECollection member_function_dies;<br>
><br>
>                      DelayedPropertyList delayed_properties;<br>
> -                    if (!ParseChildMembers (sc,<br>
> -                                            die,<br>
> -                                            clang_type,<br>
> -                                            class_language,<br>
> -                                            base_classes,<br>
> -                                            member_accessibilities,<br>
> -                                            member_function_dies,<br>
> -                                            delayed_properties,<br>
> -                                            default_accessibility,<br>
> -                                            is_a_class,<br>
> -                                            layout_info))<br>
> -                    {<br>
> -                        auto module = dwarf->GetObjectFile()->GetModule();<br>
> -                        module->ReportError (":: Class %s has members with incomplete type.", die.GetName());<br>
> -                        if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)<br>
> -                            module->ReportError(":: Try compiling the source file with -fno-limit-debug-info.");<br>
> -<br>
> -                        return false;<br>
> -                    }<br>
> +                    ParseChildMembers (sc,<br>
> +                                       die,<br>
> +                                       clang_type,<br>
> +                                       class_language,<br>
> +                                       base_classes,<br>
> +                                       member_accessibilities,<br>
> +                                       member_function_dies,<br>
> +                                       delayed_properties,<br>
> +                                       default_accessibility,<br>
> +                                       is_a_class,<br>
> +                                       layout_info);<br>
><br>
>                      // Now parse any methods if there were any...<br>
>                      size_t num_functions = member_function_dies.Size();<br>
> @@ -1977,7 +2124,14 @@ DWARFASTParserClang::CompleteTypeFromDWA<br>
>                                      if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)<br>
>                                           module->ReportError (":: Try compiling the source file with -fno-limit-debug-info.");<br>
><br>
> -                                    return false;<br>
> +                                    // We have no choice other than to pretend that the base class<br>
> +                                    // is complete. If we don't do this, clang will crash when we<br>
> +                                    // call setBases() inside of "clang_type.SetBaseClassesForClassType()"<br>
> +                                    // below. Since we provide layout assistance, all ivars in this<br>
> +                                    // class and other classes will be fine, this is the best we can do<br>
> +                                    // short of crashing.<br>
> +                                    ClangASTContext::StartTagDeclarationDefinition (base_class_type);<br>
> +                                    ClangASTContext::CompleteTagDeclarationDefinition (base_class_type);<br>
>                                  }<br>
>                              }<br>
>                          }<br>
> @@ -2420,7 +2574,6 @@ DWARFASTParserClang::ParseChildMembers (<br>
>      if (!parent_die)<br>
>          return 0;<br>
><br>
> -    uint32_t incomplete_member_info_count = 0;<br>
>      uint32_t member_idx = 0;<br>
>      BitfieldInfo last_field_info;<br>
><br>
> @@ -2754,8 +2907,8 @@ DWARFASTParserClang::ParseChildMembers (<br>
>                                  }<br>
><br>
>                                  CompilerType member_clang_type = member_type->GetLayoutCompilerType ();<br>
> -                                if (!member_clang_type.IsCompleteType() && !member_clang_type.GetCompleteType())<br>
> -                                    incomplete_member_info_count += 1;<br>
> +                                if (!member_clang_type.IsCompleteType())<br>
> +                                    member_clang_type.GetCompleteType();<br>
><br>
>                                  {<br>
>                                      // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).<br>
> @@ -2789,6 +2942,30 @@ DWARFASTParserClang::ParseChildMembers (<br>
>                                      }<br>
>                                  }<br>
><br>
> +                                if (ClangASTContext::IsCXXClassType(member_clang_type) && member_clang_type.GetCompleteType() == false)<br>
> +                                {<br>
> +                                    if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)<br>
> +                                        module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nTry compiling the source file with -fno-limit-debug-info",<br>
> +                                                                parent_die.GetOffset(),<br>
> +                                                                parent_die.GetName(),<br>
> +                                                                die.GetOffset(),<br>
> +                                                                name);<br>
> +                                    else<br>
> +                                        module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s",<br>
> +                                                                parent_die.GetOffset(),<br>
> +                                                                parent_die.GetName(),<br>
> +                                                                die.GetOffset(),<br>
> +                                                                name,<br>
> +                                                                sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");<br>
> +                                    // We have no choice other than to pretend that the member class<br>
> +                                    // is complete. If we don't do this, clang will crash when trying<br>
> +                                    // to layout the class. Since we provide layout assistance, all<br>
> +                                    // ivars in this class and other classes will be fine, this is<br>
> +                                    // the best we can do short of crashing.<br>
> +                                    ClangASTContext::StartTagDeclarationDefinition(member_clang_type);<br>
> +                                    ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type);<br>
> +                                }<br>
> +<br>
>                                  field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type,<br>
>                                                                                      name,<br>
>                                                                                      member_clang_type,<br>
> @@ -2978,7 +3155,7 @@ DWARFASTParserClang::ParseChildMembers (<br>
>          }<br>
>      }<br>
><br>
> -    return incomplete_member_info_count == 0;<br>
> +    return true;<br>
>  }<br>
><br>
><br>
><br>
> Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h (original)<br>
> +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h Tue Dec  1 18:43:32 2015<br>
> @@ -47,6 +47,12 @@ public:<br>
>                              const DWARFDIE &die) override;<br>
><br>
>      bool<br>
> +    CanCompleteType (const lldb_private::CompilerType &compiler_type) override;<br>
> +<br>
> +    bool<br>
> +    CompleteType (const lldb_private::CompilerType &compiler_type) override;<br>
> +<br>
> +    bool<br>
>      CompleteTypeFromDWARF (const DWARFDIE &die,<br>
>                             lldb_private::Type *type,<br>
>                             lldb_private::CompilerType &compiler_type) override;<br>
> @@ -175,6 +181,19 @@ protected:<br>
>      void<br>
>      LinkDeclToDIE (clang::Decl *decl, const DWARFDIE &die);<br>
><br>
> +    lldb_private::ClangASTImporter &<br>
> +    GetClangASTImporter();<br>
> +<br>
> +    lldb::TypeSP<br>
> +    ParseTypeFromDWO (const DWARFDIE &die, lldb_private::Log *log);<br>
> +<br>
> +    //----------------------------------------------------------------------<br>
> +    // Return true if this type is a declaration to a type in an external<br>
> +    // module.<br>
> +    //----------------------------------------------------------------------<br>
> +    lldb::ModuleSP<br>
> +    GetModuleForType (const DWARFDIE &die);<br>
> +<br>
>      typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;<br>
>      typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap;<br>
>      //typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> DeclContextToDIEMap;<br>
> @@ -188,6 +207,7 @@ protected:<br>
>      DIEToDeclContextMap m_die_to_decl_ctx;<br>
>      DeclContextToDIEMap m_decl_ctx_to_die;<br>
>      RecordDeclToLayoutMap m_record_decl_to_layout_map;<br>
> +    std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap;<br>
>  };<br>
><br>
>  #endif // SymbolFileDWARF_DWARFASTParserClang_h_<br>
><br>
> Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp (original)<br>
> +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp Tue Dec  1 18:43:32 2015<br>
> @@ -22,8 +22,11 @@<br>
><br>
>  #include "lldb/Core/Module.h"<br>
>  #include "lldb/Symbol/ObjectFile.h"<br>
> +#include "lldb/Symbol/Type.h"<br>
>  #include "lldb/Symbol/TypeSystem.h"<br>
><br>
> +using namespace lldb_private;<br>
> +<br>
>  DIERef<br>
>  DWARFDIE::GetDIERef() const<br>
>  {<br>
> @@ -307,6 +310,51 @@ DWARFDIE::GetDWARFDeclContext (DWARFDecl<br>
>      }<br>
>  }<br>
><br>
> +void<br>
> +DWARFDIE::GetDWOContext (std::vector<CompilerContext> &context) const<br>
> +{<br>
> +    const dw_tag_t tag = Tag();<br>
> +    if (tag == DW_TAG_compile_unit)<br>
> +        return;<br>
> +    DWARFDIE parent = GetParent();<br>
> +    if (parent)<br>
> +        parent.GetDWOContext(context);<br>
> +    switch (tag)<br>
> +    {<br>
> +        case DW_TAG_module:<br>
> +            context.push_back(CompilerContext(CompilerContextKind::Module, ConstString(GetName())));<br>
> +            break;<br>
> +        case DW_TAG_namespace:<br>
> +            context.push_back(CompilerContext(CompilerContextKind::Namespace, ConstString(GetName())));<br>
> +            break;<br>
> +        case DW_TAG_structure_type:<br>
> +            context.push_back(CompilerContext(CompilerContextKind::Structure, ConstString(GetName())));<br>
> +            break;<br>
> +        case DW_TAG_union_type:<br>
> +            context.push_back(CompilerContext(CompilerContextKind::Union, ConstString(GetName())));<br>
> +            break;<br>
> +        case DW_TAG_class_type:<br>
> +            context.push_back(CompilerContext(CompilerContextKind::Class, ConstString(GetName())));<br>
> +            break;<br>
> +        case DW_TAG_enumeration_type:<br>
> +            context.push_back(CompilerContext(CompilerContextKind::Enumeration, ConstString(GetName())));<br>
> +            break;<br>
> +        case DW_TAG_subprogram:<br>
> +            context.push_back(CompilerContext(CompilerContextKind::Function, ConstString(GetPubname())));<br>
> +            break;<br>
> +        case DW_TAG_variable:<br>
> +            context.push_back(CompilerContext(CompilerContextKind::Variable, ConstString(GetPubname())));<br>
> +            break;<br>
> +        case DW_TAG_typedef:<br>
> +            context.push_back(CompilerContext(CompilerContextKind::Typedef, ConstString(GetName())));<br>
> +            break;<br>
> +        default:<br>
> +            assert(!"remove this prior to checkin");<br>
> +            break;<br>
> +    }<br>
> +}<br>
> +<br>
> +<br>
><br>
>  DWARFDIE<br>
>  DWARFDIE::GetParentDeclContextDIE () const<br>
> @@ -371,6 +419,45 @@ DWARFDIE::IsStructOrClass () const<br>
>      return tag == DW_TAG_class_type || tag == DW_TAG_structure_type;<br>
>  }<br>
><br>
> +<br>
> +DWARFDIE<br>
> +DWARFDIE::GetContainingDWOModuleDIE () const<br>
> +{<br>
> +    if (IsValid())<br>
> +    {<br>
> +        DWARFDIE top_module_die;<br>
> +        // Now make sure this DIE is scoped in a DW_TAG_module tag and return true if so<br>
> +        for (DWARFDIE parent = GetParent(); parent.IsValid(); parent = parent.GetParent())<br>
> +        {<br>
> +            const dw_tag_t tag = parent.Tag();<br>
> +            if (tag == DW_TAG_module)<br>
> +                top_module_die = parent;<br>
> +            else if (tag == DW_TAG_compile_unit)<br>
> +                break;<br>
> +        }<br>
> +<br>
> +        return top_module_die;<br>
> +    }<br>
> +    return DWARFDIE();<br>
> +}<br>
> +<br>
> +lldb::ModuleSP<br>
> +DWARFDIE::GetContainingDWOModule () const<br>
> +{<br>
> +    if (IsValid())<br>
> +    {<br>
> +        DWARFDIE dwo_module_die = GetContainingDWOModuleDIE();<br>
> +<br>
> +        if (dwo_module_die)<br>
> +        {<br>
> +            const char *module_name = dwo_module_die.GetName();<br>
> +            if (module_name)<br>
> +                return GetDWARF()->GetDWOModule (lldb_private::ConstString(module_name));<br>
> +        }<br>
> +    }<br>
> +    return lldb::ModuleSP();<br>
> +}<br>
> +<br>
>  bool<br>
>  DWARFDIE::HasChildren () const<br>
>  {<br>
><br>
> Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h (original)<br>
> +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h Tue Dec  1 18:43:32 2015<br>
> @@ -126,6 +126,12 @@ public:<br>
>          m_die = nullptr;<br>
>      }<br>
><br>
> +    lldb::ModuleSP<br>
> +    GetContainingDWOModule () const;<br>
> +<br>
> +    DWARFDIE<br>
> +    GetContainingDWOModuleDIE () const;<br>
> +<br>
>      //----------------------------------------------------------------------<br>
>      // Accessing information about a DIE<br>
>      //----------------------------------------------------------------------<br>
> @@ -217,6 +223,9 @@ public:<br>
>      void<br>
>      GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const;<br>
><br>
> +    void<br>
> +    GetDWOContext (std::vector<lldb_private::CompilerContext> &context) const;<br>
> +<br>
>      //----------------------------------------------------------------------<br>
>      // Getting attribute values from the DIE.<br>
>      //<br>
><br>
> Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=254476&r1=254475&r2=254476&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=254476&r1=254475&r2=254476&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)<br>
> +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Dec  1 18:43:32 2015<br>
> @@ -1077,9 +1077,9 @@ SymbolFileDWARF::ParseImportedModules (c<br>
>          if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))<br>
>          {<br>
>              UpdateExternalModuleListIfNeeded();<br>
> -            for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules)<br>
> +            for (const auto &pair : m_external_type_modules)<br>
>              {<br>
> -                imported_modules.push_back(external_type_module.second.m_name);<br>
> +                imported_modules.push_back(pair.first);<br>
>              }<br>
>          }<br>
>      }<br>
> @@ -1515,13 +1515,32 @@ bool<br>
>  SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)<br>
>  {<br>
>      CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);<br>
> -    return GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType());<br>
> +    if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()))<br>
> +    {<br>
> +        return true;<br>
> +    }<br>
> +    TypeSystem *type_system = compiler_type.GetTypeSystem();<br>
> +    if (type_system)<br>
> +    {<br>
> +        DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();<br>
> +        if (dwarf_ast)<br>
> +            return dwarf_ast->CanCompleteType(compiler_type);<br>
> +    }<br>
> +    return false;<br>
>  }<br>
><br>
><br>
>  bool<br>
>  SymbolFileDWARF::CompleteType (CompilerType &compiler_type)<br>
>  {<br>
> +    TypeSystem *type_system = compiler_type.GetTypeSystem();<br>
> +    if (type_system)<br>
> +    {<br>
> +        DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();<br>
> +        if (dwarf_ast && dwarf_ast->CanCompleteType(compiler_type))<br>
> +            return dwarf_ast->CompleteType(compiler_type);<br>
> +    }<br>
> +<br>
>      // We have a struct/union/class/enum that needs to be fully resolved.<br>
>      CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);<br>
>      auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());<br>
> @@ -1641,6 +1660,17 @@ SymbolFileDWARF::GetFunction (const DWAR<br>
>      return false;<br>
>  }<br>
><br>
> +lldb::ModuleSP<br>
> +SymbolFileDWARF::GetDWOModule (ConstString name)<br>
> +{<br>
> +    UpdateExternalModuleListIfNeeded();<br>
> +    const auto &pos = m_external_type_modules.find(name);<br>
> +    if (pos != m_external_type_modules.end())<br>
> +        return pos->second;<br>
> +    else<br>
> +        return lldb::ModuleSP();<br>
> +}<br>
> +<br>
>  void<br>
>  SymbolFileDWARF::UpdateExternalModuleListIfNeeded()<br>
>  {<br>
> @@ -1658,37 +1688,24 @@ SymbolFileDWARF::UpdateExternalModuleLis<br>
>          const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();<br>
>          if (die && die.HasChildren() == false)<br>
>          {<br>
> -            const uint64_t name_strp = die.GetAttributeValueAsUnsigned (DW_AT_name, UINT64_MAX);<br>
> -            const uint64_t dwo_path_strp = die.GetAttributeValueAsUnsigned (DW_AT_GNU_dwo_name, UINT64_MAX);<br>
> -<br>
> -            if (name_strp != UINT64_MAX)<br>
> +            const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);<br>
> +<br>
> +            if (name)<br>
>              {<br>
> -                if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end())<br>
> +                ConstString const_name(name);<br>
> +                if (m_external_type_modules.find(const_name) == m_external_type_modules.end())<br>
>                  {<br>
> -                    const char *name = get_debug_str_data().PeekCStr(name_strp);<br>
> -                    const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp);<br>
> -                    if (name || dwo_path)<br>
> +                    ModuleSP module_sp;<br>
> +                    const char *dwo_path = die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);<br>
> +                    if (dwo_path)<br>
>                      {<br>
> -                        ModuleSP module_sp;<br>
> -                        if (dwo_path)<br>
> -                        {<br>
> -                            ModuleSpec dwo_module_spec;<br>
> -                            dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);<br>
> -                            dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();<br>
> -                            //printf ("Loading dwo = '%s'\n", dwo_path);<br>
> -                            Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);<br>
> -                        }<br>
> -<br>
> -                        if (dwo_path_strp != LLDB_INVALID_UID)<br>
> -                        {<br>
> -                            m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp };<br>
> -                        }<br>
> -                        else<br>
> -                        {<br>
> -                            // This hack should be removed promptly once clang emits both.<br>
> -                            m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp };<br>
> -                        }<br>
> +                        ModuleSpec dwo_module_spec;<br>
> +                        dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);<br>
> +                        dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();<br>
> +                        //printf ("Loading dwo = '%s'\n", dwo_path);<br>
> +                        Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);<br>
>                      }<br>
> +                    m_external_type_modules[const_name] = module_sp;<br>
>                  }<br>
>              }<br>
>          }<br>
> @@ -2970,6 +2987,104 @@ SymbolFileDWARF::FindTypes (const Symbol<br>
>          }<br>
>          return num_matches;<br>
>      }<br>
> +    else<br>
> +    {<br>
> +        UpdateExternalModuleListIfNeeded();<br>
> +<br>
> +        for (const auto &pair : m_external_type_modules)<br>
> +        {<br>
> +            ModuleSP external_module_sp = pair.second;<br>
> +            if (external_module_sp)<br>
> +            {<br>
> +                SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor();<br>
> +                if (sym_vendor)<br>
> +                {<br>
> +                    const uint32_t num_external_matches = sym_vendor->FindTypes (sc,<br>
> +                                                                                 name,<br>
> +                                                                                 parent_decl_ctx,<br>
> +                                                                                 append,<br>
> +                                                                                 max_matches,<br>
> +                                                                                 types);<br>
> +                    if (num_external_matches)<br>
> +                        return num_external_matches;<br>
> +                }<br>
> +            }<br>
> +        }<br>
> +    }<br>
> +<br>
> +    return 0;<br>
> +}<br>
> +<br>
> +<br>
> +size_t<br>
> +SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,<br>
> +                            bool append,<br>
> +                            TypeMap& types)<br>
> +{<br>
> +    if (!append)<br>
> +        types.Clear();<br>
> +<br>
> +    if (context.empty())<br>
> +        return 0;<br>
> +<br>
> +    DIEArray die_offsets;<br>
> +<br>
> +    ConstString name = context.back().name;<br>
> +<br>
> +    if (m_using_apple_tables)<br>
> +    {<br>
> +        if (m_apple_types_ap.get())<br>
> +        {<br>
> +            const char *name_cstr = name.GetCString();<br>
> +            m_apple_types_ap->FindByName (name_cstr, die_offsets);<br>
> +        }<br>
> +    }<br>
> +    else<br>
> +    {<br>
> +        if (!m_indexed)<br>
> +            Index ();<br>
> +<br>
> +        m_type_index.Find (name, die_offsets);<br>
> +    }<br>
> +<br>
> +    const size_t num_die_matches = die_offsets.size();<br>
> +<br>
> +    if (num_die_matches)<br>
> +    {<br>
> +        size_t num_matches = 0;<br>
> +        DWARFDebugInfo* debug_info = DebugInfo();<br>
> +        for (size_t i=0; i<num_die_matches; ++i)<br>
> +        {<br>
> +            const DIERef& die_ref = die_offsets[i];<br>
> +            DWARFDIE die = debug_info->GetDIE (die_ref);<br>
> +<br>
> +            if (die)<br>
> +            {<br>
> +              </blockquote></div></div></div>