[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