[Lldb-commits] [lldb] r164808 - in /lldb/trunk: include/lldb/Target/ObjCLanguageRuntime.h source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp

Sean Callanan scallanan at apple.com
Thu Sep 27 16:47:51 PDT 2012


Author: spyffe
Date: Thu Sep 27 18:47:51 2012
New Revision: 164808

URL: http://llvm.org/viewvc/llvm-project?rev=164808&view=rev
Log:
Improved the runtime reading to also get data
out of the metaclass, so as to enumerate class
methods for an object.

Modified:
    lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp

Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=164808&r1=164807&r2=164808&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Thu Sep 27 18:47:51 2012
@@ -119,7 +119,8 @@
         // This should return true iff the interface could be completed
         virtual bool
         Describe (std::function <void (ObjCISA)> const &superclass_func,
-                  std::function <void (const char*, const char*)> const &method_func)
+                  std::function <void (const char*, const char*)> const &instance_method_func,
+                  std::function <void (const char*, const char*)> const &class_method_func)
         {
             return false;
         }

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=164808&r1=164807&r2=164808&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Thu Sep 27 18:47:51 2012
@@ -973,7 +973,8 @@
 class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor
 {
 public:
-    ClassDescriptorV2 (ValueObject &ptr_to_object)
+    ClassDescriptorV2 (ObjCLanguageRuntime &runtime, ValueObject &ptr_to_object) :
+        m_runtime(runtime)
     {
         lldb::addr_t object_la = ptr_to_object.GetValueAsUnsigned(0);
         lldb::ProcessSP process_sp = ptr_to_object.GetProcessSP();
@@ -988,7 +989,8 @@
             Initialize (isa, process_sp);
     }
     
-    ClassDescriptorV2 (ObjCLanguageRuntime::ObjCISA isa, lldb::ProcessSP process_sp)
+    ClassDescriptorV2 (ObjCLanguageRuntime &runtime, ObjCLanguageRuntime::ObjCISA isa, lldb::ProcessSP process_sp) :
+        m_runtime(runtime)
     {
         Initialize (isa, process_sp);
     }
@@ -1008,10 +1010,7 @@
         if (!m_valid)
             return ObjCLanguageRuntime::ClassDescriptorSP();
         
-        ProcessSP process_sp = m_process_wp.lock();
-        if (!process_sp)
-            return ObjCLanguageRuntime::ClassDescriptorSP();
-        return AppleObjCRuntime::ClassDescriptorSP(new ClassDescriptorV2(m_objc_class.m_superclass,process_sp));
+        return m_runtime.GetClassDescriptor(m_objc_class.m_superclass);
     }
     
     virtual bool
@@ -1046,7 +1045,8 @@
     
     virtual bool
     Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
-              std::function <void (const char *, const char *)> const &method_func)
+              std::function <void (const char *, const char *)> const &instance_method_func,
+              std::function <void (const char *, const char *)> const &class_method_func)
     {
         if (!m_valid)
             return false;
@@ -1075,28 +1075,47 @@
             if (!ro->Read(process_sp, m_objc_class.m_data_la))
                 return false;
         }
+    
+        static ConstString NSObject_name("NSObject");
         
-        superclass_func(m_objc_class.m_superclass);
-        
-        std::auto_ptr <method_list_t> base_method_list;
-        
-        base_method_list.reset(new method_list_t);
-        if (!base_method_list->Read(process_sp, ro->m_baseMethods_la))
-            return false;
-        
-        if (base_method_list->m_entsize != method_t::GetSize(process_sp))
-            return false;
-        
-        std::auto_ptr <method_t> method;
-        method.reset(new method_t);
+        if (m_name != NSObject_name && superclass_func)
+            superclass_func(m_objc_class.m_superclass);
         
-        for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i)
+        if (instance_method_func)
         {
-            method->Read(process_sp, base_method_list->m_first_la + (i * base_method_list->m_entsize));
+            std::auto_ptr <method_list_t> base_method_list;
+            
+            base_method_list.reset(new method_list_t);
+            if (!base_method_list->Read(process_sp, ro->m_baseMethods_la))
+                return false;
             
-            method_func(method->m_name.c_str(), method->m_types.c_str());
+            if (base_method_list->m_entsize != method_t::GetSize(process_sp))
+                return false;
+            
+            std::auto_ptr <method_t> method;
+            method.reset(new method_t);
+            
+            for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i)
+            {
+                method->Read(process_sp, base_method_list->m_first_la + (i * base_method_list->m_entsize));
+                
+                instance_method_func(method->m_name.c_str(), method->m_types.c_str());
+            }
         }
         
+        if (class_method_func)
+        {
+            ObjCLanguageRuntime::ClassDescriptorSP metaclass = m_runtime.GetClassDescriptor(m_objc_class.m_isa);
+            
+            // We don't care about the metaclass's superclass, or its class methods.  Its instance methods are
+            // our class methods.
+            
+            metaclass->Describe(std::function <void (ObjCLanguageRuntime::ObjCISA)> (nullptr),
+                                class_method_func,
+                                std::function <void (const char *, const char *)> (nullptr));
+        }
+        while (0);
+            
         return true;
     }
     
@@ -1254,6 +1273,7 @@
 private:
     static const uint32_t RW_REALIZED = (1 << 31);
     
+    ObjCLanguageRuntime                &m_runtime;          // The runtime, so we can read our metaclass.
     bool                                m_valid;            // Gates whether we trust anything here at all.
     lldb::addr_t                        m_objc_class_la;    // The address of the objc_class_t.
     
@@ -1715,7 +1735,7 @@
     if (found != end && found->second)
         return found->second;
     
-    ClassDescriptorSP descriptor = ClassDescriptorSP(new ClassDescriptorV2(isa,m_process->CalculateProcess()));
+    ClassDescriptorSP descriptor = ClassDescriptorSP(new ClassDescriptorV2(*this, isa, m_process->CalculateProcess()));
     if (descriptor && descriptor->IsValid())
         m_isa_to_descriptor_cache[descriptor->GetISA()] = descriptor;
     return descriptor;
@@ -1740,7 +1760,7 @@
     
     if (ptr_value & 1)
         return ClassDescriptorSP(new ClassDescriptorV2Tagged(in_value)); // do not save tagged pointers
-    descriptor = ClassDescriptorSP(new ClassDescriptorV2(in_value));
+    descriptor = ClassDescriptorSP(new ClassDescriptorV2(*this, in_value));
     
     if (descriptor && descriptor->IsValid())
         m_isa_to_descriptor_cache[descriptor->GetISA()] = descriptor;
@@ -1832,7 +1852,7 @@
             if (m_isa_to_descriptor_cache.count(elt.second))
                 continue;
             
-            ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(elt.second, process_sp));
+            ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, elt.second, process_sp));
             
             if (log && log->GetVerbose())
                 log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%llx (%s) from dynamic table to isa->descriptor cache", elt.second, elt.first.AsCString());
@@ -1878,7 +1898,7 @@
             if (m_isa_to_descriptor_cache.count(objc_isa))
                 continue;
             
-            ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(objc_isa, process_sp));
+            ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, objc_isa, process_sp));
             
             if (log && log->GetVerbose())
                 log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%llx (%s) from static table to isa->descriptor cache", objc_isa, descriptor_sp->GetClassName().AsCString());

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp?rev=164808&r1=164807&r2=164808&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp Thu Sep 27 18:47:51 2012
@@ -194,10 +194,7 @@
     
     m_external_source->SetMetadata((uintptr_t)new_iface_decl, (uint64_t)isa);
     
-    static ConstString NSObject_name("NSObject");
-    
-    if (name != NSObject_name)
-        new_iface_decl->setHasExternalVisibleStorage();
+    new_iface_decl->setHasExternalVisibleStorage();
     
     ast_ctx->getTranslationUnitDecl()->addDecl(new_iface_decl);
     
@@ -319,7 +316,7 @@
         }
     }
     
-    clang::ObjCMethodDecl *BuildMethod (clang::ObjCInterfaceDecl *interface_decl, const char *name)
+    clang::ObjCMethodDecl *BuildMethod (clang::ObjCInterfaceDecl *interface_decl, const char *name, bool instance)
     {
         lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));  // FIXME - a more appropriate log channel?
         
@@ -330,7 +327,7 @@
         
         clang::QualType return_qual_type;
         
-        const bool isInstance = true;
+        const bool isInstance = instance;
         const bool isVariadic = false;
         const bool isSynthesized = false;
         const bool isImplicitlyDeclared = true;
@@ -516,17 +513,27 @@
         interface_decl->setSuperClass(superclass_decl);
     };
     
-    auto method_func = [log, interface_decl, this](const char *name, const char *types)
+    auto instance_method_func = [log, interface_decl, this](const char *name, const char *types)
     {        
         ObjCRuntimeMethodType method_type(types);
         
-        clang::ObjCMethodDecl *method_decl = method_type.BuildMethod (interface_decl, name);
+        clang::ObjCMethodDecl *method_decl = method_type.BuildMethod (interface_decl, name, true);
+        
+        if (method_decl)
+            interface_decl->addDecl(method_decl);
+    };
+    
+    auto class_method_func = [log, interface_decl, this](const char *name, const char *types)
+    {
+        ObjCRuntimeMethodType method_type(types);
+        
+        clang::ObjCMethodDecl *method_decl = method_type.BuildMethod (interface_decl, name, false);
         
         if (method_decl)
             interface_decl->addDecl(method_decl);
     };
     
-    if (!descriptor->Describe(superclass_func, method_func))
+    if (!descriptor->Describe(superclass_func, instance_method_func, class_method_func))
         return false;
     
     if (log)





More information about the lldb-commits mailing list