[Lldb-commits] [lldb] r254980 - Trying to submit 254476 one more time. This implement -gmodule debugging support.

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Mon Dec 7 17:02:10 PST 2015


Author: gclayton
Date: Mon Dec  7 19:02:08 2015
New Revision: 254980

URL: http://llvm.org/viewvc/llvm-project?rev=254980&view=rev
Log:
Trying to submit 254476 one more time. This implement -gmodule debugging support.

It was previously reverted due to issues that showed up only on linux. I was able to reproduce these issues and fix the underlying cause.

So this is the same patch as 254476 with the following two fixes:
- Fix not trying to complete classes that don't have external sources
- Fix ClangASTSource::CompleteType() to check the decl context of types that it finds by basename to ensure we don't complete a type "S" with a type like "std::S". Before this fix ClangASTSource::CompleteType() would accept _any_ type that had a matching basename and copy it into the other type.

<rdar://problem/22992457>


Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/include/lldb/Symbol/ClangASTImporter.h
    lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h
    lldb/trunk/include/lldb/Symbol/SymbolFile.h
    lldb/trunk/include/lldb/Symbol/SymbolVendor.h
    lldb/trunk/include/lldb/Symbol/Type.h
    lldb/trunk/include/lldb/lldb-forward.h
    lldb/trunk/include/lldb/lldb-private-enumerations.h
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Symbol/ClangASTImporter.cpp
    lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp
    lldb/trunk/source/Symbol/SymbolFile.cpp
    lldb/trunk/source/Symbol/SymbolVendor.cpp
    lldb/trunk/source/Symbol/Type.cpp

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Mon Dec  7 19:02:08 2015
@@ -151,7 +151,16 @@ public:
     {
         return ClangASTContext::GetCompleteDecl(getASTContext(), decl);
     }
-    
+
+    static void
+    DumpDeclHiearchy (clang::Decl *decl);
+
+    static void
+    DumpDeclContextHiearchy (clang::DeclContext *decl_ctx);
+
+    static bool
+    DeclsAreEquivalent (clang::Decl *lhs_decl, clang::Decl *rhs_decl);
+
     static bool
     GetCompleteDecl (clang::ASTContext *ast,
                      clang::Decl *decl);
@@ -1006,10 +1015,18 @@ public:
                                lldb::AccessType access,
                                bool is_artificial);
     
-    bool
+    static bool
     SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool has_extern);
     
-    
+
+    static bool
+    CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer);
+
+    static bool
+    Import (const CompilerType &type, lldb_private::ClangASTImporter &importer);
+
+    static bool
+    GetHasExternalStorage (const CompilerType &type);
     //------------------------------------------------------------------
     // Tag Declarations
     //------------------------------------------------------------------
@@ -1092,13 +1109,19 @@ public:
     
     void
     DumpTypeDescription (lldb::opaque_compiler_type_t type, Stream *s) override;
-    
+
+    static void
+    DumpTypeName (const CompilerType &type);
+
     static clang::EnumDecl *
     GetAsEnumDecl (const CompilerType& type);
     
     static clang::RecordDecl *
     GetAsRecordDecl (const CompilerType& type);
-    
+
+    static clang::TagDecl *
+    GetAsTagDecl (const CompilerType& type);
+
     clang::CXXRecordDecl *
     GetAsCXXRecordDecl (lldb::opaque_compiler_type_t type);
     
@@ -1109,9 +1132,12 @@ public:
     GetQualType (const CompilerType& type)
     {
         // Make sure we have a clang type before making a clang::QualType
-        ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
-        if (ast)
-            return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType());
+        if (type.GetOpaqueQualType())
+        {
+            ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem());
+            if (ast)
+                return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType());
+        }
         return clang::QualType();
     }
 

Modified: lldb/trunk/include/lldb/Symbol/ClangASTImporter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTImporter.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTImporter.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTImporter.h Mon Dec  7 19:02:08 2015
@@ -107,7 +107,11 @@ public:
     CopyType (clang::ASTContext *dst_ctx,
               clang::ASTContext *src_ctx,
               lldb::opaque_compiler_type_t type);
-    
+
+    CompilerType
+    CopyType (ClangASTContext &dst,
+              const CompilerType &src_type);
+
     clang::Decl *
     CopyDecl (clang::ASTContext *dst_ctx,
               clang::ASTContext *src_ctx,
@@ -134,7 +138,10 @@ public:
     
     bool
     CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl);
-    
+
+    bool
+    CompleteAndFetchChildren (clang::QualType type);
+
     bool
     RequireCompleteType (clang::QualType type);
     

Modified: lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h Mon Dec  7 19:02:08 2015
@@ -97,6 +97,11 @@ public:
     {
     }
 
+    void
+    FindExternalLexicalDecls(const clang::DeclContext *DC,
+                             llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+                             llvm::SmallVectorImpl<clang::Decl *> &Result) override;
+
     bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName decl_name) override;
 
     void CompleteType(clang::TagDecl *tag_decl) override;

Modified: lldb/trunk/include/lldb/Symbol/SymbolFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolFile.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/SymbolFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/SymbolFile.h Mon Dec  7 19:02:08 2015
@@ -15,7 +15,6 @@
 #include "lldb/Symbol/CompilerType.h"
 #include "lldb/Symbol/CompilerDecl.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
-
 #include "lldb/Symbol/Type.h"
 
 namespace lldb_private {
@@ -142,6 +141,8 @@ public:
     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);
     virtual uint32_t        FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list);
     virtual uint32_t        FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types);
+    virtual size_t          FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types);
+
 //  virtual uint32_t        FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) = 0;
     virtual TypeList *      GetTypeList ();
     virtual size_t          GetTypes (lldb_private::SymbolContextScope *sc_scope,

Modified: lldb/trunk/include/lldb/Symbol/SymbolVendor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolVendor.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/SymbolVendor.h (original)
+++ lldb/trunk/include/lldb/Symbol/SymbolVendor.h Mon Dec  7 19:02:08 2015
@@ -128,6 +128,9 @@ public:
                size_t max_matches,
                TypeMap& types);
 
+    virtual size_t
+    FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types);
+
     virtual CompilerDeclContext
     FindNamespace (const SymbolContext& sc, 
                    const ConstString &name,

Modified: lldb/trunk/include/lldb/Symbol/Type.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Type.h (original)
+++ lldb/trunk/include/lldb/Symbol/Type.h Mon Dec  7 19:02:08 2015
@@ -24,6 +24,31 @@
 
 namespace lldb_private {
 
+//----------------------------------------------------------------------
+// CompilerContext allows an array of these items to be passed to
+// perform detailed lookups in SymbolVendor and SymbolFile functions.
+//----------------------------------------------------------------------
+struct CompilerContext
+{
+    CompilerContext (CompilerContextKind t, const ConstString &n) :
+        type(t),
+        name(n)
+    {
+    }
+
+    bool
+    operator == (const CompilerContext &rhs) const
+    {
+        return type == rhs.type && name == rhs.name;
+    }
+
+    void
+    Dump () const;
+
+    CompilerContextKind type;
+    ConstString name;
+};
+
 class SymbolFileType :
     public std::enable_shared_from_this<SymbolFileType>,
     public UserID
@@ -35,6 +60,9 @@ class SymbolFileType :
         {
         }
 
+        SymbolFileType (SymbolFile &symbol_file, const lldb::TypeSP &type_sp);
+
+
         ~SymbolFileType ()
         {
         }

Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Mon Dec  7 19:02:08 2015
@@ -62,6 +62,7 @@ class   CommandObject;
 class   CommandReturnObject;
 class   Communication;
 class   CompactUnwindInfo;
+struct  CompilerContext;
 class   CompilerDecl;
 class   CompilerDeclContext;
 class   CompilerType;

Modified: lldb/trunk/include/lldb/lldb-private-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-enumerations.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-private-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-private-enumerations.h Mon Dec  7 19:02:08 2015
@@ -241,6 +241,25 @@ enum class TypeValidatorResult : bool {
     Success = true,
     Failure = false
 };
+
+//----------------------------------------------------------------------
+// Enumerations that can be used to specify scopes types when looking up
+// types.
+//----------------------------------------------------------------------
+enum class CompilerContextKind
+{
+    Invalid = 0,
+    TranslationUnit,
+    Module,
+    Namespace,
+    Class,
+    Structure,
+    Union,
+    Function,
+    Variable,
+    Enumeration,
+    Typedef
+};
     
 } // namespace lldb_private
 

Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py Mon Dec  7 19:02:08 2015
@@ -14,11 +14,11 @@ class TestCppIncompleteTypes(TestBase):
 
         value_f = frame.EvaluateExpression("f")
         self.assertTrue(value_f.IsValid(), "'expr f' results in a valid SBValue object")
-        self.assertFalse(value_f.GetError().Success(), "'expr f' results in an error, but LLDB does not crash")
+        self.assertTrue(value_f.GetError().Success(), "'expr f' is successful")
 
         value_a = frame.EvaluateExpression("a")
         self.assertTrue(value_a.IsValid(), "'expr a' results in a valid SBValue object")
-        self.assertFalse(value_a.GetError().Success(), "'expr a' results in an error, but LLDB does not crash")
+        self.assertTrue(value_a.GetError().Success(), "'expr a' is successful")
 
     @skipIfGcc
     @skipIfWindows # Clang on Windows asserts in external record layout in this case.

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp Mon Dec  7 19:02:08 2015
@@ -322,6 +322,11 @@ ClangASTSource::CompleteType (TagDecl *t
 
                 TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
 
+                // We have found a type by basename and we need to make sure the decl contexts
+                // are the same before we can try to complete this type with another
+                if (!ClangASTContext::DeclsAreEquivalent (tag_decl, candidate_tag_decl))
+                    continue;
+
                 if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
                     found = true;
             }

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h Mon Dec  7 19:02:08 2015
@@ -33,6 +33,18 @@ public:
                             const DWARFDIE &die) = 0;
 
     virtual bool
+    CanCompleteType (const lldb_private::CompilerType &compiler_type)
+    {
+        return false;
+    }
+
+    virtual bool
+    CompleteType (const lldb_private::CompilerType &compiler_type)
+    {
+        return false;
+    }
+
+    virtual bool
     CompleteTypeFromDWARF (const DWARFDIE &die,
                            lldb_private::Type *type,
                            lldb_private::CompilerType &compiler_type) = 0;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Mon Dec  7 19:02:08 2015
@@ -24,11 +24,14 @@
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Value.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Symbol/ClangASTImporter.h"
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/TypeList.h"
+#include "lldb/Symbol/TypeMap.h"
 #include "lldb/Target/Language.h"
 #include "Plugins/Language/ObjC/ObjCLanguage.h"
 
@@ -114,6 +117,78 @@ struct BitfieldInfo
     }
 };
 
+
+ClangASTImporter &
+DWARFASTParserClang::GetClangASTImporter()
+{
+    if (!m_clang_ast_importer_ap)
+    {
+        m_clang_ast_importer_ap.reset (new ClangASTImporter);
+    }
+    return *m_clang_ast_importer_ap;
+}
+
+
+TypeSP
+DWARFASTParserClang::ParseTypeFromDWO (const DWARFDIE &die, Log *log)
+{
+    ModuleSP dwo_module_sp = die.GetContainingDWOModule();
+    if (dwo_module_sp)
+    {
+        // This type comes from an external DWO module
+        std::vector<CompilerContext> dwo_context;
+        die.GetDWOContext(dwo_context);
+        TypeMap dwo_types;
+        if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, dwo_types))
+        {
+            const size_t num_dwo_types = dwo_types.GetSize();
+            if (num_dwo_types == 1)
+            {
+                // We found a real definition for this type elsewhere
+                // so lets use it and cache the fact that we found
+                // a complete type for this die
+                TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0);
+                if (dwo_type_sp)
+                {
+                    lldb_private::CompilerType dwo_type = dwo_type_sp->GetForwardCompilerType();
+
+                    lldb_private::CompilerType type = GetClangASTImporter().CopyType (m_ast, dwo_type);
+
+                    //printf ("copied_qual_type: ast = %p, clang_type = %p, name = '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(), external_type->GetName().GetCString());
+                    if (type)
+                    {
+                        SymbolFileDWARF *dwarf = die.GetDWARF();
+                        TypeSP type_sp (new Type (die.GetID(),
+                                                  dwarf,
+                                                  dwo_type_sp->GetName(),
+                                                  dwo_type_sp->GetByteSize(),
+                                                  NULL,
+                                                  LLDB_INVALID_UID,
+                                                  Type::eEncodingInvalid,
+                                                  &dwo_type_sp->GetDeclaration(),
+                                                  type,
+                                                  Type::eResolveStateForward));
+
+                        dwarf->GetTypeList()->Insert(type_sp);
+                        dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+                        clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
+                        if (tag_decl)
+                            LinkDeclContextToDIE(tag_decl, die);
+                        else
+                        {
+                            clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
+                            if (defn_decl_ctx)
+                                LinkDeclContextToDIE(defn_decl_ctx, die);
+                        }
+                        return type_sp;
+                    }
+                }
+            }
+        }
+    }
+    return TypeSP();
+}
+
 TypeSP
 DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
                                          const DWARFDIE &die,
@@ -487,15 +562,15 @@ DWARFASTParserClang::ParseTypeFromDWARF
                             if (dwarf->GetUniqueDWARFASTTypeMap().Find(type_name_const_str, die, decl,
                                                                        byte_size_valid ? byte_size : -1,
                                                                        *unique_ast_entry_ap))
-                        {
-                            type_sp = unique_ast_entry_ap->m_type_sp;
-                            if (type_sp)
                             {
-                            dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
-                            return type_sp;
+                                type_sp = unique_ast_entry_ap->m_type_sp;
+                                if (type_sp)
+                                {
+                                    dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+                                    return type_sp;
+                                }
                             }
                         }
-                        }
                     }
 
                     DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
@@ -600,6 +675,11 @@ DWARFASTParserClang::ParseTypeFromDWARF
                                                                              type_name_cstr);
                         }
 
+                        // See if the type comes from a DWO module and if so, track down that type.
+                        type_sp = ParseTypeFromDWO(die, log);
+                        if (type_sp)
+                            return type_sp;
+
                         DWARFDeclContext die_decl_ctx;
                         die.GetDWARFDeclContext(die_decl_ctx);
 
@@ -833,7 +913,7 @@ DWARFASTParserClang::ParseTypeFromDWARF
                                     case DW_AT_type:            encoding_form = form_value; break;
                                     case DW_AT_byte_size:       byte_size = form_value.Unsigned(); break;
                                     case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
-                                    case DW_AT_declaration:     break; //is_forward_declaration = form_value.Boolean(); break;
+                                    case DW_AT_declaration:     is_forward_declaration = form_value.Boolean(); break;
                                     case DW_AT_allocated:
                                     case DW_AT_associated:
                                     case DW_AT_bit_stride:
@@ -850,6 +930,54 @@ DWARFASTParserClang::ParseTypeFromDWARF
                             }
                         }
 
+                        if (is_forward_declaration)
+                        {
+                            type_sp = ParseTypeFromDWO(die, log);
+                            if (type_sp)
+                                return type_sp;
+
+                            DWARFDeclContext die_decl_ctx;
+                            die.GetDWARFDeclContext(die_decl_ctx);
+
+                            type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
+
+                            if (!type_sp)
+                            {
+                                SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
+                                if (debug_map_symfile)
+                                {
+                                    // We weren't able to find a full declaration in
+                                    // this DWARF, see if we have a declaration anywhere
+                                    // else...
+                                    type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
+                                }
+                            }
+
+                            if (type_sp)
+                            {
+                                if (log)
+                                {
+                                    dwarf->GetObjectFile()->GetModule()->LogMessage (log,
+                                                                                     "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64,
+                                                                                     static_cast<void*>(this),
+                                                                                     die.GetOffset(),
+                                                                                     DW_TAG_value_to_name(tag),
+                                                                                     type_name_cstr,
+                                                                                     type_sp->GetID());
+                                }
+
+                                // We found a real definition for this type elsewhere
+                                // so lets use it and cache the fact that we found
+                                // a complete type for this die
+                                dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+                                clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
+                                                                                                    dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID())));
+                                if (defn_decl_ctx)
+                                    LinkDeclContextToDIE(defn_decl_ctx, die);
+                                return type_sp;
+                            }
+
+                        }
                         DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
 
                         CompilerType enumerator_clang_type;
@@ -1130,7 +1258,7 @@ DWARFASTParserClang::ParseTypeFromDWARF
                                 if (class_type)
                                 {
                                     bool alternate_defn = false;
-                                    if (class_type->GetID() != decl_ctx_die.GetID())
+                                    if (class_type->GetID() != decl_ctx_die.GetID() || decl_ctx_die.GetContainingDWOModuleDIE())
                                     {
                                         alternate_defn = true;
 
@@ -1798,6 +1926,33 @@ DWARFASTParserClang::ParseTemplateParame
 }
 
 bool
+DWARFASTParserClang::CanCompleteType (const lldb_private::CompilerType &compiler_type)
+{
+    if (m_clang_ast_importer_ap)
+        return ClangASTContext::CanImport(compiler_type, GetClangASTImporter());
+    else
+        return false;
+}
+
+bool
+DWARFASTParserClang::CompleteType (const lldb_private::CompilerType &compiler_type)
+{
+    if (CanCompleteType(compiler_type))
+    {
+        if (ClangASTContext::Import(compiler_type, GetClangASTImporter()))
+        {
+            ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+            return true;
+        }
+        else
+        {
+            ClangASTContext::SetHasExternalStorage (compiler_type.GetOpaqueQualType(), false);
+        }
+    }
+    return false;
+}
+
+bool
 DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
                                             lldb_private::Type *type,
                                             CompilerType &clang_type)
@@ -1868,25 +2023,17 @@ DWARFASTParserClang::CompleteTypeFromDWA
                     DWARFDIECollection member_function_dies;
 
                     DelayedPropertyList delayed_properties;
-                    if (!ParseChildMembers (sc,
-                                            die,
-                                            clang_type,
-                                            class_language,
-                                            base_classes,
-                                            member_accessibilities,
-                                            member_function_dies,
-                                            delayed_properties,
-                                            default_accessibility,
-                                            is_a_class,
-                                            layout_info))
-                    {
-                        auto module = dwarf->GetObjectFile()->GetModule();
-                        module->ReportError (":: Class %s has members with incomplete type.", die.GetName());
-                        if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
-                            module->ReportError(":: Try compiling the source file with -fno-limit-debug-info.");
-
-                        return false;
-                    }
+                    ParseChildMembers (sc,
+                                       die,
+                                       clang_type,
+                                       class_language,
+                                       base_classes,
+                                       member_accessibilities,
+                                       member_function_dies,
+                                       delayed_properties,
+                                       default_accessibility,
+                                       is_a_class,
+                                       layout_info);
 
                     // Now parse any methods if there were any...
                     size_t num_functions = member_function_dies.Size();
@@ -1977,7 +2124,14 @@ DWARFASTParserClang::CompleteTypeFromDWA
                                     if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
                                          module->ReportError (":: Try compiling the source file with -fno-limit-debug-info.");
 
-                                    return false;
+                                    // We have no choice other than to pretend that the base class
+                                    // is complete. If we don't do this, clang will crash when we
+                                    // call setBases() inside of "clang_type.SetBaseClassesForClassType()"
+                                    // below. Since we provide layout assistance, all ivars in this
+                                    // class and other classes will be fine, this is the best we can do
+                                    // short of crashing.
+                                    ClangASTContext::StartTagDeclarationDefinition (base_class_type);
+                                    ClangASTContext::CompleteTagDeclarationDefinition (base_class_type);
                                 }
                             }
                         }
@@ -2420,7 +2574,6 @@ DWARFASTParserClang::ParseChildMembers (
     if (!parent_die)
         return 0;
 
-    uint32_t incomplete_member_info_count = 0;
     uint32_t member_idx = 0;
     BitfieldInfo last_field_info;
 
@@ -2754,8 +2907,8 @@ DWARFASTParserClang::ParseChildMembers (
                                 }
 
                                 CompilerType member_clang_type = member_type->GetLayoutCompilerType ();
-                                if (!member_clang_type.IsCompleteType() && !member_clang_type.GetCompleteType())
-                                    incomplete_member_info_count += 1;
+                                if (!member_clang_type.IsCompleteType())
+                                    member_clang_type.GetCompleteType();
 
                                 {
                                     // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
@@ -2789,6 +2942,30 @@ DWARFASTParserClang::ParseChildMembers (
                                     }
                                 }
 
+                                if (ClangASTContext::IsCXXClassType(member_clang_type) && member_clang_type.GetCompleteType() == false)
+                                {
+                                    if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
+                                        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",
+                                                                parent_die.GetOffset(),
+                                                                parent_die.GetName(),
+                                                                die.GetOffset(),
+                                                                name);
+                                    else
+                                        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",
+                                                                parent_die.GetOffset(),
+                                                                parent_die.GetName(),
+                                                                die.GetOffset(),
+                                                                name,
+                                                                sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
+                                    // We have no choice other than to pretend that the member class
+                                    // is complete. If we don't do this, clang will crash when trying
+                                    // to layout the class. Since we provide layout assistance, all
+                                    // ivars in this class and other classes will be fine, this is
+                                    // the best we can do short of crashing.
+                                    ClangASTContext::StartTagDeclarationDefinition(member_clang_type);
+                                    ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type);
+                                }
+
                                 field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type,
                                                                                     name,
                                                                                     member_clang_type,
@@ -2978,7 +3155,7 @@ DWARFASTParserClang::ParseChildMembers (
         }
     }
 
-    return incomplete_member_info_count == 0;
+    return true;
 }
 
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h Mon Dec  7 19:02:08 2015
@@ -47,6 +47,12 @@ public:
                             const DWARFDIE &die) override;
 
     bool
+    CanCompleteType (const lldb_private::CompilerType &compiler_type) override;
+
+    bool
+    CompleteType (const lldb_private::CompilerType &compiler_type) override;
+
+    bool
     CompleteTypeFromDWARF (const DWARFDIE &die,
                            lldb_private::Type *type,
                            lldb_private::CompilerType &compiler_type) override;
@@ -175,6 +181,19 @@ protected:
     void
     LinkDeclToDIE (clang::Decl *decl, const DWARFDIE &die);
 
+    lldb_private::ClangASTImporter &
+    GetClangASTImporter();
+
+    lldb::TypeSP
+    ParseTypeFromDWO (const DWARFDIE &die, lldb_private::Log *log);
+
+    //----------------------------------------------------------------------
+    // Return true if this type is a declaration to a type in an external
+    // module.
+    //----------------------------------------------------------------------
+    lldb::ModuleSP
+    GetModuleForType (const DWARFDIE &die);
+
     typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
     typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap;
     //typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> DeclContextToDIEMap;
@@ -188,6 +207,7 @@ protected:
     DIEToDeclContextMap m_die_to_decl_ctx;
     DeclContextToDIEMap m_decl_ctx_to_die;
     RecordDeclToLayoutMap m_record_decl_to_layout_map;
+    std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap;
 };
 
 #endif // SymbolFileDWARF_DWARFASTParserClang_h_

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp Mon Dec  7 19:02:08 2015
@@ -22,8 +22,11 @@
 
 #include "lldb/Core/Module.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Type.h"
 #include "lldb/Symbol/TypeSystem.h"
 
+using namespace lldb_private;
+
 DIERef
 DWARFDIE::GetDIERef() const
 {
@@ -307,6 +310,50 @@ DWARFDIE::GetDWARFDeclContext (DWARFDecl
     }
 }
 
+void
+DWARFDIE::GetDWOContext (std::vector<CompilerContext> &context) const
+{
+    const dw_tag_t tag = Tag();
+    if (tag == DW_TAG_compile_unit)
+        return;
+    DWARFDIE parent = GetParent();
+    if (parent)
+        parent.GetDWOContext(context);
+    switch (tag)
+    {
+        case DW_TAG_module:
+            context.push_back(CompilerContext(CompilerContextKind::Module, ConstString(GetName())));
+            break;
+        case DW_TAG_namespace:
+            context.push_back(CompilerContext(CompilerContextKind::Namespace, ConstString(GetName())));
+            break;
+        case DW_TAG_structure_type:
+            context.push_back(CompilerContext(CompilerContextKind::Structure, ConstString(GetName())));
+            break;
+        case DW_TAG_union_type:
+            context.push_back(CompilerContext(CompilerContextKind::Union, ConstString(GetName())));
+            break;
+        case DW_TAG_class_type:
+            context.push_back(CompilerContext(CompilerContextKind::Class, ConstString(GetName())));
+            break;
+        case DW_TAG_enumeration_type:
+            context.push_back(CompilerContext(CompilerContextKind::Enumeration, ConstString(GetName())));
+            break;
+        case DW_TAG_subprogram:
+            context.push_back(CompilerContext(CompilerContextKind::Function, ConstString(GetPubname())));
+            break;
+        case DW_TAG_variable:
+            context.push_back(CompilerContext(CompilerContextKind::Variable, ConstString(GetPubname())));
+            break;
+        case DW_TAG_typedef:
+            context.push_back(CompilerContext(CompilerContextKind::Typedef, ConstString(GetName())));
+            break;
+        default:
+            break;
+    }
+}
+
+
 
 DWARFDIE
 DWARFDIE::GetParentDeclContextDIE () const
@@ -371,6 +418,45 @@ DWARFDIE::IsStructOrClass () const
     return tag == DW_TAG_class_type || tag == DW_TAG_structure_type;
 }
 
+
+DWARFDIE
+DWARFDIE::GetContainingDWOModuleDIE () const
+{
+    if (IsValid())
+    {
+        DWARFDIE top_module_die;
+        // Now make sure this DIE is scoped in a DW_TAG_module tag and return true if so
+        for (DWARFDIE parent = GetParent(); parent.IsValid(); parent = parent.GetParent())
+        {
+            const dw_tag_t tag = parent.Tag();
+            if (tag == DW_TAG_module)
+                top_module_die = parent;
+            else if (tag == DW_TAG_compile_unit)
+                break;
+        }
+
+        return top_module_die;
+    }
+    return DWARFDIE();
+}
+
+lldb::ModuleSP
+DWARFDIE::GetContainingDWOModule () const
+{
+    if (IsValid())
+    {
+        DWARFDIE dwo_module_die = GetContainingDWOModuleDIE();
+
+        if (dwo_module_die)
+        {
+            const char *module_name = dwo_module_die.GetName();
+            if (module_name)
+                return GetDWARF()->GetDWOModule (lldb_private::ConstString(module_name));
+        }
+    }
+    return lldb::ModuleSP();
+}
+
 bool
 DWARFDIE::HasChildren () const
 {

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIE.h Mon Dec  7 19:02:08 2015
@@ -126,6 +126,12 @@ public:
         m_die = nullptr;
     }
 
+    lldb::ModuleSP
+    GetContainingDWOModule () const;
+
+    DWARFDIE
+    GetContainingDWOModuleDIE () const;
+
     //----------------------------------------------------------------------
     // Accessing information about a DIE
     //----------------------------------------------------------------------
@@ -217,6 +223,9 @@ public:
     void
     GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const;
 
+    void
+    GetDWOContext (std::vector<lldb_private::CompilerContext> &context) const;
+
     //----------------------------------------------------------------------
     // Getting attribute values from the DIE.
     //

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=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon Dec  7 19:02:08 2015
@@ -1077,9 +1077,9 @@ SymbolFileDWARF::ParseImportedModules (c
         if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
         {
             UpdateExternalModuleListIfNeeded();
-            for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules)
+            for (const auto &pair : m_external_type_modules)
             {
-                imported_modules.push_back(external_type_module.second.m_name);
+                imported_modules.push_back(pair.first);
             }
         }
     }
@@ -1515,13 +1515,32 @@ bool
 SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)
 {
     CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
-    return GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType());
+    if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()))
+    {
+        return true;
+    }
+    TypeSystem *type_system = compiler_type.GetTypeSystem();
+    if (type_system)
+    {
+        DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+        if (dwarf_ast)
+            return dwarf_ast->CanCompleteType(compiler_type);
+    }
+    return false;
 }
 
 
 bool
 SymbolFileDWARF::CompleteType (CompilerType &compiler_type)
 {
+    TypeSystem *type_system = compiler_type.GetTypeSystem();
+    if (type_system)
+    {
+        DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+        if (dwarf_ast && dwarf_ast->CanCompleteType(compiler_type))
+            return dwarf_ast->CompleteType(compiler_type);
+    }
+
     // We have a struct/union/class/enum that needs to be fully resolved.
     CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
     auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());
@@ -1641,6 +1660,17 @@ SymbolFileDWARF::GetFunction (const DWAR
     return false;
 }
 
+lldb::ModuleSP
+SymbolFileDWARF::GetDWOModule (ConstString name)
+{
+    UpdateExternalModuleListIfNeeded();
+    const auto &pos = m_external_type_modules.find(name);
+    if (pos != m_external_type_modules.end())
+        return pos->second;
+    else
+        return lldb::ModuleSP();
+}
+
 void
 SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
 {
@@ -1658,37 +1688,24 @@ SymbolFileDWARF::UpdateExternalModuleLis
         const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
         if (die && die.HasChildren() == false)
         {
-            const uint64_t name_strp = die.GetAttributeValueAsUnsigned (DW_AT_name, UINT64_MAX);
-            const uint64_t dwo_path_strp = die.GetAttributeValueAsUnsigned (DW_AT_GNU_dwo_name, UINT64_MAX);
-            
-            if (name_strp != UINT64_MAX)
+            const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
+
+            if (name)
             {
-                if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end())
+                ConstString const_name(name);
+                if (m_external_type_modules.find(const_name) == 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;
+                    const char *dwo_path = die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
+                    if (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 };
-                        }
+                        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);
                     }
+                    m_external_type_modules[const_name] = module_sp;
                 }
             }
         }
@@ -2970,6 +2987,104 @@ SymbolFileDWARF::FindTypes (const Symbol
         }
         return num_matches;
     }
+    else
+    {
+        UpdateExternalModuleListIfNeeded();
+
+        for (const auto &pair : m_external_type_modules)
+        {
+            ModuleSP external_module_sp = pair.second;
+            if (external_module_sp)
+            {
+                SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor();
+                if (sym_vendor)
+                {
+                    const uint32_t num_external_matches = sym_vendor->FindTypes (sc,
+                                                                                 name,
+                                                                                 parent_decl_ctx,
+                                                                                 append,
+                                                                                 max_matches,
+                                                                                 types);
+                    if (num_external_matches)
+                        return num_external_matches;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+
+size_t
+SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,
+                            bool append,
+                            TypeMap& types)
+{
+    if (!append)
+        types.Clear();
+
+    if (context.empty())
+        return 0;
+
+    DIEArray die_offsets;
+
+    ConstString name = context.back().name;
+
+    if (m_using_apple_tables)
+    {
+        if (m_apple_types_ap.get())
+        {
+            const char *name_cstr = name.GetCString();
+            m_apple_types_ap->FindByName (name_cstr, die_offsets);
+        }
+    }
+    else
+    {
+        if (!m_indexed)
+            Index ();
+
+        m_type_index.Find (name, die_offsets);
+    }
+
+    const size_t num_die_matches = die_offsets.size();
+
+    if (num_die_matches)
+    {
+        size_t num_matches = 0;
+        DWARFDebugInfo* debug_info = DebugInfo();
+        for (size_t i=0; i<num_die_matches; ++i)
+        {
+            const DIERef& die_ref = die_offsets[i];
+            DWARFDIE die = debug_info->GetDIE (die_ref);
+
+            if (die)
+            {
+                std::vector<CompilerContext> die_context;
+                die.GetDWOContext(die_context);
+                if (die_context != context)
+                    continue;
+
+                Type *matching_type = ResolveType (die, true, true);
+                if (matching_type)
+                {
+                    // We found a type pointer, now find the shared pointer form our type list
+                    types.InsertUnique (matching_type->shared_from_this());
+                    ++num_matches;
+                }
+            }
+            else
+            {
+                if (m_using_apple_tables)
+                {
+                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
+                                                                               die_ref.die_offset, name.GetCString());
+                }
+            }
+
+        }
+        return num_matches;
+    }
     return 0;
 }
 

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=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Mon Dec  7 19:02:08 2015
@@ -211,6 +211,11 @@ public:
                uint32_t max_matches,
                lldb_private::TypeMap& types) override;
 
+    size_t
+    FindTypes (const std::vector<lldb_private::CompilerContext> &context,
+               bool append,
+               lldb_private::TypeMap& types) override;
+
     lldb_private::TypeList *
     GetTypeList () override;
 
@@ -306,6 +311,9 @@ public:
     virtual lldb_private::DWARFExpression::LocationListFormat
     GetLocationListFormat() const;
 
+    lldb::ModuleSP
+    GetDWOModule (lldb_private::ConstString name);
+
 protected:
     typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr;
     typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP;
@@ -483,12 +491,7 @@ protected:
 
     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;
+    typedef std::map<lldb_private::ConstString, lldb::ModuleSP> ExternalTypeModuleMap;
 
     void
     GetTypes (const DWARFDIE &die,

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Mon Dec  7 19:02:08 2015
@@ -2280,6 +2280,157 @@ ClangASTContext::GetPointerSizedIntType
     return CompilerType();
 }
 
+void
+ClangASTContext::DumpDeclContextHiearchy (clang::DeclContext *decl_ctx)
+{
+    if (decl_ctx)
+    {
+        DumpDeclContextHiearchy (decl_ctx->getParent());
+
+        clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl_ctx);
+        if (named_decl)
+        {
+            printf ("%20s: %s\n", decl_ctx->getDeclKindName(), named_decl->getDeclName().getAsString().c_str());
+        }
+        else
+        {
+            printf ("%20s\n", decl_ctx->getDeclKindName());
+        }
+    }
+}
+
+void
+ClangASTContext::DumpDeclHiearchy (clang::Decl *decl)
+{
+    if (decl == nullptr)
+        return;
+    DumpDeclContextHiearchy(decl->getDeclContext());
+
+    clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl);
+    if (record_decl)
+    {
+        printf ("%20s: %s%s\n", decl->getDeclKindName(), record_decl->getDeclName().getAsString().c_str(), record_decl->isInjectedClassName() ? " (injected class name)" : "");
+
+    }
+    else
+    {
+        clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl);
+        if (named_decl)
+        {
+            printf ("%20s: %s\n", decl->getDeclKindName(), named_decl->getDeclName().getAsString().c_str());
+        }
+        else
+        {
+            printf ("%20s\n", decl->getDeclKindName());
+        }
+    }
+}
+
+bool
+ClangASTContext::DeclsAreEquivalent (clang::Decl *lhs_decl, clang::Decl *rhs_decl)
+{
+    if (lhs_decl && rhs_decl)
+    {
+        //----------------------------------------------------------------------
+        // Make sure the decl kinds match first
+        //----------------------------------------------------------------------
+        const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind();
+        const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind();
+
+        if (lhs_decl_kind == rhs_decl_kind)
+        {
+            //------------------------------------------------------------------
+            // Now check that the decl contexts kinds are all equivalent
+            // before we have to check any names of the decl contexts...
+            //------------------------------------------------------------------
+            clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
+            clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
+            if (lhs_decl_ctx && rhs_decl_ctx)
+            {
+                while (1)
+                {
+                    if (lhs_decl_ctx && rhs_decl_ctx)
+                    {
+                        const clang::Decl::Kind lhs_decl_ctx_kind = lhs_decl_ctx->getDeclKind();
+                        const clang::Decl::Kind rhs_decl_ctx_kind = rhs_decl_ctx->getDeclKind();
+                        if (lhs_decl_ctx_kind == rhs_decl_ctx_kind)
+                        {
+                            lhs_decl_ctx = lhs_decl_ctx->getParent();
+                            rhs_decl_ctx = rhs_decl_ctx->getParent();
+
+                            if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr)
+                                break;
+                        }
+                        else
+                            return false;
+                    }
+                    else
+                        return false;
+                }
+
+                //--------------------------------------------------------------
+                // Now make sure the name of the decls match
+                //--------------------------------------------------------------
+                clang::NamedDecl *lhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(lhs_decl);
+                clang::NamedDecl *rhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(rhs_decl);
+                if (lhs_named_decl && rhs_named_decl)
+                {
+                    clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
+                    clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
+                    if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind())
+                    {
+                        if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
+                            return false;
+                    }
+                    else
+                        return false;
+                }
+                else
+                    return false;
+
+                //--------------------------------------------------------------
+                // We know that the decl context kinds all match, so now we need
+                // to make sure the names match as well
+                //--------------------------------------------------------------
+                lhs_decl_ctx = lhs_decl->getDeclContext();
+                rhs_decl_ctx = rhs_decl->getDeclContext();
+                while (1)
+                {
+                    switch (lhs_decl_ctx->getDeclKind())
+                    {
+                    case clang::Decl::TranslationUnit:
+                        // We don't care about the translation unit names
+                        return true;
+                    default:
+                        {
+                            clang::NamedDecl *lhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx);
+                            clang::NamedDecl *rhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx);
+                            if (lhs_named_decl && rhs_named_decl)
+                            {
+                                clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
+                                clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
+                                if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind())
+                                {
+                                    if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
+                                        return false;
+                                }
+                                else
+                                    return false;
+                            }
+                            else
+                                return false;
+                        }
+                        break;
+
+                    }
+                    lhs_decl_ctx = lhs_decl_ctx->getParent();
+                    rhs_decl_ctx = rhs_decl_ctx->getParent();
+                }
+            }
+        }
+    }
+    return false;
+}
 bool
 ClangASTContext::GetCompleteDecl (clang::ASTContext *ast,
                                   clang::Decl *decl)
@@ -2451,81 +2602,112 @@ GetCompleteQualType (clang::ASTContext *
         case clang::Type::ConstantArray:
         case clang::Type::IncompleteArray:
         case clang::Type::VariableArray:
-        {
-            const clang::ArrayType *array_type = llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
-            
-            if (array_type)
-                return GetCompleteQualType (ast, array_type->getElementType(), allow_completion);
-        }
+            {
+                const clang::ArrayType *array_type = llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
+                
+                if (array_type)
+                    return GetCompleteQualType (ast, array_type->getElementType(), allow_completion);
+            }
             break;
-            
         case clang::Type::Record:
+            {
+                clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                {
+                    if (cxx_record_decl->hasExternalLexicalStorage())
+                    {
+                        const bool is_complete = cxx_record_decl->isCompleteDefinition();
+                        const bool fields_loaded = cxx_record_decl->hasLoadedFieldsFromExternalStorage();
+                        if (is_complete && fields_loaded)
+                            return true;
+
+                        if (!allow_completion)
+                            return false;
+
+                        // Call the field_begin() accessor to for it to use the external source
+                        // to load the fields...
+                        clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
+                        if (external_ast_source)
+                        {
+                            external_ast_source->CompleteType(cxx_record_decl);
+                            if (cxx_record_decl->isCompleteDefinition())
+                            {
+                                cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true);
+                                cxx_record_decl->field_begin();
+                            }
+                        }
+                    }
+                }
+                const clang::TagType *tag_type = llvm::cast<clang::TagType>(qual_type.getTypePtr());
+                return !tag_type->isIncompleteType();
+            }
+            break;
+
         case clang::Type::Enum:
-        {
-            const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
-            if (tag_type)
             {
-                clang::TagDecl *tag_decl = tag_type->getDecl();
-                if (tag_decl)
+                const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
+                if (tag_type)
                 {
-                    if (tag_decl->isCompleteDefinition())
-                        return true;
-                    
-                    if (!allow_completion)
-                        return false;
-                    
-                    if (tag_decl->hasExternalLexicalStorage())
+                    clang::TagDecl *tag_decl = tag_type->getDecl();
+                    if (tag_decl)
                     {
-                        if (ast)
+                        if (tag_decl->getDefinition())
+                            return true;
+                        
+                        if (!allow_completion)
+                            return false;
+                        
+                        if (tag_decl->hasExternalLexicalStorage())
                         {
-                            clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
-                            if (external_ast_source)
+                            if (ast)
                             {
-                                external_ast_source->CompleteType(tag_decl);
-                                return !tag_type->isIncompleteType();
+                                clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
+                                if (external_ast_source)
+                                {
+                                    external_ast_source->CompleteType(tag_decl);
+                                    return !tag_type->isIncompleteType();
+                                }
                             }
                         }
+                        return false;
                     }
-                    return false;
                 }
+                
             }
-            
-        }
             break;
-            
         case clang::Type::ObjCObject:
         case clang::Type::ObjCInterface:
-        {
-            const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
-            if (objc_class_type)
             {
-                clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-                // We currently can't complete objective C types through the newly added ASTContext
-                // because it only supports TagDecl objects right now...
-                if (class_interface_decl)
+                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+                if (objc_class_type)
                 {
-                    if (class_interface_decl->getDefinition())
-                        return true;
-                    
-                    if (!allow_completion)
-                        return false;
-                    
-                    if (class_interface_decl->hasExternalLexicalStorage())
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    // We currently can't complete objective C types through the newly added ASTContext
+                    // because it only supports TagDecl objects right now...
+                    if (class_interface_decl)
                     {
-                        if (ast)
+                        if (class_interface_decl->getDefinition())
+                            return true;
+                        
+                        if (!allow_completion)
+                            return false;
+                        
+                        if (class_interface_decl->hasExternalLexicalStorage())
                         {
-                            clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
-                            if (external_ast_source)
+                            if (ast)
                             {
-                                external_ast_source->CompleteType (class_interface_decl);
-                                return !objc_class_type->isIncompleteType();
+                                clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
+                                if (external_ast_source)
+                                {
+                                    external_ast_source->CompleteType (class_interface_decl);
+                                    return !objc_class_type->isIncompleteType();
+                                }
                             }
                         }
+                        return false;
                     }
-                    return false;
                 }
             }
-        }
             break;
             
         case clang::Type::Typedef:
@@ -2536,7 +2718,10 @@ GetCompleteQualType (clang::ASTContext *
             
         case clang::Type::Paren:
             return GetCompleteQualType (ast, llvm::cast<clang::ParenType>(qual_type)->desugar(), allow_completion);
-            
+
+        case clang::Type::Attributed:
+            return GetCompleteQualType (ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(), allow_completion);
+
         default:
             break;
     }
@@ -7160,6 +7345,16 @@ ClangASTContext::GetAsRecordDecl (const
     return nullptr;
 }
 
+clang::TagDecl *
+ClangASTContext::GetAsTagDecl (const CompilerType& type)
+{
+    clang::QualType qual_type = GetCanonicalQualType(type);
+    if (qual_type.isNull())
+        return nullptr;
+    else
+        return qual_type->getAsTagDecl();
+}
+
 clang::CXXRecordDecl *
 ClangASTContext::GetAsCXXRecordDecl (lldb::opaque_compiler_type_t type)
 {
@@ -8037,6 +8232,64 @@ ClangASTContext::AddMethodToObjCObjectTy
 }
 
 bool
+ClangASTContext::GetHasExternalStorage (const CompilerType &type)
+{
+    if (IsClangType(type))
+        return false;
+
+    clang::QualType qual_type (GetCanonicalQualType(type));
+
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+        {
+            clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+            if (cxx_record_decl)
+                return cxx_record_decl->hasExternalLexicalStorage () || cxx_record_decl->hasExternalVisibleStorage();
+        }
+            break;
+
+        case clang::Type::Enum:
+        {
+            clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+            if (enum_decl)
+                return enum_decl->hasExternalLexicalStorage () || enum_decl->hasExternalVisibleStorage();
+        }
+            break;
+
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+        {
+            const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+            assert (objc_class_type);
+            if (objc_class_type)
+            {
+                clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+                if (class_interface_decl)
+                    return class_interface_decl->hasExternalLexicalStorage () || class_interface_decl->hasExternalVisibleStorage ();
+            }
+        }
+            break;
+
+        case clang::Type::Typedef:
+            return GetHasExternalStorage (CompilerType(type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+
+        case clang::Type::Elaborated:
+            return GetHasExternalStorage (CompilerType(type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+
+        case clang::Type::Paren:
+            return GetHasExternalStorage (CompilerType(type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+        default:
+            break;
+    }
+    return false;
+}
+
+
+bool
 ClangASTContext::SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool has_extern)
 {
     if (!type)
@@ -8106,39 +8359,174 @@ ClangASTContext::SetHasExternalStorage (
 }
 
 
-#pragma mark TagDecl
+bool
+ClangASTContext::CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer)
+{
+    if (IsClangType(type))
+    {
+        // TODO: remove external completion BOOL
+        // CompleteAndFetchChildren should get the Decl out and check for the
+
+        clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
+
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+            {
+                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                {
+                    if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL))
+                        return true;
+                }
+            }
+                break;
+
+            case clang::Type::Enum:
+            {
+                clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+                if (enum_decl)
+                {
+                    if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL))
+                        return true;
+                }
+            }
+                break;
+
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+            {
+                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+                if (objc_class_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    // We currently can't complete objective C types through the newly added ASTContext
+                    // because it only supports TagDecl objects right now...
+                    if (class_interface_decl)
+                    {
+                        if (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL))
+                            return true;
+                    }
+                }
+            }
+                break;
+
+
+            case clang::Type::Typedef:
+                return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer);
+
+            case clang::Type::Elaborated:
+                return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer);
 
+            case clang::Type::Paren:
+                return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer);
+
+            default:
+                break;
+        }
+    }
+    return false;
+}
 bool
-ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type)
+ClangASTContext::Import (const CompilerType &type, lldb_private::ClangASTImporter &importer)
 {
-    if (type)
+    if (IsClangType(type))
     {
-        
-        clang::QualType qual_type (GetQualType(type));
-        const clang::Type *t = qual_type.getTypePtr();
-        if (t)
+        // TODO: remove external completion BOOL
+        // CompleteAndFetchChildren should get the Decl out and check for the
+
+        clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
+
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
         {
-            const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(t);
-            if (tag_type)
+            case clang::Type::Record:
             {
-                clang::TagDecl *tag_decl = tag_type->getDecl();
-                if (tag_decl)
+                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
                 {
-                    tag_decl->startDefinition();
-                    return true;
+                    if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL))
+                        return importer.CompleteAndFetchChildren(qual_type);
                 }
             }
-            
-            const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(t);
-            if (object_type)
+                break;
+
+            case clang::Type::Enum:
             {
-                clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
-                if (interface_decl)
+                clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+                if (enum_decl)
                 {
-                    interface_decl->startDefinition();
-                    return true;
+                    if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL))
+                        return importer.CompleteAndFetchChildren(qual_type);
                 }
             }
+                break;
+
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+            {
+                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+                if (objc_class_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    // We currently can't complete objective C types through the newly added ASTContext
+                    // because it only supports TagDecl objects right now...
+                    if (class_interface_decl)
+                    {
+                        if (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL))
+                            return importer.CompleteAndFetchChildren(qual_type);
+                    }
+                }
+            }
+                break;
+
+
+            case clang::Type::Typedef:
+                return Import (CompilerType(type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer);
+
+            case clang::Type::Elaborated:
+                return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer);
+
+            case clang::Type::Paren:
+                return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer);
+                
+            default:
+                break;
+        }
+    }
+    return false;
+}
+
+
+#pragma mark TagDecl
+
+bool
+ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type)
+{
+    clang::QualType qual_type (ClangASTContext::GetQualType(type));
+    if (!qual_type.isNull())
+    {
+        const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
+        if (tag_type)
+        {
+            clang::TagDecl *tag_decl = tag_type->getDecl();
+            if (tag_decl)
+            {
+                tag_decl->startDefinition();
+                return true;
+            }
+        }
+        
+        const clang::ObjCObjectType *object_type = qual_type->getAs<clang::ObjCObjectType>();
+        if (object_type)
+        {
+            clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
+            if (interface_decl)
+            {
+                interface_decl->startDefinition();
+                return true;
+            }
         }
     }
     return false;
@@ -8147,26 +8535,22 @@ ClangASTContext::StartTagDeclarationDefi
 bool
 ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type)
 {
-    if (type)
+    clang::QualType qual_type (ClangASTContext::GetQualType(type));
+    if (!qual_type.isNull())
     {
-        clang::QualType qual_type (GetQualType(type));
-        if (qual_type.isNull())
-            return false;
-        ClangASTContext *lldb_ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
-        if (lldb_ast == nullptr)
-            return false;
-        clang::ASTContext *ast = lldb_ast->getASTContext();
-
         clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
         
         if (cxx_record_decl)
         {
-            cxx_record_decl->completeDefinition();
-            
+            if (!cxx_record_decl->isCompleteDefinition())
+                cxx_record_decl->completeDefinition();
+            cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
+            cxx_record_decl->setHasExternalLexicalStorage (false);
+            cxx_record_decl->setHasExternalVisibleStorage (false);
             return true;
         }
         
-        const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(qual_type.getTypePtr());
+        const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>();
         
         if (enutype)
         {
@@ -8174,25 +8558,33 @@ ClangASTContext::CompleteTagDeclarationD
             
             if (enum_decl)
             {
-                /// TODO This really needs to be fixed.
-                
-                unsigned NumPositiveBits = 1;
-                unsigned NumNegativeBits = 0;
-                
-                clang::QualType promotion_qual_type;
-                // If the enum integer type is less than an integer in bit width,
-                // then we must promote it to an integer size.
-                if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
+                if (!enum_decl->isCompleteDefinition())
                 {
-                    if (enum_decl->getIntegerType()->isSignedIntegerType())
-                        promotion_qual_type = ast->IntTy;
+                    ClangASTContext *lldb_ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
+                    if (lldb_ast == nullptr)
+                        return false;
+                    clang::ASTContext *ast = lldb_ast->getASTContext();
+
+                    /// TODO This really needs to be fixed.
+                    
+                    unsigned NumPositiveBits = 1;
+                    unsigned NumNegativeBits = 0;
+                    
+                    clang::QualType promotion_qual_type;
+                    // If the enum integer type is less than an integer in bit width,
+                    // then we must promote it to an integer size.
+                    if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
+                    {
+                        if (enum_decl->getIntegerType()->isSignedIntegerType())
+                            promotion_qual_type = ast->IntTy;
+                        else
+                            promotion_qual_type = ast->UnsignedIntTy;
+                    }
                     else
-                        promotion_qual_type = ast->UnsignedIntTy;
+                        promotion_qual_type = enum_decl->getIntegerType();
+                    
+                    enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
                 }
-                else
-                    promotion_qual_type = enum_decl->getIntegerType();
-                
-                enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
                 return true;
             }
         }
@@ -8976,6 +9368,72 @@ ClangASTContext::DumpTypeDescription (ll
     }
 }
 
+void
+ClangASTContext::DumpTypeName (const CompilerType &type)
+{
+    if (IsClangType(type))
+    {
+        clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type)));
+
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+            {
+                const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                    printf("class %s", cxx_record_decl->getName().str().c_str());
+            }
+                break;
+
+            case clang::Type::Enum:
+            {
+                clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+                if (enum_decl)
+                {
+                    printf("enum %s", enum_decl->getName().str().c_str());
+                }
+            }
+                break;
+
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+            {
+                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+                if (objc_class_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    // We currently can't complete objective C types through the newly added ASTContext
+                    // because it only supports TagDecl objects right now...
+                    if (class_interface_decl)
+                        printf("@class %s", class_interface_decl->getName().str().c_str());
+                }
+            }
+                break;
+
+
+            case clang::Type::Typedef:
+                printf("typedef %s", llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getName().str().c_str());
+                break;
+
+            case clang::Type::Elaborated:
+                printf("elaborated ");
+                return DumpTypeName (CompilerType (type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+
+            case clang::Type::Paren:
+                printf("paren ");
+                return DumpTypeName (CompilerType (type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+            default:
+                printf("ClangASTContext::DumpTypeName() type_class = %u", type_class);
+                break;
+        }
+    }
+
+}
+
+
+
 clang::ClassTemplateDecl *
 ClangASTContext::ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
                                          lldb::AccessType access_type,

Modified: lldb/trunk/source/Symbol/ClangASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTImporter.cpp?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTImporter.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTImporter.cpp Mon Dec  7 19:02:08 2015
@@ -67,6 +67,31 @@ ClangASTImporter::CopyType (clang::ASTCo
     return CopyType (dst_ast, src_ast, QualType::getFromOpaquePtr(type)).getAsOpaquePtr();
 }
 
+CompilerType
+ClangASTImporter::CopyType (ClangASTContext &dst_ast,
+                            const CompilerType &src_type)
+{
+    clang::ASTContext *dst_clang_ast = dst_ast.getASTContext();
+    if (dst_clang_ast)
+    {
+        ClangASTContext *src_ast = llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
+        if (src_ast)
+        {
+            clang::ASTContext *src_clang_ast = src_ast->getASTContext();
+            if (src_clang_ast)
+            {
+                lldb::opaque_compiler_type_t dst_clang_type = CopyType(dst_clang_ast,
+                                                                       src_clang_ast,
+                                                                       src_type.GetOpaqueQualType());
+
+                if (dst_clang_type)
+                    return CompilerType(&dst_ast, dst_clang_type);
+            }
+        }
+    }
+    return CompilerType();
+}
+
 clang::Decl *
 ClangASTImporter::CopyDecl (clang::ASTContext *dst_ast,
                             clang::ASTContext *src_ast,
@@ -429,6 +454,68 @@ ClangASTImporter::CompleteObjCInterfaceD
 }
 
 bool
+ClangASTImporter::CompleteAndFetchChildren (clang::QualType type)
+{
+    if (!RequireCompleteType(type))
+        return false;
+
+    if (const TagType *tag_type = type->getAs<TagType>())
+    {
+        TagDecl *tag_decl = tag_type->getDecl();
+
+        DeclOrigin decl_origin = GetDeclOrigin(tag_decl);
+
+        if (!decl_origin.Valid())
+            return false;
+
+        MinionSP minion_sp (GetMinion(&tag_decl->getASTContext(), decl_origin.ctx));
+
+        TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl);
+
+        for (Decl *origin_child_decl : origin_tag_decl->decls())
+        {
+            minion_sp->Import(origin_child_decl);
+        }
+
+        if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl))
+        {
+            record_decl->setHasLoadedFieldsFromExternalStorage(true);
+        }
+
+        return true;
+    }
+
+    if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>())
+    {
+        if (ObjCInterfaceDecl *objc_interface_decl = objc_object_type->getInterface())
+        {
+            DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl);
+
+            if (!decl_origin.Valid())
+                return false;
+
+            MinionSP minion_sp (GetMinion(&objc_interface_decl->getASTContext(), decl_origin.ctx));
+
+            ObjCInterfaceDecl *origin_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl);
+
+            for (Decl *origin_child_decl : origin_interface_decl->decls())
+            {
+                minion_sp->Import(origin_child_decl);
+            }
+
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+    
+    return true;
+}
+
+
+bool
 ClangASTImporter::RequireCompleteType (clang::QualType type)
 {
     if (type.isNull())
@@ -793,10 +880,14 @@ ClangASTImporter::Minion::Imported (clan
             {
                 if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to))
                 {
-                    NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
-
-                    if (!m_decls_already_deported->count(to_named_decl))
-                        m_decls_to_deport->insert(to_named_decl);
+                    RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from);
+                    if (from_record_decl == nullptr || from_record_decl->isInjectedClassName() == false)
+                    {
+                        NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
+
+                        if (!m_decls_already_deported->count(to_named_decl))
+                            m_decls_to_deport->insert(to_named_decl);
+                    }
                 }
             }
             

Modified: lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp (original)
+++ lldb/trunk/source/Symbol/ClangExternalASTSourceCallbacks.cpp Mon Dec  7 19:02:08 2015
@@ -41,6 +41,7 @@
 #endif
 
 #include "lldb/Core/Log.h"
+#include "clang/AST/Decl.h"
 
 using namespace clang;
 using namespace lldb_private;
@@ -160,3 +161,16 @@ ClangExternalASTSourceCallbacks::layoutR
     return false;
 }
 
+void
+ClangExternalASTSourceCallbacks::FindExternalLexicalDecls (const clang::DeclContext *decl_ctx,
+                                                           llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+                                                           llvm::SmallVectorImpl<clang::Decl *> &decls)
+{
+    if (m_callback_tag_decl && decl_ctx)
+    {
+        clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(const_cast<clang::DeclContext *>(decl_ctx));
+        if (tag_decl)
+            CompleteType(tag_decl);
+    }
+}
+

Modified: lldb/trunk/source/Symbol/SymbolFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolFile.cpp?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/SymbolFile.cpp (original)
+++ lldb/trunk/source/Symbol/SymbolFile.cpp Mon Dec  7 19:02:08 2015
@@ -142,3 +142,11 @@ SymbolFile::FindTypes (const SymbolConte
     return 0;
 }
 
+
+size_t
+SymbolFile::FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types)
+{
+    if (!append)
+        types.Clear();
+    return 0;
+}

Modified: lldb/trunk/source/Symbol/SymbolVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolVendor.cpp?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/SymbolVendor.cpp (original)
+++ lldb/trunk/source/Symbol/SymbolVendor.cpp Mon Dec  7 19:02:08 2015
@@ -361,6 +361,21 @@ SymbolVendor::FindTypes (const SymbolCon
 }
 
 size_t
+SymbolVendor::FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types)
+{
+    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->FindTypes(context, append, types);
+    }
+    if (!append)
+        types.Clear();
+    return 0;
+}
+
+size_t
 SymbolVendor::GetTypes (SymbolContextScope *sc_scope,
                         uint32_t type_mask,
                         lldb_private::TypeList &type_list)

Modified: lldb/trunk/source/Symbol/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Type.cpp?rev=254980&r1=254979&r2=254980&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Type.cpp (original)
+++ lldb/trunk/source/Symbol/Type.cpp Mon Dec  7 19:02:08 2015
@@ -7,8 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// Other libraries and framework includes
+// C Includes
+#include <stdio.h>
 
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Module.h"
@@ -36,6 +40,27 @@
 using namespace lldb;
 using namespace lldb_private;
 
+void
+CompilerContext::Dump() const
+{
+    switch (type)
+    {
+        case CompilerContextKind::Invalid:          printf("Invalid"); break;
+        case CompilerContextKind::TranslationUnit:  printf("TranslationUnit"); break;
+        case CompilerContextKind::Module:           printf("Module"); break;
+        case CompilerContextKind::Namespace:        printf("Namespace"); break;
+        case CompilerContextKind::Class:            printf("Class"); break;
+        case CompilerContextKind::Structure:        printf("Structure"); break;
+        case CompilerContextKind::Union:            printf("Union"); break;
+        case CompilerContextKind::Function:         printf("Function"); break;
+        case CompilerContextKind::Variable:         printf("Variable"); break;
+        case CompilerContextKind::Enumeration:      printf("Enumeration"); break;
+        case CompilerContextKind::Typedef:          printf("Typedef"); break;
+        default: printf("???(%u)", type);
+    }
+    printf("(\"%s\")\n", name.GetCString());
+}
+
 class TypeAppendVisitor
 {
 public:
@@ -62,6 +87,13 @@ TypeListImpl::Append (const lldb_private
     type_list.ForEach(cb);
 }
 
+SymbolFileType::SymbolFileType (SymbolFile &symbol_file, const lldb::TypeSP &type_sp) :
+    UserID (type_sp ? type_sp->GetID() : LLDB_INVALID_UID),
+    m_symbol_file (symbol_file),
+    m_type_sp (type_sp)
+{
+}
+
 
 Type *
 SymbolFileType::GetType ()




More information about the lldb-commits mailing list