[Lldb-commits] [lldb] r121722 - in /lldb/trunk: include/lldb/Core/ include/lldb/Expression/ include/lldb/Symbol/ include/lldb/Target/ source/Expression/ source/Plugins/ABI/MacOSX-i386/ source/Plugins/ABI/SysV-x86_64/ source/Symbol/ source/Target/

Sean Callanan scallanan at apple.com
Mon Dec 13 14:46:15 PST 2010


Author: spyffe
Date: Mon Dec 13 16:46:15 2010
New Revision: 121722

URL: http://llvm.org/viewvc/llvm-project?rev=121722&view=rev
Log:
Added support for generating expressions that have
access to the members of the Objective-C self object.

The approach we take is to generate the method as a
@category on top of the self object, and to pass the
"self" pointer to it.  (_cmd is currently NULL.)

Most changes are in ClangExpressionDeclMap, but the
change that adds support to the ABIs to pass _cmd
touches a fair amount of code.

Modified:
    lldb/trunk/include/lldb/Core/ClangForward.h
    lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h
    lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
    lldb/trunk/include/lldb/Expression/ClangFunction.h
    lldb/trunk/include/lldb/Symbol/ClangASTType.h
    lldb/trunk/include/lldb/Target/ABI.h
    lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h
    lldb/trunk/include/lldb/Target/ThreadPlanCallUserExpression.h
    lldb/trunk/source/Expression/ASTResultSynthesizer.cpp
    lldb/trunk/source/Expression/ClangASTSource.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/ClangFunction.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Expression/IRForTarget.cpp
    lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
    lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
    lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
    lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
    lldb/trunk/source/Symbol/ClangASTType.cpp
    lldb/trunk/source/Target/ThreadPlanCallFunction.cpp
    lldb/trunk/source/Target/ThreadPlanCallUserExpression.cpp

Modified: lldb/trunk/include/lldb/Core/ClangForward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ClangForward.h?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ClangForward.h (original)
+++ lldb/trunk/include/lldb/Core/ClangForward.h Mon Dec 13 16:46:15 2010
@@ -34,6 +34,7 @@
     class CodeGenOptions;
     class CodeGenerator;
     class CompilerInstance;
+    class CompoundStmt;
     class CXXBaseSpecifier;
     class CXXBoolLiteralExpr;
     class CXXFunctionalCastExpr;

Modified: lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h (original)
+++ lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h Mon Dec 13 16:46:15 2010
@@ -123,12 +123,31 @@
     void TransformTopLevelDecl(clang::Decl *D);
     
     //----------------------------------------------------------------------
+    /// Process an Objective-C method and produce the result variable and
+    /// initialization
+    ///
+    /// @param[in] MethodDecl
+    ///     The method to process.
+    //----------------------------------------------------------------------
+    bool SynthesizeObjCMethodResult(clang::ObjCMethodDecl *MethodDecl);
+    
+    //----------------------------------------------------------------------
     /// Process a function and produce the result variable and initialization
     ///
     /// @param[in] FunDecl
     ///     The function to process.
     //----------------------------------------------------------------------
-    bool SynthesizeResult(clang::FunctionDecl *FunDecl);
+    bool SynthesizeFunctionResult(clang::FunctionDecl *FunDecl);
+    
+    //----------------------------------------------------------------------
+    /// Process a functionbody and produce the result variable and 
+    /// initialization
+    ///
+    /// @param[in] Body
+    ///     The body of the function.
+    //----------------------------------------------------------------------
+    bool SynthesizeBodyResult(clang::CompoundStmt *Body,
+                              clang::DeclContext *DC);
     
     clang::ASTContext *m_ast_context;           ///< The AST context to use for identifiers and types.
     clang::ASTConsumer *m_passthrough;          ///< The ASTConsumer down the chain, for passthrough.  NULL if it's a SemaConsumer.

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Mon Dec 13 16:46:15 2010
@@ -291,6 +291,10 @@
     /// @param[out] object_ptr
     ///     The this pointer.
     ///
+    /// @param[in] object_name
+    ///     The name of the object pointer -- "this," "self," or similar
+    ///     depending on language
+    ///
     /// @param[in] exe_ctx
     ///     The execution context at which to dump the struct.
     ///
@@ -302,6 +306,7 @@
     ///     True on success; false otherwise.
     //------------------------------------------------------------------
     bool GetObjectPointer(lldb::addr_t &object_ptr,
+                          ConstString &object_name,
                           ExecutionContext &exe_ctx,
                           Error &error);
     

Modified: lldb/trunk/include/lldb/Expression/ClangFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangFunction.h?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangFunction.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangFunction.h Mon Dec 13 16:46:15 2010
@@ -423,8 +423,13 @@
     ///     True if the thread plan may simply be discarded if an error occurs.
     ///
     /// @param[in] this_arg
-    ///     If non-NULL, the function is invoked like a C++ method, with the
-    ///     value pointed to by the pointer as its 'this' argument.
+    ///     If non-NULL (and cmd_arg is NULL), the function is invoked like a C++ 
+    ///     method, with the value pointed to by the pointer as its 'this' 
+    ///     argument.
+    ///
+    /// @param[in] cmd_arg
+    ///     If non-NULL, the function is invoked like an Objective-C method, with
+    ///     this_arg in the 'self' slot and cmd_arg in the '_cmd' slot
     ///
     /// @return
     ///     A ThreadPlan for executing the function.
@@ -436,7 +441,8 @@
                                  Stream &errors, 
                                  bool stop_others, 
                                  bool discard_on_error,
-                                 lldb::addr_t *this_arg = 0);
+                                 lldb::addr_t *this_arg = 0,
+                                 lldb::addr_t *cmd_arg = 0);
     
     //------------------------------------------------------------------
     /// Get a thread plan to run the function this ClangFunction was created with.

Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTType.h?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTType.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTType.h Mon Dec 13 16:46:15 2010
@@ -162,6 +162,12 @@
     DumpTypeDescription (clang::ASTContext *ast_context,
                          lldb::clang_type_t opaque_clang_qual_type,
                          Stream *s);
+    
+    void DumpTypeCode (Stream *s);
+    
+    static void
+    DumpTypeCode (void *type,
+                  Stream *s);
                          
     lldb::Encoding
     GetEncoding (uint32_t &count);                 

Modified: lldb/trunk/include/lldb/Target/ABI.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ABI.h?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ABI.h (original)
+++ lldb/trunk/include/lldb/Target/ABI.h Mon Dec 13 16:46:15 2010
@@ -35,7 +35,8 @@
                         lldb::addr_t functionAddress,
                         lldb::addr_t returnAddress, 
                         lldb::addr_t arg,
-                        lldb::addr_t *this_arg) const = 0;
+                        lldb::addr_t *this_arg,
+                        lldb::addr_t *cmd_arg) const = 0;
     
     virtual bool
     GetArgumentValues (Thread &thread,

Modified: lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h Mon Dec 13 16:46:15 2010
@@ -28,7 +28,8 @@
                             lldb::addr_t arg,
                             bool stop_other_threads,
                             bool discard_on_error = true,
-                            lldb::addr_t *this_arg = 0);
+                            lldb::addr_t *this_arg = 0,
+                            lldb::addr_t *cmd_arg = 0);
     
     virtual
     ~ThreadPlanCallFunction ();

Modified: lldb/trunk/include/lldb/Target/ThreadPlanCallUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanCallUserExpression.h?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanCallUserExpression.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanCallUserExpression.h Mon Dec 13 16:46:15 2010
@@ -31,6 +31,7 @@
                             bool stop_other_threads,
                             bool discard_on_error,
                             lldb::addr_t *this_arg,
+                            lldb::addr_t *cmd_arg,
                             ClangUserExpression::ClangUserExpressionSP &user_expression_sp);
     
     virtual

Modified: lldb/trunk/source/Expression/ASTResultSynthesizer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ASTResultSynthesizer.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ASTResultSynthesizer.cpp (original)
+++ lldb/trunk/source/Expression/ASTResultSynthesizer.cpp Mon Dec 13 16:46:15 2010
@@ -12,6 +12,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Stmt.h"
 #include "clang/Parse/Parser.h"
@@ -54,9 +55,23 @@
 void
 ASTResultSynthesizer::TransformTopLevelDecl(Decl* D)
 {
-    LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D);
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D))
+    {
+        if (log)
+        {
+            if (named_decl->getIdentifier())
+                log->Printf("TransformTopLevelDecl(%s)", named_decl->getIdentifier()->getNameStart());
+            else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
+                log->Printf("TransformTopLevelDecl(%s)", method_decl->getSelector().getAsString().c_str());
+            else
+                log->Printf("TransformTopLevelDecl(<complex>)");
+        }
+
+    }
     
-    if (linkage_spec_decl)
+    if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D))
     {
         RecordDecl::decl_iterator decl_iterator;
         
@@ -67,14 +82,21 @@
             TransformTopLevelDecl(*decl_iterator);
         }
     }
-    
-    FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D);
-    
-    if (m_ast_context &&
-        function_decl &&
-        !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
+    else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
     {
-        SynthesizeResult(function_decl);
+        if (m_ast_context &&
+            !method_decl->getSelector().getAsString().compare("$__lldb_expr:"))
+        {
+            SynthesizeObjCMethodResult(method_decl);
+        }
+    }
+    else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D))
+    {
+        if (m_ast_context &&
+            !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
+        {
+            SynthesizeFunctionResult(function_decl);
+        }
     }
 }
 
@@ -97,15 +119,15 @@
 }
 
 bool 
-ASTResultSynthesizer::SynthesizeResult (FunctionDecl *FunDecl)
+ASTResultSynthesizer::SynthesizeFunctionResult (FunctionDecl *FunDecl)
 {
-    ASTContext &Ctx(*m_ast_context);
-    
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
+    ASTContext &Ctx(*m_ast_context);
+
     if (!m_sema)
         return false;
-
+    
     FunctionDecl *function_decl = FunDecl;
     
     if (!function_decl)
@@ -126,6 +148,80 @@
     Stmt *function_body = function_decl->getBody();
     CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
     
+    bool ret = SynthesizeBodyResult (compound_stmt,
+                                     function_decl);
+    
+    if (log)
+    {
+        std::string s;
+        raw_string_ostream os(s);
+        
+        function_decl->print(os);
+        
+        os.flush();
+        
+        log->Printf("Transformed function AST:\n%s", s.c_str());
+    }
+    
+    return ret;
+}
+
+bool
+ASTResultSynthesizer::SynthesizeObjCMethodResult (ObjCMethodDecl *MethodDecl)
+{
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    
+    ASTContext &Ctx(*m_ast_context);
+    
+    if (!m_sema)
+        return false;
+        
+    if (!MethodDecl)
+        return false;
+    
+    if (log)
+    {
+        std::string s;
+        raw_string_ostream os(s);
+        
+        Ctx.getTranslationUnitDecl()->print(os);
+        
+        os.flush();
+        
+        log->Printf("AST context before transforming:\n%s", s.c_str());
+    }
+    
+    Stmt *method_body = MethodDecl->getBody();
+    CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body);
+    
+    bool ret = SynthesizeBodyResult (compound_stmt,
+                                     MethodDecl);
+    
+    if (log)
+    {
+        std::string s;
+        raw_string_ostream os(s);
+        
+        MethodDecl->print(os);
+        
+        os.flush();
+        
+        log->Printf("Transformed function AST:\n%s", s.c_str());
+    }
+    
+    return ret;
+}
+
+bool 
+ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body, 
+                                            DeclContext *DC)
+{
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    
+    ASTContext &Ctx(*m_ast_context);
+    
+    CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(Body);
+    
     if (!compound_stmt)
         return false;
     
@@ -169,7 +265,7 @@
     IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result");
         
     clang::VarDecl *result_decl = VarDecl::Create(Ctx, 
-                                                  function_decl, 
+                                                  DC, 
                                                   SourceLocation(), 
                                                   &result_id, 
                                                   expr_qual_type, 
@@ -180,7 +276,7 @@
     if (!result_decl)
         return false;
     
-    function_decl->addDecl(result_decl);
+    DC->addDecl(result_decl);
     
     ///////////////////////////////
     // call AddInitializerToDecl
@@ -210,18 +306,6 @@
     
     *last_stmt_ptr = reinterpret_cast<Stmt*>(result_initialization_stmt_result.take());
 
-    if (log)
-    {
-        std::string s;
-        raw_string_ostream os(s);
-        
-        function_decl->print(os);
-        
-        os.flush();
-        
-        log->Printf("Transformed function AST:\n%s", s.c_str());
-    }
-    
     return true;
 }
 

Modified: lldb/trunk/source/Expression/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangASTSource.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Expression/ClangASTSource.cpp Mon Dec 13 16:46:15 2010
@@ -227,6 +227,14 @@
         
         return tag_decl;
     }
+    else if (ObjCObjectType *objc_object_type = dyn_cast<clang::ObjCObjectType>(qual_type))
+    {
+        ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
+        
+        m_decls.push_back((NamedDecl*)interface_decl);
+        
+        return (NamedDecl*)interface_decl;
+    }
     else
     {
         return NULL;

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Mon Dec 13 16:46:15 2010
@@ -371,6 +371,7 @@
 ClangExpressionDeclMap::GetObjectPointer
 (
     lldb::addr_t &object_ptr,
+    ConstString &object_name,
     ExecutionContext &exe_ctx,
     Error &err
 )
@@ -389,12 +390,11 @@
         return false;
     }
     
-    static ConstString g_this_const_str ("this");
-    Variable *object_ptr_var = FindVariableInScope (*exe_ctx.frame, g_this_const_str, &m_struct_vars->m_object_pointer_type);
+    Variable *object_ptr_var = FindVariableInScope (*exe_ctx.frame, object_name, &m_struct_vars->m_object_pointer_type);
     
     if (!object_ptr_var)
     {
-        err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
+        err.SetErrorStringWithFormat("Couldn't find '%s' with appropriate type in scope", object_name.GetCString());
         return false;
     }
     
@@ -404,7 +404,7 @@
     
     if (!location_value.get())
     {
-        err.SetErrorString("Couldn't get the location for 'this'");
+        err.SetErrorStringWithFormat("Couldn't get the location for '%s'", object_name.GetCString());
         return false;
     }
     
@@ -417,7 +417,7 @@
         if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(), 
                                                m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
         {
-            err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
+            err.SetErrorStringWithFormat("'%s' is not of an expected pointer size", object_name.GetCString());
             return false;
         }
         
@@ -427,7 +427,7 @@
         
         if (exe_ctx.process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
         {
-            err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
+            err.SetErrorStringWithFormat("Coldn't read '%s' from the target: %s", object_name.GetCString(), read_error.AsCString());
             return false;
         }
         
@@ -441,7 +441,7 @@
     }
     else
     {
-        err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
+        err.SetErrorStringWithFormat("'%s' is not in memory; LLDB must be extended to handle registers", object_name.GetCString());
         return false;
     }
 }
@@ -1250,11 +1250,66 @@
             TypeFromUser class_user_type(pointer_target_type,
                                          this_type->GetClangAST());
 
+            if (log)
+            {
+                StreamString type_stream;
+                class_user_type.DumpTypeCode(&type_stream);
+                type_stream.Flush();
+                log->Printf("Adding type for $__lldb_class: %s", type_stream.GetString().c_str());
+            }
+            
             AddOneType(context, class_user_type, true);
             
             return;
         }
         
+        static ConstString g_lldb_objc_class_name ("$__lldb_objc_class");
+        if (name == g_lldb_objc_class_name)
+        {
+            // Clang is looking for the type of "*self"
+            
+            VariableList *vars = m_parser_vars->m_exe_ctx->frame->GetVariableList(false);
+
+            if (!vars)
+                return;
+        
+            lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
+        
+            if (!self_var)
+                return;
+        
+            Type *self_type = self_var->GetType();
+            
+            if (!self_type)
+                return;
+        
+            TypeFromUser self_user_type(self_type->GetClangType(),
+                                        self_type->GetClangAST());
+            
+            m_struct_vars->m_object_pointer_type = self_user_type;
+
+            void *pointer_target_type;
+        
+            if (!ClangASTContext::IsPointerType(self_user_type.GetOpaqueQualType(),
+                                                &pointer_target_type))
+                return;
+        
+            TypeFromUser class_user_type(pointer_target_type,
+                                         self_type->GetClangAST());
+            
+            if (log)
+            {
+                StreamString type_stream;
+                class_user_type.DumpTypeCode(&type_stream);
+                type_stream.Flush();
+                log->Printf("Adding type for $__lldb_objc_class: %s", type_stream.GetString().c_str());
+            }
+            
+            AddOneType(context, class_user_type, false);
+            
+            return;
+        }
+        
         ClangExpressionVariable *pvar(m_parser_vars->m_persistent_vars->GetVariable(name));
     
         if (pvar)

Modified: lldb/trunk/source/Expression/ClangFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangFunction.cpp Mon Dec 13 16:46:15 2010
@@ -372,7 +372,8 @@
                                             Stream &errors, 
                                             bool stop_others, 
                                             bool discard_on_error, 
-                                            lldb::addr_t *this_arg)
+                                            lldb::addr_t *this_arg,
+                                            lldb::addr_t *cmd_arg)
 {
     // FIXME: Use the errors Stream for better error reporting.
 
@@ -388,11 +389,12 @@
 
     Address wrapper_address (NULL, func_addr);
     ThreadPlan *new_plan = new ThreadPlanCallFunction (*exe_ctx.thread, 
-                                          wrapper_address,
-                                          args_addr,
-                                          stop_others, 
-                                          discard_on_error,
-                                          this_arg);
+                                                       wrapper_address,
+                                                       args_addr,
+                                                       stop_others, 
+                                                       discard_on_error,
+                                                       this_arg,
+                                                       cmd_arg);
     return new_plan;
 }
 

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Mon Dec 13 16:46:15 2010
@@ -174,6 +174,27 @@
         
         m_needs_object_ptr = true;
     }
+    else if(m_objectivec)
+    {
+        const char *function_name = FunctionName();
+        
+        m_transformed_stream.Printf("%s                                                     \n"
+                                    "@interface $__lldb_objc_class ($__lldb_category)       \n"
+                                    "-(void)%s:(void *)$__lldb_arg;                         \n"
+                                    "@end                                                   \n"
+                                    "@implementation $__lldb_objc_class ($__lldb_category)  \n"
+                                    "-(void)%s:(void *)$__lldb_arg                          \n"
+                                    "{                                                      \n"
+                                    "    %s;                                                \n"
+                                    "}                                                      \n"
+                                    "@end                                                   \n",
+                                    m_expr_prefix.c_str(),
+                                    function_name,
+                                    function_name,
+                                    m_expr_text.c_str());
+        
+        m_needs_object_ptr = true;
+    }
     else
     {
         m_transformed_stream.Printf("%s                             \n"
@@ -297,14 +318,31 @@
 
     if (m_jit_addr != LLDB_INVALID_ADDRESS)
     {
-        
         Error materialize_error;
         
-        
-        if (m_needs_object_ptr && !(m_expr_decl_map->GetObjectPointer(object_ptr, exe_ctx, materialize_error)))
+        if (m_needs_object_ptr)
         {
-            error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
-            return false;
+            ConstString object_name;
+            
+            if (m_cplusplus)
+            {
+                object_name.SetCString("this");
+            }
+            else if (m_objectivec)
+            {
+                object_name.SetCString("self");
+            }
+            else
+            {
+                error_stream.Printf("Need object pointer but don't know the language\n");
+                return false;
+            }
+            
+            if (!(m_expr_decl_map->GetObjectPointer(object_ptr, object_name, exe_ctx, materialize_error)))
+            {
+                error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
+                return false;
+            }
         }
                 
         if (!m_expr_decl_map->Materialize(exe_ctx, struct_address, materialize_error))
@@ -351,19 +389,22 @@
     lldb::addr_t struct_address;
             
     lldb::addr_t object_ptr = NULL;
+    lldb::addr_t cmd_ptr = NULL;
     
     PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr);
     
     // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the
     // ClangUserExpression resources before the thread plan finishes execution in the target.  But because we are 
-    // forcing unwind_on_error to be true here, in practical terms that can't happen.  
+    // forcing unwind_on_error to be true here, in practical terms that can't happen.
+    
     return ClangFunction::GetThreadPlanToCallFunction (exe_ctx, 
                                                        m_jit_addr, 
                                                        struct_address, 
                                                        error_stream,
                                                        true,
                                                        true, 
-                                                       (m_needs_object_ptr ? &object_ptr : NULL));
+                                                       (m_needs_object_ptr ? &object_ptr : NULL),
+                                                       (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
 }
 
 bool
@@ -423,17 +464,24 @@
         lldb::addr_t struct_address;
                 
         lldb::addr_t object_ptr = NULL;
+        lldb::addr_t cmd_ptr = NULL;
         
-        PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr);
+        if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr))
+            return Process::eExecutionSetupError;
         
         const bool stop_others = true;
         const bool try_all_threads = true;
         
         Address wrapper_address (NULL, m_jit_addr);
-        lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (*(exe_ctx.thread), wrapper_address, struct_address, 
-                                                                               stop_others, discard_on_error, 
-                                                                               (m_needs_object_ptr ? &object_ptr : NULL),
-                                                                               shared_ptr_to_me));
+        lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (*(exe_ctx.thread), 
+                                                                          wrapper_address, 
+                                                                          struct_address, 
+                                                                          stop_others, 
+                                                                          discard_on_error, 
+                                                                          (m_needs_object_ptr ? &object_ptr : NULL),
+                                                                          ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
+                                                                          shared_ptr_to_me));
+        
         if (call_plan_sp == NULL || !call_plan_sp->ValidatePlan (NULL))
             return Process::eExecutionSetupError;
     

Modified: lldb/trunk/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRForTarget.cpp (original)
+++ lldb/trunk/source/Expression/IRForTarget.cpp Mon Dec 13 16:46:15 2010
@@ -899,7 +899,7 @@
                 
         size_t value_size = (ast_context->getTypeSize(qual_type) + 7) / 8;
         off_t value_alignment = (ast_context->getTypeAlign(qual_type) + 7) / 8;
-                
+        
         if (log)
             log->Printf("Type of \"%s\" is [clang \"%s\", lldb \"%s\"] [size %d, align %d]", 
                         name.c_str(), 
@@ -907,7 +907,7 @@
                         PrintType(value_type).c_str(), 
                         value_size, 
                         value_alignment);
-
+        
         
         if (named_decl && !m_decl_map->AddValueToStruct(named_decl,
                                                         lldb_private::ConstString (name.c_str()),
@@ -1353,6 +1353,23 @@
         
         argument = iter;
     }
+    else if (argument->getName().equals("self"))
+    {
+        ++iter;
+        
+        if (iter == llvm_function.getArgumentList().end())
+            return false;
+        
+        if (!iter->getName().equals("_cmd"))
+            return false;
+        
+        ++iter;
+        
+        if (iter == llvm_function.getArgumentList().end())
+            return false;
+        
+        argument = iter;
+    }
     
     if (!argument->getName().equals("$__lldb_arg"))
         return false;
@@ -1430,7 +1447,11 @@
     //
     
     if (!CreateResultVariable(llvm_module, *function))
+    {
+        if (log)
+            log->Printf("CreateResultVariable() failed");
         return false;
+    }
     
     ///////////////////////////////////////////////////////////////////////////////
     // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
@@ -1449,7 +1470,11 @@
     }
     
     if (!RewriteObjCConstStrings(llvm_module, *function))
+    {
+        if (log)
+            log->Printf("RewriteObjCConstStrings() failed");
         return false;
+    }
     
     if (log)
     {
@@ -1472,16 +1497,32 @@
          ++bbi)
     {
         if (!RemoveGuards(llvm_module, *bbi))
+        {
+            if (log)
+                log->Printf("RemoveGuards() failed");
             return false;
+        }
         
         if (!RewritePersistentAllocs(llvm_module, *bbi))
+        {
+            if (log)
+                log->Printf("RewritePersistentAllocs() failed");
             return false;
+        }
         
         if (!RewriteObjCSelectors(llvm_module, *bbi))
+        {
+            if (log)
+                log->Printf("RewriteObjCSelectors() failed");
             return false;
+        }
 
         if (!ResolveCalls(llvm_module, *bbi))
+        {
+            if (log)
+                log->Printf("ResolveCalls() failed");
             return false;
+        }
     }
     
     ///////////////////////////////
@@ -1489,10 +1530,18 @@
     //
     
     if (!ResolveExternals(llvm_module, *function))
+    {
+        if (log)
+            log->Printf("ResolveExternals() failed");
         return false;
+    }
     
     if (!ReplaceVariables(llvm_module, *function))
+    {
+        if (log)
+            log->Printf("ReplaceVariables() failed");
         return false;
+    }
     
     if (log)
     {

Modified: lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp Mon Dec 13 16:46:15 2010
@@ -58,7 +58,8 @@
                                     lldb::addr_t functionAddress, 
                                     lldb::addr_t returnAddress, 
                                     lldb::addr_t arg,
-                                    lldb::addr_t *this_arg) const
+                                    lldb::addr_t *this_arg,
+                                    lldb::addr_t *cmd_arg) const
 {
     RegisterContext *reg_ctx = thread.GetRegisterContext();
     if (!reg_ctx)
@@ -73,7 +74,9 @@
     
     // Make room for the argument(s) on the stack
     
-    if (this_arg)
+    if (this_arg && cmd_arg)
+        sp -= 12;
+    else if (this_arg)
         sp -= 8;
     else
         sp -= 4;
@@ -86,6 +89,19 @@
     
     Error error;
     
+    if (this_arg && cmd_arg)
+    {
+        uint32_t cmd_argU32 = *cmd_arg & 0xffffffffull;
+        uint32_t this_argU32 = *this_arg & 0xffffffffull;
+        uint32_t argU32 = arg & 0xffffffffull;
+        
+        if (thread.GetProcess().WriteMemory(sp, &this_argU32, sizeof(this_argU32), error) != sizeof(this_argU32))
+            return false;
+        if (thread.GetProcess().WriteMemory(sp, &cmd_argU32, sizeof(cmd_argU32), error) != sizeof(cmd_argU32))
+            return false;
+        if (thread.GetProcess().WriteMemory(sp + 4, &argU32, sizeof(argU32), error) != sizeof(argU32))
+            return false;
+    }
     if (this_arg)
     {
         uint32_t this_argU32 = *this_arg & 0xffffffffull;

Modified: lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h Mon Dec 13 16:46:15 2010
@@ -35,7 +35,8 @@
                             lldb::addr_t functionAddress,
                             lldb::addr_t returnAddress, 
                             lldb::addr_t arg,
-                            lldb::addr_t *this_arg) const;
+                            lldb::addr_t *this_arg,
+                            lldb::addr_t *cmd_arg) const;
         
         virtual bool
         PrepareNormalCall (Thread &thread,

Modified: lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Mon Dec 13 16:46:15 2010
@@ -59,18 +59,22 @@
                                     lldb::addr_t functionAddress, 
                                     lldb::addr_t returnAddress, 
                                     lldb::addr_t arg,
-                                    lldb::addr_t *this_arg) const
+                                    lldb::addr_t *this_arg,
+                                    lldb::addr_t *cmd_arg) const
 {
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     if (log)
-        log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n  thread = %p\n  sp = 0x%llx\n  functionAddress = 0x%llx\n  returnAddress = 0x%llx\n  arg = 0x%llx\n  this_arg = %p(0x%llx)\n)",
+        log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n  thread = %p\n  sp = 0x%llx\n  functionAddress = 0x%llx\n  returnAddress = 0x%llx\n  arg = 0x%llx\n  this_arg = %p(0x%llx)\n  cmd_arg = %p(0x%llx)\n)",
                     (void*)&thread,
                     (uint64_t)sp,
                     (uint64_t)functionAddress,
                     (uint64_t)returnAddress,
                     (void*)arg,
-                    this_arg ? (uint64_t)*this_arg : (uint64_t)0);
+                    this_arg,
+                    this_arg ? (uint64_t)*this_arg : (uint64_t)0,
+                    cmd_arg,
+                    cmd_arg ? (uint64_t)*cmd_arg : (uint64_t)0);
     
     RegisterContext *reg_ctx = thread.GetRegisterContext();
     if (!reg_ctx)
@@ -88,6 +92,31 @@
 
     // The argument is in %rdi, and not on the stack.
     
+    if (cmd_arg)
+    {
+        if (log)
+            log->PutCString("The trivial call has a self and a _cmd pointer");
+        
+        uint32_t rsiID = reg_ctx->GetRegisterInfoByName("rsi", 0)->kinds[eRegisterKindLLDB];
+        uint32_t rdxID = reg_ctx->GetRegisterInfoByName("rdx", 0)->kinds[eRegisterKindLLDB];
+        
+        if (log)
+            log->Printf("About to write 'self' (0x%llx) into RDI", (uint64_t)*this_arg);
+        
+        if (!reg_ctx->WriteRegisterFromUnsigned(rdiID, *this_arg))
+            return false;
+        
+        if (log)
+            log->Printf("About to write '_cmd' (0x%llx) into RSI", (uint64_t)*cmd_arg);
+        
+        if (!reg_ctx->WriteRegisterFromUnsigned(rsiID, *this_arg))
+            return false;
+        
+        if (log)
+            log->Printf("About to write the argument (0x%llx) into RDX", (uint64_t)arg);
+        
+        if (!reg_ctx->WriteRegisterFromUnsigned(rdxID, arg))
+            return false;    }
     if (this_arg)
     {
         if (log)

Modified: lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h Mon Dec 13 16:46:15 2010
@@ -34,7 +34,8 @@
                         lldb::addr_t functionAddress,
                         lldb::addr_t returnAddress, 
                         lldb::addr_t arg,
-                        lldb::addr_t *this_arg) const;
+                        lldb::addr_t *this_arg,
+                        lldb::addr_t *cmd_arg) const;
     
     virtual bool
     PrepareNormalCall (Thread &thread,

Modified: lldb/trunk/source/Symbol/ClangASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTType.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTType.cpp Mon Dec 13 16:46:15 2010
@@ -928,6 +928,20 @@
     }
 }
 
+void
+ClangASTType::DumpTypeCode (Stream *s)
+{
+    DumpTypeCode(m_type, s);
+}
+
+void
+ClangASTType::DumpTypeCode (void *type, 
+                            Stream *s)
+{
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(type));
+    s->PutCString(qual_type.getAsString().c_str());
+}
+
 bool
 ClangASTType::GetValueAsScalar
 (

Modified: lldb/trunk/source/Target/ThreadPlanCallFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanCallFunction.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanCallFunction.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanCallFunction.cpp Mon Dec 13 16:46:15 2010
@@ -40,7 +40,8 @@
                                                 lldb::addr_t arg,
                                                 bool stop_other_threads,
                                                 bool discard_on_error,
-                                                lldb::addr_t *this_arg) :
+                                                lldb::addr_t *this_arg,
+                                                lldb::addr_t *cmd_arg) :
     ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
     m_valid (false),
     m_stop_other_threads (stop_other_threads),
@@ -86,7 +87,8 @@
                                  FunctionLoadAddr, 
                                  StartLoadAddr, 
                                  m_arg_addr,
-                                 this_arg))
+                                 this_arg,
+                                 cmd_arg))
         return;
     
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));

Modified: lldb/trunk/source/Target/ThreadPlanCallUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanCallUserExpression.cpp?rev=121722&r1=121721&r2=121722&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanCallUserExpression.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanCallUserExpression.cpp Mon Dec 13 16:46:15 2010
@@ -42,8 +42,9 @@
                                                 bool stop_other_threads,
                                                 bool discard_on_error,
                                                 lldb::addr_t *this_arg,
+                                                lldb::addr_t *cmd_arg,
                                                 ClangUserExpression::ClangUserExpressionSP &user_expression_sp) :
-    ThreadPlanCallFunction (thread, function, arg, stop_other_threads, discard_on_error, this_arg),
+    ThreadPlanCallFunction (thread, function, arg, stop_other_threads, discard_on_error, this_arg, cmd_arg),
     m_user_expression_sp (user_expression_sp)
 {
 }





More information about the lldb-commits mailing list