[lldb-dev] [RFC} [Patch] SBFunction::ExecuteFunction (v3)

Carlo Kok ck at remobjects.com
Wed Oct 15 00:21:43 PDT 2014



jingham at apple.com schreef op 10/14/2014 om 7:34 PM:

>>
>> Does this actually get returned for anything else? the
>> SBTypeMemberFunction? If it is I'm not sure how to call this for
>> other languages. I'll rename them to ExecuteObjcFunction and put a
>> check in it for the next version of this patch.
>
> Even if only ObjC returns this now, there's nothing anywhere that
> says that is true, so it's better to be explicit...
>
> And it would be great to add a test case too!

all done & attached.

>
> Thanks for working on this, I think it will be useful. >
> Jim

That part is going to be a bit trickier. I work on windows and afaik the 
test system doesn't work on Windows, at least I couldn't get it to work.

-- 
Carlo Kok
RemObjects Software
-------------- next part --------------
Index: include/lldb/API/SBExpressionOptions.h
===================================================================
--- include/lldb/API/SBExpressionOptions.h	(revision 219490)
+++ include/lldb/API/SBExpressionOptions.h	(working copy)
@@ -118,6 +118,8 @@
     friend class SBFrame;
     friend class SBValue;
     friend class SBTarget;
+    friend class SBTypeMemberFunction;
+    friend class SBFunction;
 
 private:
     // This auto_pointer is made in the constructor and is always valid.
Index: include/lldb/API/SBFrame.h
===================================================================
--- include/lldb/API/SBFrame.h	(revision 219490)
+++ include/lldb/API/SBFrame.h	(working copy)
@@ -210,6 +210,8 @@
     friend class SBInstruction;
     friend class SBThread;
     friend class SBValue;
+    friend class SBTypeMemberFunction;
+    friend class SBFunction;
 #ifndef LLDB_DISABLE_PYTHON
     friend class lldb_private::ScriptInterpreterPython;
 #endif
Index: include/lldb/API/SBFunction.h
===================================================================
--- include/lldb/API/SBFunction.h	(revision 219490)
+++ include/lldb/API/SBFunction.h	(working copy)
@@ -68,6 +68,12 @@
     bool
     GetDescription (lldb::SBStream &description);
 
+    lldb::SBValue ExecuteFunction(lldb::SBFrame &frame,
+                                  lldb::SBValueList arguments,
+                                  lldb::SBExpressionOptions options,
+                                  bool reusable);
+
+    void RemoveReusableFunction (lldb::SBTarget &target);
 protected:
 
     lldb_private::Function *
Index: include/lldb/API/SBTarget.h
===================================================================
--- include/lldb/API/SBTarget.h	(revision 219490)
+++ include/lldb/API/SBTarget.h	(working copy)
@@ -942,6 +942,7 @@
     friend class SBSourceManager;
     friend class SBSymbol;
     friend class SBValue;
+    friend class SBTypeMemberFunction;
 
     //------------------------------------------------------------------
     // Constructors are private, use static Target::Create function to
Index: include/lldb/API/SBType.h
===================================================================
--- include/lldb/API/SBType.h	(revision 219490)
+++ include/lldb/API/SBType.h	(working copy)
@@ -104,7 +104,14 @@
     bool
     GetDescription (lldb::SBStream &description,
                     lldb::DescriptionLevel description_level);
-    
+
+    lldb::SBValue ExecuteObjCFunction (lldb::SBFrame &frame,
+                                   lldb::SBValue self,
+                                   lldb::SBValueList arguments,
+                                   lldb::SBExpressionOptions options,
+                                   bool reusable);
+
+    void RemoveReusableObjCFunction (lldb::SBTarget& target);
 protected:
     friend class SBType;
     
Index: include/lldb/API/SBValueList.h
===================================================================
--- include/lldb/API/SBValueList.h	(revision 219490)
+++ include/lldb/API/SBValueList.h	(working copy)
@@ -59,6 +59,7 @@
 
 private:
     friend class SBFrame;
+    friend class SBTypeMemberFunction;
     
     SBValueList (const ValueListImpl *lldb_object_ptr);
 
Index: include/lldb/Expression/ClangFunction.h
===================================================================
--- include/lldb/Expression/ClangFunction.h	(revision 219490)
+++ include/lldb/Expression/ClangFunction.h	(working copy)
@@ -23,6 +23,7 @@
 #include "lldb/Core/ValueObjectList.h"
 #include "lldb/Expression/ClangExpression.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Target/ExecutionContext.h"
 
 namespace lldb_private
 {
@@ -133,7 +134,7 @@
     /// @return
     ///     The number of errors.
     //------------------------------------------------------------------
-    unsigned
+    virtual unsigned
     CompileFunction (Stream &errors);
     
     //------------------------------------------------------------------
@@ -406,7 +407,13 @@
     {
         return m_arg_values;
     }
-private:
+
+    Address
+    GetFunctionAddress() const
+    {
+        return m_function_addr;
+    }
+protected:
     //------------------------------------------------------------------
     // For ClangFunction only
     //------------------------------------------------------------------
@@ -443,6 +450,76 @@
     bool                            m_JITted;                       ///< True if the wrapper function has already been JIT-compiled.
 };
 
+class ClangFunctionWithDeclMap : public ClangFunction
+{
+public:
+    //------------------------------------------------------------------
+    /// Constructor
+    ///
+    /// @param[in] exe_scope
+    ///     An execution context scope that gets us at least a target and 
+    ///     process.
+    ///
+    /// @param[in] function_ptr
+    ///     The default function to be called.  Can be overridden using
+    ///     WriteFunctionArguments().
+    ///
+    /// @param[in] ast_context
+    ///     The AST context to evaluate argument types in.
+    ///
+    /// @param[in] arg_value_list
+    ///     The default values to use when calling this function.  Can
+    ///     be overridden using WriteFunctionArguments().
+    //------------------------------------------------------------------  
+    ClangFunctionWithDeclMap (ExecutionContextScope &exe_scope,
+        Function &function_ptr,
+        ClangASTContext *ast_context,
+        const ValueList &arg_value_list,
+        const char *name);
+
+    //------------------------------------------------------------------
+    /// Constructor
+    ///
+    /// @param[in] exe_scope
+    ///     An execution context scope that gets us at least a target and 
+    ///     process.
+    ///
+    /// @param[in] ast_context
+    ///     The AST context to evaluate argument types in.
+    ///
+    /// @param[in] return_qualtype
+    ///     An opaque Clang QualType for the function result.  Should be
+    ///     defined in ast_context.
+    ///
+    /// @param[in] function_address
+    ///     The address of the function to call.
+    ///
+    /// @param[in] arg_value_list
+    ///     The default values to use when calling this function.  Can
+    ///     be overridden using WriteFunctionArguments().
+    //------------------------------------------------------------------
+    ClangFunctionWithDeclMap (ExecutionContextScope &exe_scope,
+        const ClangASTType &return_type,
+        const Address& function_address,
+        const ValueList &arg_value_list,
+        const char *name);
+
+    ClangExpressionDeclMap *
+        DeclMap ()
+    {
+        return m_expr_decl_map.get();
+    }
+
+    unsigned
+    CompileFunction (Stream &errors);
+
+private:
+    ExecutionContext m_context;
+    std::shared_ptr<Materializer> m_materializer;
+    std::unique_ptr<ClangExpressionDeclMap>     m_expr_decl_map;        ///< The map to use when parsing the expression.
+
+};
+
 } // Namespace lldb_private
 
 #endif  // lldb_ClangFunction_h_
Index: include/lldb/Symbol/Type.h
===================================================================
--- include/lldb/Symbol/Type.h	(revision 219490)
+++ include/lldb/Symbol/Type.h	(working copy)
@@ -876,7 +876,13 @@
     
     bool
     GetDescription (Stream& stream);
-    
+
+    bool
+    IsObjCMethod () const
+    { 
+        return m_objc_method_decl != NULL;  
+    } 
+
 protected:
     std::string
     GetPrintableTypeName ();
Index: include/lldb/Target/ObjCLanguageRuntime.h
===================================================================
--- include/lldb/Target/ObjCLanguageRuntime.h	(revision 219490)
+++ include/lldb/Target/ObjCLanguageRuntime.h	(working copy)
@@ -510,6 +510,11 @@
     {
         m_negative_complete_class_cache.clear();
     }
+
+
+    lldb::addr_t
+    GetSelectorFor(const ConstString& value, ExecutionContextScope *exe_scope);
+
     
 protected:
     //------------------------------------------------------------------
@@ -607,11 +612,13 @@
     typedef std::multimap<uint32_t, ObjCISA> HashToISAMap;
     typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
     typedef HashToISAMap::iterator HashToISAIterator;
+    typedef std::map<ConstString, lldb::addr_t> SelectorMap;
 
     MsgImplMap m_impl_cache;
     LazyBool m_has_new_literals_and_indexing;
     ISAToDescriptorMap m_isa_to_descriptor;
     HashToISAMap m_hash_to_isa_map;
+    SelectorMap m_selector_map;
 
 protected:
     uint32_t m_isa_to_descriptor_stop_id;
Index: include/lldb/Target/Target.h
===================================================================
--- include/lldb/Target/Target.h	(revision 219490)
+++ include/lldb/Target/Target.h	(working copy)
@@ -1345,6 +1345,25 @@
     lldb::SearchFilterSP
     GetSearchFilterForModuleAndCUList (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles);
 
+    std::shared_ptr<ClangFunction>& GetOrAddClangFunction (Function* func)
+    {
+        return m_clang_functions[func];
+    }
+
+    std::shared_ptr<ClangFunction>& GetOrAddClangFunction (TypeMemberFunctionImpl* func)
+    {
+        return m_clang_functions[func];
+    }
+
+    void RemoveClangFunction (Function* func)
+    {
+        m_clang_functions.erase (func);
+    }
+
+    void RemoveClangFunction (TypeMemberFunctionImpl* func)
+    {
+        m_clang_functions.erase (func);
+    }
 protected:
     //------------------------------------------------------------------
     // Member variables.
@@ -1378,6 +1397,9 @@
     lldb::user_id_t         m_stop_hook_next_id;
     bool                    m_valid;
     bool                    m_suppress_stop_hooks;
+    typedef std::map<void*, std::shared_ptr<ClangFunction>> ClangFunctionCollection;
+    ClangFunctionCollection m_clang_functions;
+
     
     static void
     ImageSearchPathsChanged (const PathMappingList &path_list,
Index: scripts/Python/interface/SBFunction.i
===================================================================
--- scripts/Python/interface/SBFunction.i	(revision 219490)
+++ scripts/Python/interface/SBFunction.i	(working copy)
@@ -85,7 +85,14 @@
 
     bool
     GetDescription (lldb::SBStream &description);
-    
+
+    lldb::SBValue ExecuteFunction(lldb::SBFrame &frame,
+                                  lldb::SBValueList arguments,
+                                  lldb::SBExpressionOptions options,
+                                  bool reusable);
+
+    void RemoveReusableFunction (lldb::SBTarget &target);	
+
     bool
     operator == (const lldb::SBFunction &rhs) const;
     
Index: scripts/Python/interface/SBType.i
===================================================================
--- scripts/Python/interface/SBType.i	(revision 219490)
+++ scripts/Python/interface/SBType.i	(working copy)
@@ -101,7 +101,15 @@
     bool
     GetDescription (lldb::SBStream &description,
                     lldb::DescriptionLevel description_level);
-    
+
+    lldb::SBValue ExecuteObjCFunction (lldb::SBFrame &frame,
+                                   lldb::SBValue self,
+                                   lldb::SBValueList arguments,
+                                   lldb::SBExpressionOptions options,
+                                   bool reusable);
+
+    void RemoveReusableObjCFunction (lldb::SBTarget& target);
+					
 protected:
     lldb::TypeMemberFunctionImplSP m_opaque_sp;
 };
Index: source/API/SBFunction.cpp
===================================================================
--- source/API/SBFunction.cpp	(revision 219490)
+++ source/API/SBFunction.cpp	(working copy)
@@ -18,6 +18,13 @@
 #include "lldb/Symbol/Type.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Target.h"
+#include "lldb/API/SBExpressionOptions.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/API/SBFrame.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/ClangExpressionDeclMap.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -229,3 +236,95 @@
 
 
 
+lldb::SBValue SBFunction::ExecuteFunction(lldb::SBFrame &frame,
+    lldb::SBValueList arguments,
+    lldb::SBExpressionOptions options,
+    bool reusable)
+{
+    if (!m_opaque_ptr)
+    {
+        return SBValue();
+    }
+
+    ExecutionContext exe_ctx = frame.GetFrameSP();
+
+    if (!exe_ctx.GetFrameSP())
+    {
+        return SBValue();
+    }
+
+    Mutex::Locker api_locker;
+    TargetSP target_sp (exe_ctx.GetTargetSP ());
+    if (target_sp)
+    {
+        api_locker.Lock (target_sp->GetAPIMutex ());
+    }
+
+    ValueList args;
+    for (int i = 0; i < arguments.GetSize(); i++)
+    {
+        const ValueObjectSP value = arguments.GetValueAtIndex(i).GetSP();
+        value->UpdateValueIfNeeded();
+        args.PushValue(value->GetValue());
+    }
+    //arguments.
+    
+    std::shared_ptr<ClangFunction>& funcp_sp = exe_ctx.GetTargetPtr ()->GetOrAddClangFunction (m_opaque_ptr);
+    
+    StreamString errors;
+
+    if (!funcp_sp)
+    {
+        funcp_sp.reset (new ClangFunctionWithDeclMap (*frame.GetFrameSP (),
+            m_opaque_ptr->GetClangType ().GetFunctionReturnType (),
+            m_opaque_ptr->GetAddressRange ().GetBaseAddress (),
+            args,
+            m_opaque_ptr->GetName ().GetCString ()));
+
+        if (funcp_sp->CompileFunction (errors))
+        {
+            funcp_sp.reset ();
+            return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error (errors.GetData ())));
+        }
+            
+
+        if (!funcp_sp->WriteFunctionWrapper (exe_ctx, errors))
+        {
+            funcp_sp.reset ();
+            return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error (errors.GetData ())));
+        }
+    }
+    errors.Clear ();
+
+    lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+    if (!funcp_sp->WriteFunctionArguments (exe_ctx, args_addr,
+        funcp_sp->GetFunctionAddress (), args, errors))
+    {
+        return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error (errors.GetData ())));
+    }
+
+    Value res;
+    if (funcp_sp->ExecuteFunction (exe_ctx, &args_addr, *options.get (), errors, res))
+    {
+        funcp_sp->DeallocateFunctionResults (exe_ctx, args_addr);
+        if (!reusable)
+            exe_ctx.GetTargetPtr ()->RemoveClangFunction (m_opaque_ptr);
+        return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error (errors.GetData ())));
+    }
+
+    SBValue results = ValueObjectConstResult::Create (exe_ctx.GetThreadPtr(), res, ConstString ("<evaluation result>"));
+
+    funcp_sp->DeallocateFunctionResults (exe_ctx, args_addr);
+    if (!reusable)
+        exe_ctx.GetTargetPtr ()->RemoveClangFunction (m_opaque_ptr);
+    return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error (errors.GetData ())));
+}
+
+void SBFunction::RemoveReusableFunction (lldb::SBTarget &target)
+{
+    Mutex::Locker api_locker;
+    if (target.m_opaque_sp) {
+        api_locker.Lock (target.m_opaque_sp->GetAPIMutex ());
+        target.m_opaque_sp->RemoveClangFunction (m_opaque_ptr);
+    }
+}
\ No newline at end of file
Index: source/API/SBType.cpp
===================================================================
--- source/API/SBType.cpp	(revision 219490)
+++ source/API/SBType.cpp	(working copy)
@@ -17,6 +17,23 @@
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/ClangASTType.h"
 #include "lldb/Symbol/Type.h"
+#include "lldb/API/SBValue.h"
+#include "lldb/API/SBValueList.h"
+#include "lldb/API/SBExpressionOptions.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBFrame.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/API/SBValueList.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/API/SBTarget.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Expression/ClangExpressionDeclMap.h"
 
 #include "clang/AST/Decl.h"
 
@@ -821,3 +838,126 @@
 {
     return *m_opaque_sp.get();
 }
+
+void SBTypeMemberFunction::RemoveReusableObjCFunction (lldb::SBTarget& target)
+{
+    Mutex::Locker api_locker;
+    if (target.m_opaque_sp) {
+        api_locker.Lock (target.m_opaque_sp->GetAPIMutex ());
+
+        target.m_opaque_sp->RemoveClangFunction (m_opaque_sp.get ());
+    }
+}
+
+lldb::SBValue SBTypeMemberFunction::ExecuteObjCFunction (lldb::SBFrame &frame,
+    lldb::SBValue self,
+    lldb::SBValueList arguments,
+    lldb::SBExpressionOptions options,
+    bool reusable)
+{
+    if (!m_opaque_sp)
+    {
+        return SBValue ();
+    }
+    if (!frame.GetFrameSP ())
+    {
+        return SBValue ();
+    }
+    
+    if (!m_opaque_sp->IsObjCMethod())
+    {
+        return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP().get(), Error ("ExecuteObjcFunction only works on ObjC methods")));
+    }
+
+    if (!self.IsValid ())
+    {
+        return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error ("No self value passed")));
+    }
+
+    ExecutionContext exe_ctx;
+    frame.GetFrameSP ()->CalculateExecutionContext (exe_ctx);
+
+    StreamString errors;
+
+    Mutex::Locker api_locker;
+    TargetSP target_sp (exe_ctx.GetTargetSP ());
+    if (target_sp)
+    {
+        api_locker.Lock (target_sp->GetAPIMutex ());
+    }
+
+
+    TypeMemberFunctionImpl& val = *m_opaque_sp.get ();
+
+    ValueList args;
+    ClangASTContext* ast = exe_ctx.GetTargetPtr ()->GetScratchClangASTContext ();
+    ClangASTType pointertype = ast->GetCStringType (true);
+    ValueObjectSP selfptr = self.GetSP ()->Cast (pointertype);
+    selfptr->UpdateValueIfNeeded ();
+    args.PushValue (selfptr->GetValue ());
+
+    uint64_t sel = exe_ctx.GetProcessPtr ()->GetObjCLanguageRuntime ()->GetSelectorFor (ConstString (m_opaque_sp->GetName ()), exe_ctx.GetFramePtr ());
+    Value selectorvalue (ast->GetPointerByteSize () == 4 ? Scalar ((uint32_t)sel) : Scalar (sel));
+    selectorvalue.SetClangType (pointertype);
+    args.PushValue (selectorvalue);
+
+
+    for (int i = 0; i < arguments.GetSize (); i++)  {
+        const ValueObjectSP value = arguments.GetValueAtIndex (i).GetSP ();
+        value->UpdateValueIfNeeded ();
+        args.PushValue (value->GetValue ());
+    }
+
+    std::shared_ptr<ClangFunction>& funcp_sp = exe_ctx.GetTargetPtr ()->GetOrAddClangFunction (m_opaque_sp.get ());
+
+    if (!funcp_sp)
+    {
+        SymbolContextList sclist;
+        exe_ctx.GetTargetPtr ()->GetImages ().FindFunctions (ConstString ("objc_msgSend"), eFunctionNameTypeAny,
+            true, false, true, sclist);
+        if (!sclist.GetSize ()) {
+            return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error ("Cannot find objc_msgSend")));
+        }
+        Address* msgsend_address = &sclist[0].symbol->GetAddress ();
+        funcp_sp.reset (new ClangFunctionWithDeclMap (*frame.GetFrameSP (),
+            m_opaque_sp->GetReturnType (),
+            *msgsend_address,
+            args,
+            m_opaque_sp->GetName ().GetCString ()));
+
+
+        if (funcp_sp->CompileFunction (errors))
+        {
+            funcp_sp.reset ();
+            return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error (errors.GetData ())));
+        }
+
+        if (!funcp_sp->WriteFunctionWrapper (exe_ctx, errors))
+        {
+            funcp_sp.reset ();
+            return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error (errors.GetData ())));
+        }
+    }
+    errors.Clear ();
+
+    lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+    if (!funcp_sp->WriteFunctionArguments (exe_ctx, args_addr,
+        funcp_sp->GetFunctionAddress (), args, errors))
+    {
+        return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error (errors.GetData ())));
+    }
+
+    Value res;
+    if (funcp_sp->ExecuteFunction (exe_ctx, &args_addr, *options.get (), errors, res))
+    {
+        funcp_sp->DeallocateFunctionResults (exe_ctx, args_addr);
+        if (!reusable)
+            exe_ctx.GetTargetPtr ()->RemoveClangFunction (m_opaque_sp.get ());
+        return SBValue (ValueObjectConstResult::Create (frame.GetFrameSP ().get (), Error (errors.GetData ())));
+    }
+
+    funcp_sp->DeallocateFunctionResults (exe_ctx, args_addr);
+    if (!reusable)
+        exe_ctx.GetTargetPtr ()->RemoveClangFunction (m_opaque_sp.get ());
+    return ValueObjectConstResult::Create (exe_ctx.GetThreadPtr (), res, ConstString ("<evaluation result>"));
+}
Index: source/Expression/ClangFunction.cpp
===================================================================
--- source/Expression/ClangFunction.cpp	(revision 219490)
+++ source/Expression/ClangFunction.cpp	(working copy)
@@ -43,6 +43,7 @@
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/ThreadPlan.h"
 #include "lldb/Target/ThreadPlanCallFunction.h"
+#include "lldb/Expression/ClangExpressionDeclMap.h"
 
 using namespace lldb_private;
 
@@ -594,3 +595,48 @@
     
     return m_struct_extractor.get();
 }
+
+
+ClangFunctionWithDeclMap::ClangFunctionWithDeclMap (ExecutionContextScope &exe_scope,
+    Function &function_ptr,
+    ClangASTContext *ast_context,
+    const ValueList &arg_value_list,
+    const char *name)
+    : ClangFunction (exe_scope, function_ptr, ast_context, arg_value_list, name)
+{
+    exe_scope.CalculateExecutionContext (m_context);
+    // ClangASTSource depends on the struct name starting with $ for external lookups
+    m_wrapper_struct_name = "$__lldb_caller_struct"; 
+}
+
+ClangFunctionWithDeclMap::ClangFunctionWithDeclMap (ExecutionContextScope &exe_scope,
+    const ClangASTType &return_type,
+    const Address& function_address,
+    const ValueList &arg_value_list,
+    const char *name)
+
+    : ClangFunction (exe_scope, return_type, function_address, arg_value_list, name)
+{
+    exe_scope.CalculateExecutionContext (m_context);
+    // ClangASTSource depends on the struct name starting with $ for external lookups
+    m_wrapper_struct_name = "$__lldb_caller_struct";
+}
+
+
+unsigned ClangFunctionWithDeclMap::CompileFunction (Stream &errors)
+{
+    if (!m_materializer)
+        m_materializer.reset (new Materializer ());
+    
+    if (!m_expr_decl_map) 
+        m_expr_decl_map.reset (new ClangExpressionDeclMap (false, m_context));
+        
+    if (!m_expr_decl_map->WillParse (m_context, m_materializer.get ()))
+    {
+        errors.PutCString ("Could not materialize");
+        return 1;
+    }
+    unsigned res = ClangFunction::CompileFunction (errors);
+
+    return res;
+}
\ No newline at end of file
Index: source/Target/ObjCLanguageRuntime.cpp
===================================================================
--- source/Target/ObjCLanguageRuntime.cpp	(revision 219490)
+++ source/Target/ObjCLanguageRuntime.cpp	(working copy)
@@ -19,6 +19,7 @@
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Core/ValueObjectConstResult.h"
 
 #include "llvm/ADT/StringRef.h"
 
@@ -626,3 +627,22 @@
 {
     return nullptr;
 }
+
+lldb::addr_t
+ObjCLanguageRuntime::GetSelectorFor (const ConstString& value, ExecutionContextScope *exe_scope)
+{
+    auto res = m_selector_map.find (value);
+    if (res != m_selector_map.end ())
+        return res->second;
+
+    ValueList args;
+    std::string selector;
+    selector = selector + "((void* (*)(char*))sel_registerName)(\"" + value.AsCString () + "\")";
+    ValueObjectSP selectorptr;
+    exe_scope->CalculateTarget ()->EvaluateExpression (selector.c_str (), exe_scope->CalculateStackFrame ().get (), selectorptr);
+
+    addr_t result = selectorptr->GetValueAsUnsigned (0);
+    if (result)
+        m_selector_map[value] = result;
+    return result;
+}
\ No newline at end of file


More information about the lldb-dev mailing list