jing...@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
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
_______________________________________________
lldb-dev mailing list
lldb-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev