[Lldb-commits] [lldb] r163651 - in /lldb/trunk: include/lldb/Symbol/ include/lldb/Target/ source/Expression/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Target/

Sean Callanan scallanan at apple.com
Tue Sep 11 14:44:01 PDT 2012


Author: spyffe
Date: Tue Sep 11 16:44:01 2012
New Revision: 163651

URL: http://llvm.org/viewvc/llvm-project?rev=163651&view=rev
Log:
This patch is part of ongoing work to extract type
information from the Objective-C runtime.

This patch takes the old AppleObjCSymbolVendor and
replaces it with an AppleObjCTypeVendor, which is
much more lightweight.  Specifically, the SymbolVendor
needs to pretend that there is a backing symbol file
for the Types it vends, whereas a TypeVendor only
vends bare ClangASTTypes.  These ClangASTTypes only
need to exist in an ASTContext.

The ClangASTSource now falls back to the runtime's
TypeVendor (if one exists) if the debug information
doesn't find a complete type for a particular
Objective-C interface.  The runtime's TypeVendor
maintains an ASTContext full of types it knows about,
and re-uses the ISA-based type query information used
by the ValueObjects.

Currently, the runtime's TypeVendor doesn't provide
useful answers because we haven't yet implemented a
way to iterate across all ISAs contained in the target
process's runtime.  That's the next step.

Added:
    lldb/trunk/include/lldb/Symbol/TypeVendor.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
      - copied, changed from r163149, lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h
      - copied, changed from r163149, lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h
Removed:
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h
Modified:
    lldb/trunk/include/lldb/Target/LanguageRuntime.h
    lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
    lldb/trunk/source/Expression/ClangASTSource.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
    lldb/trunk/source/Target/ObjCLanguageRuntime.cpp

Added: lldb/trunk/include/lldb/Symbol/TypeVendor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/TypeVendor.h?rev=163651&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Symbol/TypeVendor.h (added)
+++ lldb/trunk/include/lldb/Symbol/TypeVendor.h Tue Sep 11 16:44:01 2012
@@ -0,0 +1,56 @@
+//===-- TypeVendor.h --------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TypeVendor_h_
+#define liblldb_TypeVendor_h_
+
+namespace lldb_private {
+    
+//----------------------------------------------------------------------
+// The type vendor class is intended as a generic interface to search
+// for Clang types that are not necessarily backed by a specific symbol
+// file.
+//----------------------------------------------------------------------
+class TypeVendor
+{
+public:
+    //------------------------------------------------------------------
+    // Constructors and Destructors
+    //------------------------------------------------------------------
+    TypeVendor()
+    {
+    }
+    
+    virtual
+    ~TypeVendor()
+    {
+    }
+    
+    virtual uint32_t
+    FindTypes (const ConstString &name,
+               bool append,
+               uint32_t max_matches,
+               std::vector <ClangASTType> &types) = 0;
+
+protected:
+    //------------------------------------------------------------------
+    // Classes that inherit from TypeVendor can see and modify these
+    //------------------------------------------------------------------
+    
+private:
+    //------------------------------------------------------------------
+    // For TypeVendor only
+    //------------------------------------------------------------------
+    DISALLOW_COPY_AND_ASSIGN (TypeVendor);
+};
+    
+    
+} // namespace lldb_private
+
+#endif

Modified: lldb/trunk/include/lldb/Target/LanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/LanguageRuntime.h?rev=163651&r1=163650&r2=163651&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/LanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/LanguageRuntime.h Tue Sep 11 16:44:01 2012
@@ -83,6 +83,12 @@
     
     static const char *
     GetNameForLanguageType (lldb::LanguageType language);
+    
+    Process *
+    GetProcess()
+    {
+        return m_process;
+    }
         
 protected:
     //------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=163651&r1=163650&r2=163651&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Tue Sep 11 16:44:01 2012
@@ -19,6 +19,7 @@
 #include "lldb/lldb-private.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/TypeVendor.h"
 #include "lldb/Target/LanguageRuntime.h"
 
 namespace lldb_private {
@@ -222,14 +223,17 @@
     virtual ObjCISA
     GetISA(ValueObject& valobj) = 0;
     
+    virtual ObjCISA
+    GetISA(const ConstString &name);
+    
     virtual ConstString
     GetActualTypeName(ObjCISA isa);
     
     virtual ObjCISA
     GetParentClass(ObjCISA isa);
     
-    virtual SymbolVendor *
-    GetSymbolVendor()
+    virtual TypeVendor *
+    GetTypeVendor()
     {
         return NULL;
     }

Modified: lldb/trunk/source/Expression/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangASTSource.cpp?rev=163651&r1=163650&r2=163651&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Expression/ClangASTSource.cpp Tue Sep 11 16:44:01 2012
@@ -622,9 +622,11 @@
                             name.GetCString(), 
                             (name_string ? name_string : "<anonymous>"));
             }
-            
+                        
+            clang::ASTContext *type_ast = type_sp->GetClangAST();
+            lldb::clang_type_t full_type = type_sp->GetClangFullType();
 
-            void *copied_type = GuardedCopyType(m_ast_context, type_sp->GetClangAST(), type_sp->GetClangFullType());
+            void *copied_type = GuardedCopyType(m_ast_context, type_ast, full_type);
                 
             if (!copied_type)
             {                
@@ -641,6 +643,87 @@
     } while(0);
 }
 
+static void
+FindObjCMethodDeclsWithOrigin (unsigned int current_id,
+                               NameSearchContext &context,
+                               ObjCInterfaceDecl *original_interface_decl,
+                               clang::ASTContext *ast_context,
+                               ClangASTImporter *ast_importer,
+                               const char *log_info)
+{
+    const DeclarationName &decl_name(context.m_decl_name);
+    clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
+
+    Selector original_selector;
+    
+    if (decl_name.isObjCZeroArgSelector())
+    {
+        IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
+        original_selector = original_ctx->Selectors.getSelector(0, &ident);
+    }
+    else if (decl_name.isObjCOneArgSelector())
+    {
+        const std::string &decl_name_string = decl_name.getAsString();
+        std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1);
+        IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str());
+        original_selector = original_ctx->Selectors.getSelector(1, &ident);
+    }
+    else
+    {
+        SmallVector<IdentifierInfo *, 4> idents;
+        
+        clang::Selector sel = decl_name.getObjCSelector();
+        
+        int num_args = sel.getNumArgs();
+        
+        for (unsigned i = 0;
+             i != num_args;
+             ++i)
+        {
+            idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
+        }
+        
+        original_selector = original_ctx->Selectors.getSelector(num_args, idents.data());
+    }
+    
+    DeclarationName original_decl_name(original_selector);
+    
+    ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name);
+    
+    if (result.first == result.second)
+        return;
+    
+    if (!*result.first)
+        return;
+    
+    ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(*result.first);
+    
+    if (!result_method)
+        return;
+    
+    Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method);
+    
+    if (!copied_decl)
+        return;
+    
+    ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
+    
+    if (!copied_method_decl)
+        return;
+    
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    
+    if (log)
+    {
+        ASTDumper dumper((Decl*)copied_method_decl);
+        log->Printf("  CAS::FOMD[%d] found (%s) %s", current_id, log_info, dumper.GetCString());
+    }
+    
+    context.AddNamedDecl(copied_method_decl);
+    
+    return;
+}
+
 void
 ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
 {
@@ -669,72 +752,12 @@
             
         ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl);
         
-        Selector original_selector;
-                
-        if (decl_name.isObjCZeroArgSelector())
-        {
-            IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
-            original_selector = original_ctx->Selectors.getSelector(0, &ident);
-        }
-        else if (decl_name.isObjCOneArgSelector())
-        {
-            const std::string &decl_name_string = decl_name.getAsString();
-            std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1);
-            IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str());
-            original_selector = original_ctx->Selectors.getSelector(1, &ident);
-        }
-        else
-        {
-            SmallVector<IdentifierInfo *, 4> idents;
-            
-            clang::Selector sel = decl_name.getObjCSelector();
-            
-            int num_args = sel.getNumArgs();
-            
-            for (unsigned i = 0;
-                 i != num_args;
-                 ++i)
-            {
-                idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
-            }
-            
-            original_selector = original_ctx->Selectors.getSelector(num_args, idents.data());
-        }
-        
-        DeclarationName original_decl_name(original_selector);
-                
-        ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name);
-        
-        if (result.first == result.second)
-            break;
-        
-        if (!*result.first)
-            break;
-        
-        ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(*result.first);
-        
-        if (!result_method)
-            break;
-        
-        Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &result_method->getASTContext(), result_method);
-        
-        if (!copied_decl)
-            continue;
-        
-        ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
-        
-        if (!copied_method_decl)
-            continue;
-        
-        if (log)
-        {
-            ASTDumper dumper((Decl*)copied_method_decl);
-            log->Printf("  CAS::FOMD[%d] found (in debug info) %s", current_id, dumper.GetCString());
-        }
-        
-        context.AddNamedDecl(copied_method_decl);
-        
-        return;
+        FindObjCMethodDeclsWithOrigin(current_id,
+                                      context,
+                                      original_interface_decl,
+                                      m_ast_context,
+                                      m_ast_importer,
+                                      "in debug info");
     } while (0);
     
     StreamString ss;
@@ -845,53 +868,105 @@
     }
     while (0);
     
-    for (uint32_t i = 0, e = sc_list.GetSize();
-         i != e;
-         ++i)
+    if (sc_list.GetSize())
     {
-        SymbolContext sc;
-        
-        if (!sc_list.GetContextAtIndex(i, sc))
-            continue;
-        
-        if (!sc.function)
-            continue;
-        
-        DeclContext *function_ctx = sc.function->GetClangDeclContext();
-        
-        if (!function_ctx)
-            continue;
-        
-        ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(function_ctx);
-        
-        if (!method_decl)
-            continue;
+        // We found a good function symbol.  Use that.
         
-        ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
-        
-        if (!found_interface_decl)
-            continue;
-        
-        if (found_interface_decl->getName() == interface_decl->getName())
+        for (uint32_t i = 0, e = sc_list.GetSize();
+             i != e;
+             ++i)
         {
-            Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
+            SymbolContext sc;
+            
+            if (!sc_list.GetContextAtIndex(i, sc))
+                continue;
             
-            if (!copied_decl)
+            if (!sc.function)
                 continue;
             
-            ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
+            DeclContext *function_ctx = sc.function->GetClangDeclContext();
             
-            if (!copied_method_decl)
+            if (!function_ctx)
                 continue;
             
-            if (log)
+            ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(function_ctx);
+            
+            if (!method_decl)
+                continue;
+            
+            ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
+            
+            if (!found_interface_decl)
+                continue;
+            
+            if (found_interface_decl->getName() == interface_decl->getName())
             {
-                ASTDumper dumper((Decl*)copied_method_decl);
-                log->Printf("  CAS::FOMD[%d] found (in debug info) %s", current_id, dumper.GetCString());
+                Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
+                
+                if (!copied_decl)
+                    continue;
+                
+                ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
+                
+                if (!copied_method_decl)
+                    continue;
+                
+                if (log)
+                {
+                    ASTDumper dumper((Decl*)copied_method_decl);
+                    log->Printf("  CAS::FOMD[%d] found (in debug info) %s", current_id, dumper.GetCString());
+                }
+                
+                context.AddNamedDecl(copied_method_decl);
             }
+        }
+    }
+    else
+    {
+        do
+        {
+            // We need to look at the runtime.
+            
+            lldb::ProcessSP process(m_target->GetProcessSP());
+            
+            if (!process)
+                break;
+            
+            ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+
+            TypeVendor *type_vendor = language_runtime->GetTypeVendor();
+            
+            if (!type_vendor)
+                break;
+            
+            ConstString interface_name(interface_decl->getNameAsString().c_str());
+            bool append = false;
+            uint32_t max_matches = 1;
+            std::vector <ClangASTType> types;
+            
+            if (!type_vendor->FindTypes(interface_name,
+                                        append,
+                                        max_matches,
+                                        types))
+                break;
+            
+            const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
+            
+            const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type);
             
-            context.AddNamedDecl(copied_method_decl);
+            if (!runtime_interface_type)
+                break;
+            
+            ObjCInterfaceDecl *runtime_interface_decl = runtime_interface_type->getDecl();
+            
+            FindObjCMethodDeclsWithOrigin(current_id,
+                                          context,
+                                          runtime_interface_decl,
+                                          m_ast_context,
+                                          m_ast_importer,
+                                          "in runtime");
         }
+        while(0);
     }
 }
 
@@ -1055,41 +1130,89 @@
     if (!language_runtime)
         return;
     
-    lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
-    
-    if (!complete_type_sp)
-        return;
-    
-    TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType(), complete_type_sp->GetClangAST());
-    lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
-    
-    if (!complete_opaque_type)
-        return;
-    
-    const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
-    const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
-    
-    if (!complete_interface_type)
-        return;
-    
-    DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_type->getDecl());
-    
-    if (complete_iface_decl.decl == origin_iface_decl.decl)
-        return; // already checked this one
-    
-    if (log)
-        log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
-                    current_id,
-                    complete_iface_decl.decl, 
-                    &complete_iface_decl->getASTContext());
-    
+    do
+    {
+        // First see if any other debug information has this property/ivar.
+        
+        lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
+        
+        if (!complete_type_sp)
+            break;
+        
+        TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType(), complete_type_sp->GetClangAST());
+        lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
+        
+        if (!complete_opaque_type)
+            break;
+        
+        const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
+        const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
+        
+        if (!complete_interface_type)
+            break;
+        
+        DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_type->getDecl());
+        
+        if (complete_iface_decl.decl == origin_iface_decl.decl)
+            break; // already checked this one
+        
+        if (log)
+            log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+                        current_id,
+                        complete_iface_decl.decl, 
+                        &complete_iface_decl->getASTContext());
+        
+        if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, 
+                                                   context, 
+                                                   *m_ast_context, 
+                                                   m_ast_importer, 
+                                                   complete_iface_decl))
+            return;
+    }
+    while(0);
     
-    if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, 
-                                               context, 
-                                               *m_ast_context, 
-                                               m_ast_importer, 
-                                               complete_iface_decl))
-        return;
+    do
+    {
+        // Now check the runtime.
+        
+        TypeVendor *type_vendor = language_runtime->GetTypeVendor();
+        
+        if (!type_vendor)
+            break;
+        
+        bool append = false;
+        uint32_t max_matches = 1;
+        std::vector <ClangASTType> types;
+        
+        if (!type_vendor->FindTypes(class_name,
+                                    append,
+                                    max_matches,
+                                    types))
+            break;
+        
+        const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
+
+        const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type);
+        
+        if (!runtime_interface_type)
+            break;
+        
+        DeclFromUser<const ObjCInterfaceDecl> runtime_iface_decl(runtime_interface_type->getDecl());
+        
+        if (log)
+            log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+                        current_id,
+                        runtime_iface_decl.decl,
+                        &runtime_iface_decl->getASTContext());
+        
+        if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
+                                                   context,
+                                                   *m_ast_context,
+                                                   m_ast_importer,
+                                                   runtime_iface_decl))
+            return;
+    }
+    while(0);
 }
 
 typedef llvm::DenseMap <const FieldDecl *, uint64_t> FieldOffsetMap;

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=163651&r1=163650&r2=163651&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Tue Sep 11 16:44:01 2012
@@ -32,6 +32,7 @@
 #include "lldb/Expression/ClangUtilityFunction.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/TypeList.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
@@ -39,7 +40,7 @@
 #include "lldb/Target/Thread.h"
 
 #include "AppleObjCRuntimeV2.h"
-#include "AppleObjCSymbolVendor.h"
+#include "AppleObjCTypeVendor.h"
 #include "AppleObjCTrampolineHandler.h"
 
 #include <vector>
@@ -700,13 +701,13 @@
     return descriptor->GetClassName();
 }
 
-SymbolVendor *
-AppleObjCRuntimeV2::GetSymbolVendor()
+TypeVendor *
+AppleObjCRuntimeV2::GetTypeVendor()
 {
-    if (!m_symbol_vendor_ap.get())
-        m_symbol_vendor_ap.reset(new AppleObjCSymbolVendor(m_process));
+    if (!m_type_vendor_ap.get())
+        m_type_vendor_ap.reset(new AppleObjCTypeVendor(*this));
     
-    return m_symbol_vendor_ap.get();
+    return m_type_vendor_ap.get();
 }
 
 AppleObjCRuntimeV2::ClassDescriptorV2::ClassDescriptorV2 (ValueObject &isa_pointer)

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h?rev=163651&r1=163650&r2=163651&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h Tue Sep 11 16:44:01 2012
@@ -244,7 +244,7 @@
     static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
     
     virtual ObjCLanguageRuntime::ObjCISA
-    GetISA(ValueObject& valobj);   
+    GetISA(ValueObject& valobj);
     
     virtual ConstString
     GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa);
@@ -255,8 +255,8 @@
     virtual ClassDescriptorSP
     GetClassDescriptor (ObjCISA isa);
     
-    virtual SymbolVendor *
-    GetSymbolVendor();
+    virtual TypeVendor *
+    GetTypeVendor();
     
 protected:
     virtual lldb::BreakpointResolverSP
@@ -278,7 +278,7 @@
     lldb::addr_t                        m_get_class_name_args;
     Mutex                               m_get_class_name_args_mutex;
     
-    std::auto_ptr<SymbolVendor>         m_symbol_vendor_ap;
+    std::auto_ptr<TypeVendor>           m_type_vendor_ap;
     
     static const char *g_find_class_name_function_name;
     static const char *g_find_class_name_function_body;

Removed: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp?rev=163650&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp (removed)
@@ -1,83 +0,0 @@
-//===-- AppleObjCSymbolVendor.cpp -------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AppleObjCSymbolVendor.h"
-
-#include "lldb/Core/Log.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-
-#include "clang/AST/ASTContext.h"
-
-using namespace lldb_private;
-
-AppleObjCSymbolVendor::AppleObjCSymbolVendor(Process *process) :
-    SymbolVendor(lldb::ModuleSP()),
-    m_process(process->shared_from_this()),
-    m_ast_ctx(process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str())
-{
-}
-
-uint32_t
-AppleObjCSymbolVendor::FindTypes (const SymbolContext& sc, 
-                                  const ConstString &name,
-                                  const ClangNamespaceDecl *namespace_decl, 
-                                  bool append, 
-                                  uint32_t max_matches, 
-                                  TypeList& types)
-{
-    lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));  // FIXME - a more appropriate log channel?
-        
-    if (log)
-        log->Printf("ObjC SymbolVendor asked for '%s'", 
-                    name.AsCString());
-    
-    if (!append)
-        types.Clear();
-    
-    uint32_t ret = 0;
-    
-    ModuleList &target_modules = m_process->GetTarget().GetImages();
-    Mutex::Locker modules_locker(target_modules.GetMutex());
-    
-    for (size_t image_index = 0, end_index = target_modules.GetSize();
-         image_index < end_index;
-         ++image_index)
-    {
-        Module *image = target_modules.GetModulePointerAtIndexUnlocked(image_index);
-        
-        if (!image)
-            continue;
-        
-        SymbolVendor *symbol_vendor = image->GetSymbolVendor();
-        
-        if (!symbol_vendor)
-            continue;
-        
-        SymbolFile *symbol_file = image->GetSymbolVendor()->GetSymbolFile();
-        
-        // Don't use a symbol file if it actually has types. We are specifically
-        // looking for something in runtime information, not from debug information,
-        // as the data in debug information will get parsed by the debug info
-        // symbol files. So we veto any symbol file that has actual variable
-        // type parsing abilities.
-        if (symbol_file == NULL || (symbol_file->GetAbilities() & SymbolFile::VariableTypes))
-            continue;
-        
-        const bool inferior_append = true;
-        
-        ret += symbol_file->FindTypes (sc, name, namespace_decl, inferior_append, max_matches - ret, types);
-        
-        if (ret >= max_matches)
-            break;
-    }
-    
-    return ret;
-}

Removed: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h?rev=163650&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h (removed)
@@ -1,47 +0,0 @@
-//===-- AppleObjCSymbolVendor.h ---------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_AppleObjCSymbolVendor_h_
-#define liblldb_AppleObjCSymbolVendor_h_
-
-// C Includes
-// C++ Includes
-
-#include <map>
-
-// Other libraries and framework includes
-// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/SymbolVendor.h"
-#include "lldb/Symbol/SymbolFile.h"
-
-namespace lldb_private {
-    
-class AppleObjCSymbolVendor : public SymbolVendor
-{
-public:
-    AppleObjCSymbolVendor(Process* process);
-    
-    virtual uint32_t
-    FindTypes (const SymbolContext& sc, 
-               const ConstString &name,
-               const ClangNamespaceDecl *namespace_decl, 
-               bool append, 
-               uint32_t max_matches, 
-               TypeList& types);
-    
-private:
-    lldb::ProcessSP                     m_process;
-    ClangASTContext                     m_ast_ctx;
-};
-
-} // namespace lldb_private
-
-#endif  // liblldb_AppleObjCSymbolVendor_h_

Copied: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp (from r163149, lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp?p2=lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp&p1=lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp&r1=163149&r2=163651&rev=163651&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp Tue Sep 11 16:44:01 2012
@@ -7,77 +7,192 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "AppleObjCSymbolVendor.h"
+#include "AppleObjCTypeVendor.h"
 
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Expression/ASTDumper.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
 
 using namespace lldb_private;
 
-AppleObjCSymbolVendor::AppleObjCSymbolVendor(Process *process) :
-    SymbolVendor(lldb::ModuleSP()),
-    m_process(process->shared_from_this()),
-    m_ast_ctx(process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str())
+class lldb_private::AppleObjCExternalASTSource : public ClangExternalASTSourceCommon
 {
+public:
+    AppleObjCExternalASTSource (AppleObjCTypeVendor &type_vendor) :
+        m_type_vendor(type_vendor)
+    {
+    }
+    
+    clang::DeclContextLookupResult
+    FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
+                                    clang::DeclarationName Name)
+    {
+        return clang::DeclContextLookupResult();
+    }
+    
+    clang::ExternalLoadResult
+    FindExternalLexicalDecls (const clang::DeclContext *DC,
+                              bool (*isKindWeWant)(clang::Decl::Kind),
+                              llvm::SmallVectorImpl<clang::Decl*> &Decls)
+    {
+        return clang::ELR_Success;
+    }
+    
+    void
+    CompleteType (clang::TagDecl *Tag)
+    {
+        return;
+    }
+    
+    void
+    CompleteType (clang::ObjCInterfaceDecl *Class)
+    {
+        return;
+    }
+    
+    bool
+    layoutRecordType(const clang::RecordDecl *Record,
+                     uint64_t &Size,
+                     uint64_t &Alignment,
+                     llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets,
+                     llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+                     llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets)
+    {
+        return false;
+    }
+    
+    void StartTranslationUnit (clang::ASTConsumer *Consumer)
+    {
+        clang::TranslationUnitDecl *translation_unit_decl = m_type_vendor.m_ast_ctx.getASTContext()->getTranslationUnitDecl();
+        translation_unit_decl->setHasExternalVisibleStorage();
+        translation_unit_decl->setHasExternalLexicalStorage();
+    }
+private:
+    AppleObjCTypeVendor &m_type_vendor;
+};
+
+AppleObjCTypeVendor::AppleObjCTypeVendor(ObjCLanguageRuntime &runtime) :
+    TypeVendor(),
+    m_runtime(runtime),
+    m_ast_ctx(runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple().getTriple().c_str())
+{
+    m_external_source = new AppleObjCExternalASTSource (*this);
+    llvm::OwningPtr<clang::ExternalASTSource> external_source_owning_ptr (m_external_source);
+    m_ast_ctx.getASTContext()->setExternalSource(external_source_owning_ptr);
 }
 
 uint32_t
-AppleObjCSymbolVendor::FindTypes (const SymbolContext& sc, 
-                                  const ConstString &name,
-                                  const ClangNamespaceDecl *namespace_decl, 
-                                  bool append, 
-                                  uint32_t max_matches, 
-                                  TypeList& types)
+AppleObjCTypeVendor::FindTypes (const ConstString &name,
+                                bool append,
+                                uint32_t max_matches,
+                                std::vector <ClangASTType> &types)
 {
-    lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));  // FIXME - a more appropriate log channel?
-        
+    static unsigned int invocation_id = 0;
+    unsigned int current_id = invocation_id++;
+    
+    lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));  // FIXME - a more appropriate log channel?
+    
     if (log)
-        log->Printf("ObjC SymbolVendor asked for '%s'", 
-                    name.AsCString());
+        log->Printf("AppleObjCTypeVendor::FindTypes [%u] ('%s', %s, %u, )",
+                    current_id,
+                    (const char*)name.AsCString(),
+                    append ? "true" : "false",
+                    max_matches);
     
     if (!append)
-        types.Clear();
+        types.clear();
     
     uint32_t ret = 0;
     
-    ModuleList &target_modules = m_process->GetTarget().GetImages();
-    Mutex::Locker modules_locker(target_modules.GetMutex());
-    
-    for (size_t image_index = 0, end_index = target_modules.GetSize();
-         image_index < end_index;
-         ++image_index)
+    do
     {
-        Module *image = target_modules.GetModulePointerAtIndexUnlocked(image_index);
-        
-        if (!image)
-            continue;
+        // See if the type is already in our ASTContext.
         
-        SymbolVendor *symbol_vendor = image->GetSymbolVendor();
+        clang::ASTContext *ast_ctx = m_ast_ctx.getASTContext();
         
-        if (!symbol_vendor)
-            continue;
+        clang::IdentifierInfo &identifier_info = ast_ctx->Idents.get(name.GetStringRef());
+        clang::DeclarationName decl_name = ast_ctx->DeclarationNames.getIdentifier(&identifier_info);
         
-        SymbolFile *symbol_file = image->GetSymbolVendor()->GetSymbolFile();
+        clang::DeclContext::lookup_const_result lookup_result = ast_ctx->getTranslationUnitDecl()->lookup(decl_name);
         
-        // Don't use a symbol file if it actually has types. We are specifically
-        // looking for something in runtime information, not from debug information,
-        // as the data in debug information will get parsed by the debug info
-        // symbol files. So we veto any symbol file that has actual variable
-        // type parsing abilities.
-        if (symbol_file == NULL || (symbol_file->GetAbilities() & SymbolFile::VariableTypes))
-            continue;
+        if (lookup_result.first != lookup_result.second)
+        {
+            if (const clang::ObjCInterfaceDecl *result_iface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(*lookup_result.first))
+            {
+                clang::QualType result_iface_type = ast_ctx->getObjCInterfaceType(result_iface_decl);
+                
+                if (log)
+                {
+                    ASTDumper dumper(result_iface_type);
+                    log->Printf("AOCTV::FT [%u] Found %s (isa 0x%llx) in the ASTContext",
+                                current_id,
+                                dumper.GetCString(),
+                                m_external_source->GetMetadata((uintptr_t)result_iface_decl));
+                }
+                    
+                types.push_back(ClangASTType(ast_ctx, result_iface_type.getAsOpaquePtr()));
+                ret++;
+                break;
+            }
+            else
+            {
+                if (log)
+                    log->Printf("AOCTV::FT [%u] There's something in the ASTContext, but it's not something we know about",
+                                current_id);
+                break;
+            }
+        }
+        else if(log)
+        {
+            log->Printf("AOCTV::FT [%u] Couldn't find %s in the ASTContext",
+                        current_id,
+                        name.AsCString());
+        }
         
-        const bool inferior_append = true;
+        // It's not.  If it exists, we have to put it into our ASTContext.
         
-        ret += symbol_file->FindTypes (sc, name, namespace_decl, inferior_append, max_matches - ret, types);
+        // TODO Actually do this.  But we have to search the class list first.  Until then we'll just give up.
+        break;
         
-        if (ret >= max_matches)
+        ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name);
+    
+        if (!isa)
+        {
+            if (log)
+                log->Printf("AOCTV::FT [%u] Couldn't find the isa",
+                            current_id);
+            
             break;
-    }
+        }
+        
+        clang::ObjCInterfaceDecl *new_iface_decl = clang::ObjCInterfaceDecl::Create(*ast_ctx,
+                                                                                    ast_ctx->getTranslationUnitDecl(),
+                                                                                    clang::SourceLocation(),
+                                                                                    &identifier_info,
+                                                                                    NULL);
+        
+        m_external_source->SetMetadata((uintptr_t)new_iface_decl, (uint64_t)isa);
+        
+        new_iface_decl->setHasExternalVisibleStorage();
+        
+        clang::QualType new_iface_type = ast_ctx->getObjCInterfaceType(new_iface_decl);
+        
+        if (log)
+        {
+            ASTDumper dumper(new_iface_type);
+            log->Printf("AOCTV::FT [%u] Created %s (isa 0x%llx)",
+                        current_id,
+                        dumper.GetCString(),
+                        (uint64_t)isa);
+        }
+    } while (0);
     
     return ret;
 }

Copied: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h (from r163149, lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h?p2=lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h&p1=lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h&r1=163149&r2=163651&rev=163651&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h Tue Sep 11 16:44:01 2012
@@ -16,30 +16,32 @@
 #include <map>
 
 // Other libraries and framework includes
+
 // Project includes
 #include "lldb/lldb-private.h"
 #include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/SymbolVendor.h"
-#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/TypeVendor.h"
 
 namespace lldb_private {
+
+class AppleObjCExternalASTSource;
     
-class AppleObjCSymbolVendor : public SymbolVendor
+class AppleObjCTypeVendor : public TypeVendor
 {
 public:
-    AppleObjCSymbolVendor(Process* process);
+    AppleObjCTypeVendor(ObjCLanguageRuntime &runtime);
     
     virtual uint32_t
-    FindTypes (const SymbolContext& sc, 
-               const ConstString &name,
-               const ClangNamespaceDecl *namespace_decl, 
-               bool append, 
-               uint32_t max_matches, 
-               TypeList& types);
+    FindTypes (const ConstString &name,
+               bool append,
+               uint32_t max_matches,
+               std::vector <ClangASTType> &types);
     
+    friend class AppleObjCExternalASTSource;
 private:
-    lldb::ProcessSP                     m_process;
-    ClangASTContext                     m_ast_ctx;
+    ObjCLanguageRuntime            &m_runtime;
+    ClangASTContext                 m_ast_ctx;
+    AppleObjCExternalASTSource   *m_external_source;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/source/Target/ObjCLanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ObjCLanguageRuntime.cpp?rev=163651&r1=163650&r2=163651&view=diff
==============================================================================
--- lldb/trunk/source/Target/ObjCLanguageRuntime.cpp (original)
+++ lldb/trunk/source/Target/ObjCLanguageRuntime.cpp Tue Sep 11 16:44:01 2012
@@ -281,6 +281,16 @@
 }
 
 ObjCLanguageRuntime::ObjCISA
+ObjCLanguageRuntime::GetISA(const ConstString &name)
+{
+    for (const ISAToDescriptorMap::value_type &val : m_isa_to_descriptor_cache)
+        if (val.second && val.second->GetClassName() == name)
+            return val.first;
+    
+    return 0;
+}
+
+ObjCLanguageRuntime::ObjCISA
 ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
 {
     if (!IsValidISA(isa))





More information about the lldb-commits mailing list