summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBFrame.cpp2
-rw-r--r--lldb/source/Breakpoint/BreakpointLocation.cpp33
-rw-r--r--lldb/source/Breakpoint/BreakpointOptions.cpp1
-rw-r--r--lldb/source/Breakpoint/Watchpoint.cpp14
-rw-r--r--lldb/source/Breakpoint/WatchpointOptions.cpp1
-rw-r--r--lldb/source/Commands/CommandObjectArgs.cpp2
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp5
-rw-r--r--lldb/source/DataFormatters/VectorType.cpp2
-rw-r--r--lldb/source/Expression/ASTStructExtractor.cpp2
-rw-r--r--lldb/source/Expression/CMakeLists.txt6
-rw-r--r--lldb/source/Expression/ClangASTSource.cpp1
-rw-r--r--lldb/source/Expression/ClangExpressionParser.cpp33
-rw-r--r--lldb/source/Expression/ClangFunctionCaller.cpp220
-rw-r--r--lldb/source/Expression/ClangUserExpression.cpp669
-rw-r--r--lldb/source/Expression/ClangUtilityFunction.cpp36
-rw-r--r--lldb/source/Expression/Expression.cpp32
-rw-r--r--lldb/source/Expression/FunctionCaller.cpp (renamed from lldb/source/Expression/ClangFunction.cpp)222
-rw-r--r--lldb/source/Expression/IRDynamicChecks.cpp13
-rw-r--r--lldb/source/Expression/UserExpression.cpp644
-rw-r--r--lldb/source/Expression/UtilityFunction.cpp123
-rw-r--r--lldb/source/Plugins/Language/ObjC/CoreMedia.cpp2
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSArray.cpp1
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp2
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp55
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h4
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp9
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h2
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp208
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h12
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp98
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h7
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp14
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h6
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp112
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h9
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp99
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h8
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp117
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h8
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp109
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h8
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp2
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp54
-rw-r--r--lldb/source/Target/Process.cpp29
-rw-r--r--lldb/source/Target/StopInfo.cpp15
-rw-r--r--lldb/source/Target/Target.cpp120
-rw-r--r--lldb/source/Target/ThreadPlanCallUserExpression.cpp4
47 files changed, 1736 insertions, 1439 deletions
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp
index df6cc51ed07..ee467402569 100644
--- a/lldb/source/API/SBFrame.cpp
+++ b/lldb/source/API/SBFrame.cpp
@@ -22,7 +22,7 @@
#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Expression/ClangPersistentVariables.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp
index 1d082f69416..0dab0e16bf1 100644
--- a/lldb/source/Breakpoint/BreakpointLocation.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocation.cpp
@@ -21,9 +21,10 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObject.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
@@ -88,6 +89,12 @@ BreakpointLocation::GetBreakpoint ()
return m_owner;
}
+Target &
+BreakpointLocation::GetTarget()
+{
+ return m_owner.GetTarget();
+}
+
bool
BreakpointLocation::IsEnabled () const
{
@@ -278,10 +285,26 @@ BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
!m_user_expression_sp ||
!m_user_expression_sp->MatchesContext(exe_ctx))
{
- m_user_expression_sp.reset(new ClangUserExpression(condition_text,
- NULL,
- lldb::eLanguageTypeUnknown,
- ClangUserExpression::eResultTypeAny));
+ LanguageType language = eLanguageTypeUnknown;
+ // See if we can figure out the language from the frame, otherwise use the default language:
+ CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
+ if (comp_unit)
+ language = comp_unit->GetLanguage();
+
+ Error error;
+ m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(condition_text,
+ NULL,
+ language,
+ Expression::eResultTypeAny,
+ error));
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf("Error getting condition expression: %s.", error.AsCString());
+ m_user_expression_sp.reset();
+ return true;
+ }
+
StreamString errors;
diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp
index db76ffb8685..99a4d47a8d9 100644
--- a/lldb/source/Breakpoint/BreakpointOptions.cpp
+++ b/lldb/source/Breakpoint/BreakpointOptions.cpp
@@ -20,7 +20,6 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
-#include "lldb/Expression/ClangUserExpression.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/lldb/source/Breakpoint/Watchpoint.cpp b/lldb/source/Breakpoint/Watchpoint.cpp
index af9cfaff6a2..41b24fd67df 100644
--- a/lldb/source/Breakpoint/Watchpoint.cpp
+++ b/lldb/source/Breakpoint/Watchpoint.cpp
@@ -22,7 +22,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
using namespace lldb;
using namespace lldb_private;
@@ -371,7 +371,17 @@ Watchpoint::SetCondition (const char *condition)
else
{
// Pass NULL for expr_prefix (no translation-unit level definitions).
- m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
+ Error error;
+ m_condition_ap.reset(m_target.GetUserExpressionForLanguage (condition,
+ NULL,
+ lldb::eLanguageTypeUnknown,
+ UserExpression::eResultTypeAny,
+ error));
+ if (error.Fail())
+ {
+ // FIXME: Log something...
+ m_condition_ap.reset();
+ }
}
SendWatchpointChangedEvent (eWatchpointEventTypeConditionChanged);
}
diff --git a/lldb/source/Breakpoint/WatchpointOptions.cpp b/lldb/source/Breakpoint/WatchpointOptions.cpp
index c2c9696c4ce..d11c8f74f94 100644
--- a/lldb/source/Breakpoint/WatchpointOptions.cpp
+++ b/lldb/source/Breakpoint/WatchpointOptions.cpp
@@ -20,7 +20,6 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
-#include "lldb/Expression/ClangUserExpression.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/lldb/source/Commands/CommandObjectArgs.cpp b/lldb/source/Commands/CommandObjectArgs.cpp
index 39dcba07cca..c4db97caa6a 100644
--- a/lldb/source/Commands/CommandObjectArgs.cpp
+++ b/lldb/source/Commands/CommandObjectArgs.cpp
@@ -17,9 +17,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
-#include "lldb/Expression/ClangFunction.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 7e787bce8c9..96dd90e7ecc 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -17,8 +17,7 @@
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
-#include "lldb/Expression/ClangUserExpression.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/StringConvert.h"
@@ -345,7 +344,7 @@ CommandObjectExpression::EvaluateExpression
}
else
{
- if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
+ if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult)
{
if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
{
diff --git a/lldb/source/DataFormatters/VectorType.cpp b/lldb/source/DataFormatters/VectorType.cpp
index faef33de909..56ca3ceac2a 100644
--- a/lldb/source/DataFormatters/VectorType.cpp
+++ b/lldb/source/DataFormatters/VectorType.cpp
@@ -235,7 +235,7 @@ namespace lldb_private {
TargetSP target_sp(m_backend.GetTargetSP());
m_child_type = ::GetCompilerTypeForFormat(m_parent_format,
element_type,
- target_sp ? target_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC) : nullptr);
+ target_sp ? target_sp->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC) : nullptr);
m_num_children = ::CalculateNumChildren(parent_type,
m_child_type);
m_item_format = GetItemFormatForFormat(m_parent_format,
diff --git a/lldb/source/Expression/ASTStructExtractor.cpp b/lldb/source/Expression/ASTStructExtractor.cpp
index 98628dbc92b..049173e32f3 100644
--- a/lldb/source/Expression/ASTStructExtractor.cpp
+++ b/lldb/source/Expression/ASTStructExtractor.cpp
@@ -28,7 +28,7 @@ using namespace lldb_private;
ASTStructExtractor::ASTStructExtractor(ASTConsumer *passthrough,
const char *struct_name,
- ClangFunction &function) :
+ ClangFunctionCaller &function) :
m_ast_context (NULL),
m_passthrough (passthrough),
m_passthrough_sema (NULL),
diff --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt
index 92f8f0863bf..4b689da027b 100644
--- a/lldb/source/Expression/CMakeLists.txt
+++ b/lldb/source/Expression/CMakeLists.txt
@@ -5,18 +5,22 @@ add_lldb_library(lldbExpression
ClangASTSource.cpp
ClangExpressionDeclMap.cpp
ClangExpressionParser.cpp
- ClangFunction.cpp
+ ClangFunctionCaller.cpp
ClangModulesDeclVendor.cpp
ClangPersistentVariables.cpp
ClangUserExpression.cpp
ClangUtilityFunction.cpp
DWARFExpression.cpp
+ Expression.cpp
ExpressionSourceCode.cpp
ExpressionVariable.cpp
+ FunctionCaller.cpp
IRDynamicChecks.cpp
IRExecutionUnit.cpp
IRForTarget.cpp
IRInterpreter.cpp
IRMemoryMap.cpp
Materializer.cpp
+ UserExpression.cpp
+ UtilityFunction.cpp
)
diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp
index ef778a1bca4..e6ddaa7e506 100644
--- a/lldb/source/Expression/ClangASTSource.cpp
+++ b/lldb/source/Expression/ClangASTSource.cpp
@@ -15,7 +15,6 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Expression/ASTDumper.h"
#include "lldb/Expression/ClangASTSource.h"
-#include "lldb/Expression/ClangExpression.h"
#include "lldb/Expression/ClangModulesDeclVendor.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompilerDeclContext.h"
diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp
index d5dbaf16b4a..2a4663966cf 100644
--- a/lldb/source/Expression/ClangExpressionParser.cpp
+++ b/lldb/source/Expression/ClangExpressionParser.cpp
@@ -19,7 +19,7 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Expression/ClangASTSource.h"
-#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangExpressionHelper.h"
#include "lldb/Expression/ClangExpressionDeclMap.h"
#include "lldb/Expression/ClangModulesDeclVendor.h"
#include "lldb/Expression/ClangPersistentVariables.h"
@@ -37,6 +37,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/CodeGen/CodeGenAction.h"
@@ -108,7 +109,7 @@ public:
}
virtual void moduleImport(SourceLocation import_location,
- ModuleIdPath path,
+ clang::ModuleIdPath path,
const clang::Module * /*null*/)
{
std::vector<ConstString> string_path;
@@ -149,9 +150,9 @@ public:
//===----------------------------------------------------------------------===//
ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
- ClangExpression &expr,
+ Expression &expr,
bool generate_debug_info) :
- m_expr (expr),
+ ExpressionParser (exe_scope, expr, generate_debug_info),
m_compiler (),
m_code_generator (),
m_pp_callbacks(nullptr)
@@ -255,7 +256,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->getLangOpts().WChar = true;
m_compiler->getLangOpts().Blocks = true;
m_compiler->getLangOpts().DebuggerSupport = true; // Features specifically for debugger clients
- if (expr.DesiredResultType() == ClangExpression::eResultTypeId)
+ if (expr.DesiredResultType() == Expression::eResultTypeId)
m_compiler->getLangOpts().DebuggerCastResultToId = true;
m_compiler->getLangOpts().CharIsSigned =
@@ -346,7 +347,8 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
ast_context->InitBuiltinTypes(m_compiler->getTarget());
- ClangExpressionDeclMap *decl_map = m_expr.DeclMap();
+ ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
+ ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap();
if (decl_map)
{
@@ -430,9 +432,11 @@ ClangExpressionParser::Parse (Stream &stream)
diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor());
- ASTConsumer *ast_transformer = m_expr.ASTTransformer(m_code_generator.get());
+ ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
- if (ClangExpressionDeclMap *decl_map = m_expr.DeclMap())
+ ASTConsumer *ast_transformer = type_system_helper->ASTTransformer(m_code_generator.get());
+
+ if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap())
decl_map->InstallCodeGenerator(m_code_generator.get());
if (ast_transformer)
@@ -479,7 +483,7 @@ ClangExpressionParser::Parse (Stream &stream)
if (!num_errors)
{
- if (m_expr.DeclMap() && !m_expr.DeclMap()->ResolveUnknownTypes())
+ if (type_system_helper->DeclMap() && !type_system_helper->DeclMap()->ResolveUnknownTypes())
{
stream.Printf("error: Couldn't infer the type of a variable\n");
num_errors++;
@@ -552,7 +556,8 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
exe_ctx.GetTargetSP(),
m_compiler->getTargetOpts().Features));
- ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
+ ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
+ ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap(); // result can be NULL
if (decl_map)
{
@@ -640,11 +645,3 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
return err;
}
-
-bool
-ClangExpressionParser::GetGenerateDebugInfo () const
-{
- if (m_compiler)
- return m_compiler->getCodeGenOpts().getDebugInfo() == CodeGenOptions::FullDebugInfo;
- return false;
-}
diff --git a/lldb/source/Expression/ClangFunctionCaller.cpp b/lldb/source/Expression/ClangFunctionCaller.cpp
new file mode 100644
index 00000000000..628952fe6b8
--- /dev/null
+++ b/lldb/source/Expression/ClangFunctionCaller.cpp
@@ -0,0 +1,220 @@
+//===-- ClangFunctionCallerCaller.cpp ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/CodeGen/CodeGenAction.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/IR/Module.h"
+
+// Project includes
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Expression/ASTStructExtractor.h"
+#include "lldb/Expression/ClangExpressionParser.h"
+#include "lldb/Expression/ClangFunctionCaller.h"
+#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
+
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// ClangFunctionCaller constructor
+//----------------------------------------------------------------------
+ClangFunctionCaller::ClangFunctionCaller
+(
+ ExecutionContextScope &exe_scope,
+ const CompilerType &return_type,
+ const Address& functionAddress,
+ const ValueList &arg_value_list,
+ const char *name
+) :
+ FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list, name),
+ m_type_system_helper (*this)
+{
+ m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
+ // Can't make a ClangFunctionCaller without a process.
+ assert (m_jit_process_wp.lock());
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ClangFunctionCaller::~ClangFunctionCaller()
+{
+}
+
+unsigned
+ClangFunctionCaller::CompileFunction (Stream &errors)
+{
+ if (m_compiled)
+ return 0;
+
+ // FIXME: How does clang tell us there's no return value? We need to handle that case.
+ unsigned num_errors = 0;
+
+ std::string return_type_str (m_function_return_type.GetTypeName().AsCString(""));
+
+ // Cons up the function we're going to wrap our call in, then compile it...
+ // We declare the function "extern "C"" because the compiler might be in C++
+ // mode which would mangle the name and then we couldn't find it again...
+ m_wrapper_function_text.clear();
+ m_wrapper_function_text.append ("extern \"C\" void ");
+ m_wrapper_function_text.append (m_wrapper_function_name);
+ m_wrapper_function_text.append (" (void *input)\n{\n struct ");
+ m_wrapper_function_text.append (m_wrapper_struct_name);
+ m_wrapper_function_text.append (" \n {\n");
+ m_wrapper_function_text.append (" ");
+ m_wrapper_function_text.append (return_type_str);
+ m_wrapper_function_text.append (" (*fn_ptr) (");
+
+ // Get the number of arguments. If we have a function type and it is prototyped,
+ // trust that, otherwise use the values we were given.
+
+ // FIXME: This will need to be extended to handle Variadic functions. We'll need
+ // to pull the defined arguments out of the function, then add the types from the
+ // arguments list for the variable arguments.
+
+ uint32_t num_args = UINT32_MAX;
+ bool trust_function = false;
+ // GetArgumentCount returns -1 for an unprototyped function.
+ CompilerType function_clang_type;
+ if (m_function_ptr)
+ {
+ function_clang_type = m_function_ptr->GetCompilerType();
+ if (function_clang_type)
+ {
+ int num_func_args = function_clang_type.GetFunctionArgumentCount();
+ if (num_func_args >= 0)
+ {
+ trust_function = true;
+ num_args = num_func_args;
+ }
+ }
+ }
+
+ if (num_args == UINT32_MAX)
+ num_args = m_arg_values.GetSize();
+
+ std::string args_buffer; // This one stores the definition of all the args in "struct caller".
+ std::string args_list_buffer; // This one stores the argument list called from the structure.
+ for (size_t i = 0; i < num_args; i++)
+ {
+ std::string type_name;
+
+ if (trust_function)
+ {
+ type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i).GetTypeName().AsCString("");
+ }
+ else
+ {
+ CompilerType clang_qual_type = m_arg_values.GetValueAtIndex(i)->GetCompilerType ();
+ if (clang_qual_type)
+ {
+ type_name = clang_qual_type.GetTypeName().AsCString("");
+ }
+ else
+ {
+ errors.Printf("Could not determine type of input value %" PRIu64 ".", (uint64_t)i);
+ return 1;
+ }
+ }
+
+ m_wrapper_function_text.append (type_name);
+ if (i < num_args - 1)
+ m_wrapper_function_text.append (", ");
+
+ char arg_buf[32];
+ args_buffer.append (" ");
+ args_buffer.append (type_name);
+ snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i);
+ args_buffer.push_back (' ');
+ args_buffer.append (arg_buf);
+ args_buffer.append (";\n");
+
+ args_list_buffer.append ("__lldb_fn_data->");
+ args_list_buffer.append (arg_buf);
+ if (i < num_args - 1)
+ args_list_buffer.append (", ");
+
+ }
+ m_wrapper_function_text.append (");\n"); // Close off the function calling prototype.
+
+ m_wrapper_function_text.append (args_buffer);
+
+ m_wrapper_function_text.append (" ");
+ m_wrapper_function_text.append (return_type_str);
+ m_wrapper_function_text.append (" return_value;");
+ m_wrapper_function_text.append ("\n };\n struct ");
+ m_wrapper_function_text.append (m_wrapper_struct_name);
+ m_wrapper_function_text.append ("* __lldb_fn_data = (struct ");
+ m_wrapper_function_text.append (m_wrapper_struct_name);
+ m_wrapper_function_text.append (" *) input;\n");
+
+ m_wrapper_function_text.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
+ m_wrapper_function_text.append (args_list_buffer);
+ m_wrapper_function_text.append (");\n}\n");
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ if (log)
+ log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
+
+ // Okay, now compile this expression
+
+ lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
+ if (jit_process_sp)
+ {
+ const bool generate_debug_info = true;
+ m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this, generate_debug_info));
+
+ num_errors = m_parser->Parse (errors);
+ }
+ else
+ {
+ errors.Printf("no process - unable to inject function");
+ num_errors = 1;
+ }
+
+ m_compiled = (num_errors == 0);
+
+ if (!m_compiled)
+ return num_errors;
+
+ return num_errors;
+}
+
+clang::ASTConsumer *
+ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer (clang::ASTConsumer *passthrough)
+{
+ m_struct_extractor.reset(new ASTStructExtractor(passthrough, m_owner.GetWrapperStructName(), m_owner));
+
+ return m_struct_extractor.get();
+}
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp
index 9239389753e..a6e5923bf28 100644
--- a/lldb/source/Expression/ClangUserExpression.cpp
+++ b/lldb/source/Expression/ClangUserExpression.cpp
@@ -25,7 +25,6 @@
#include "lldb/Expression/ASTResultSynthesizer.h"
#include "lldb/Expression/ClangExpressionDeclMap.h"
#include "lldb/Expression/ClangExpressionParser.h"
-#include "lldb/Expression/ClangFunction.h"
#include "lldb/Expression/ClangModulesDeclVendor.h"
#include "lldb/Expression/ClangPersistentVariables.h"
#include "lldb/Expression/ClangUserExpression.h"
@@ -54,32 +53,13 @@
using namespace lldb_private;
-ClangUserExpression::ClangUserExpression (const char *expr,
+ClangUserExpression::ClangUserExpression (ExecutionContextScope &exe_scope,
+ const char *expr,
const char *expr_prefix,
lldb::LanguageType language,
ResultType desired_type) :
- ClangExpression (),
- m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
- m_stack_frame_top (LLDB_INVALID_ADDRESS),
- m_expr_text (expr),
- m_expr_prefix (expr_prefix ? expr_prefix : ""),
- m_language (language),
- m_transformed_text (),
- m_desired_type (desired_type),
- m_expr_decl_map(),
- m_execution_unit_sp(),
- m_materializer_ap(),
- m_result_synthesizer(),
- m_jit_module_wp(),
- m_enforce_valid_object (true),
- m_in_cplusplus_method (false),
- m_in_objectivec_method (false),
- m_in_static_method(false),
- m_needs_object_ptr (false),
- m_const_object (false),
- m_target (NULL),
- m_can_interpret (false),
- m_materialized_address (LLDB_INVALID_ADDRESS)
+ UserExpression (exe_scope, expr, expr_prefix, language, desired_type),
+ m_type_system_helper(*m_target_wp.lock().get())
{
switch (m_language)
{
@@ -99,21 +79,6 @@ ClangUserExpression::ClangUserExpression (const char *expr,
ClangUserExpression::~ClangUserExpression ()
{
- if (m_target)
- {
- lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
- if (jit_module_sp)
- m_target->GetImages().Remove(jit_module_sp);
- }
-}
-
-clang::ASTConsumer *
-ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
-{
- m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
- *m_target));
-
- return m_result_synthesizer.get();
}
void
@@ -338,54 +303,6 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
}
}
-void
-ClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
-{
- m_process_wp = exe_ctx.GetProcessSP();
-
- lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
-
- if (frame_sp)
- m_address = frame_sp->GetFrameCodeAddress();
-}
-
-bool
-ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
- lldb::TargetSP &target_sp,
- lldb::ProcessSP &process_sp,
- lldb::StackFrameSP &frame_sp)
-{
- lldb::ProcessSP expected_process_sp = m_process_wp.lock();
- process_sp = exe_ctx.GetProcessSP();
-
- if (process_sp != expected_process_sp)
- return false;
-
- process_sp = exe_ctx.GetProcessSP();
- target_sp = exe_ctx.GetTargetSP();
- frame_sp = exe_ctx.GetFrameSP();
-
- if (m_address.IsValid())
- {
- if (!frame_sp)
- return false;
- else
- return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
- }
-
- return true;
-}
-
-bool
-ClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
-{
- lldb::TargetSP target_sp;
- lldb::ProcessSP process_sp;
- lldb::StackFrameSP frame_sp;
-
- return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
-}
-
// This is a really nasty hack, meant to fix Objective-C expressions of the form
// (int)[myArray count]. Right now, because the type information for count is
// not available, [myArray count] returns id, which can't be directly cast to
@@ -405,26 +322,6 @@ ApplyObjcCastHack(std::string &expr)
#undef OBJC_CAST_HACK_FROM
}
-// Another hack, meant to allow use of unichar despite it not being available in
-// the type information. Although we could special-case it in type lookup,
-// hopefully we'll figure out a way to #include the same environment as is
-// present in the original source file rather than try to hack specific type
-// definitions in as needed.
-//static void
-//ApplyUnicharHack(std::string &expr)
-//{
-//#define UNICHAR_HACK_FROM "unichar"
-//#define UNICHAR_HACK_TO "unsigned short"
-//
-// size_t from_offset;
-//
-// while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
-// expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
-//
-//#undef UNICHAR_HACK_TO
-//#undef UNICHAR_HACK_FROM
-//}
-
bool
ClangUserExpression::Parse (Stream &error_stream,
ExecutionContext &exe_ctx,
@@ -525,7 +422,7 @@ ClangUserExpression::Parse (Stream &error_stream,
m_materializer_ap.reset(new Materializer());
- m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
+ ResetDeclMap(exe_ctx, keep_result_in_memory);
class OnExit
{
@@ -545,13 +442,13 @@ ClangUserExpression::Parse (Stream &error_stream,
Callback m_callback;
};
- OnExit on_exit([this]() { m_expr_decl_map.reset(); });
+ OnExit on_exit([this]() { ResetDeclMap(); });
- if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
+ if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
{
error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
- m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
+ ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
return false;
}
@@ -570,7 +467,7 @@ ClangUserExpression::Parse (Stream &error_stream,
{
error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
- m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
+ ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
return false;
}
@@ -617,7 +514,7 @@ ClangUserExpression::Parse (Stream &error_stream,
// }
}
- m_expr_decl_map.reset(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any ClangASTImporter::Minions.
+ ResetDeclMap(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any ClangASTImporter::Minions.
if (jit_error.Success())
{
@@ -636,537 +533,81 @@ ClangUserExpression::Parse (Stream &error_stream,
}
}
-static lldb::addr_t
-GetObjectPointer (lldb::StackFrameSP frame_sp,
- ConstString &object_name,
- Error &err)
-{
- err.Clear();
-
- if (!frame_sp)
- {
- err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
- return LLDB_INVALID_ADDRESS;
- }
-
- lldb::VariableSP var_sp;
- lldb::ValueObjectSP valobj_sp;
-
- valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
- lldb::eNoDynamicValues,
- StackFrame::eExpressionPathOptionCheckPtrVsMember |
- StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
- StackFrame::eExpressionPathOptionsNoSyntheticChildren |
- StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
- var_sp,
- err);
-
- if (!err.Success() || !valobj_sp.get())
- return LLDB_INVALID_ADDRESS;
-
- lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-
- if (ret == LLDB_INVALID_ADDRESS)
- {
- err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
- return LLDB_INVALID_ADDRESS;
- }
-
- return ret;
-}
-
bool
-ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
- ExecutionContext &exe_ctx,
- lldb::addr_t &struct_address,
- lldb::addr_t &object_ptr,
- lldb::addr_t &cmd_ptr)
+ClangUserExpression::AddInitialArguments (ExecutionContext &exe_ctx,
+ std::vector<lldb::addr_t> &args,
+ Stream &error_stream)
{
- lldb::TargetSP target;
- lldb::ProcessSP process;
- lldb::StackFrameSP frame;
-
- if (!LockAndCheckContext(exe_ctx,
- target,
- process,
- frame))
- {
- error_stream.Printf("The context has changed before we could JIT the expression!\n");
- return false;
- }
-
- if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
+ lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
+ lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
+
+ if (m_needs_object_ptr)
{
- if (m_needs_object_ptr)
- {
- ConstString object_name;
-
- if (m_in_cplusplus_method)
- {
- object_name.SetCString("this");
- }
- else if (m_in_objectivec_method)
- {
- object_name.SetCString("self");
- }
- else
- {
- error_stream.Printf("Need object pointer but don't know the language\n");
- return false;
- }
-
- Error object_ptr_error;
-
- object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
-
- if (!object_ptr_error.Success())
- {
- error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
- object_ptr = 0;
- }
-
- if (m_in_objectivec_method)
- {
- ConstString cmd_name("_cmd");
-
- cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
-
- if (!object_ptr_error.Success())
- {
- error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
- cmd_ptr = 0;
- }
- }
- }
+ lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
+ if (!frame_sp)
+ return true;
+
+ ConstString object_name;
- if (m_materialized_address == LLDB_INVALID_ADDRESS)
+ if (m_in_cplusplus_method)
{
- Error alloc_error;
-
- IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
-
- m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(),
- m_materializer_ap->GetStructAlignment(),
- lldb::ePermissionsReadable | lldb::ePermissionsWritable,
- policy,
- alloc_error);
-
- if (!alloc_error.Success())
- {
- error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
- return false;
- }
+ object_name.SetCString("this");
}
-
- struct_address = m_materialized_address;
-
- if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
+ else if (m_in_objectivec_method)
{
- Error alloc_error;
-
- const size_t stack_frame_size = 512 * 1024;
-
- m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size,
- 8,
- lldb::ePermissionsReadable | lldb::ePermissionsWritable,
- IRMemoryMap::eAllocationPolicyHostOnly,
- alloc_error);
-
- m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
-
- if (!alloc_error.Success())
- {
- error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
- return false;
- }
+ object_name.SetCString("self");
}
-
- Error materialize_error;
-
- m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error);
-
- if (!materialize_error.Success())
+ else
{
- error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString());
+ error_stream.Printf("Need object pointer but don't know the language\n");
return false;
}
- }
- return true;
-}
-
-bool
-ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
- ExecutionContext &exe_ctx,
- lldb::ExpressionVariableSP &result,
- lldb::addr_t function_stack_bottom,
- lldb::addr_t function_stack_top)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- if (log)
- log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
- if (!m_dematerializer_sp)
- {
- error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
- return false;
- }
-
- Error dematerialize_error;
-
- m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
-
- if (!dematerialize_error.Success())
- {
- error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
- return false;
- }
-
- if (result)
- result->TransferAddress();
-
- m_dematerializer_sp.reset();
-
- return true;
-}
-
-lldb::ExpressionResults
-ClangUserExpression::Execute (Stream &error_stream,
- ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions& options,
- lldb::ClangUserExpressionSP &shared_ptr_to_me,
- lldb::ExpressionVariableSP &result)
-{
- // The expression log is quite verbose, and if you're just tracking the execution of the
- // expression, it's quite convenient to have these logs come out with the STEP log as well.
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-
- if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
- {
- lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
+ Error object_ptr_error;
- lldb::addr_t object_ptr = 0;
- lldb::addr_t cmd_ptr = 0;
+ object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
- if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
+ if (!object_ptr_error.Success())
{
- error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
- return lldb::eExpressionSetupError;
+ error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
+ object_ptr = 0;
}
- lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
- lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
-
- if (m_can_interpret)
+ if (m_in_objectivec_method)
{
- llvm::Module *module = m_execution_unit_sp->GetModule();
- llvm::Function *function = m_execution_unit_sp->GetFunction();
-
- if (!module || !function)
- {
- error_stream.Printf("Supposed to interpret, but nothing is there");
- return lldb::eExpressionSetupError;
- }
-
- Error interpreter_error;
-
- llvm::SmallVector <lldb::addr_t, 3> args;
-
- if (m_needs_object_ptr)
- {
- args.push_back(object_ptr);
+ ConstString cmd_name("_cmd");
- if (m_in_objectivec_method)
- args.push_back(cmd_ptr);
- }
-
- args.push_back(struct_address);
-
- function_stack_bottom = m_stack_frame_bottom;
- function_stack_top = m_stack_frame_top;
-
- IRInterpreter::Interpret (*module,
- *function,
- args,
- *m_execution_unit_sp.get(),
- interpreter_error,
- function_stack_bottom,
- function_stack_top,
- exe_ctx);
+ cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
- if (!interpreter_error.Success())
+ if (!object_ptr_error.Success())
{
- error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
- return lldb::eExpressionDiscarded;
+ error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
+ cmd_ptr = 0;
}
}
- else
- {
- if (!exe_ctx.HasThreadScope())
- {
- error_stream.Printf("ClangUserExpression::Execute called with no thread selected.");
- return lldb::eExpressionSetupError;
- }
-
- Address wrapper_address (m_jit_start_addr);
-
- llvm::SmallVector <lldb::addr_t, 3> args;
-
- if (m_needs_object_ptr) {
- args.push_back(object_ptr);
- if (m_in_objectivec_method)
- args.push_back(cmd_ptr);
- }
-
- args.push_back(struct_address);
-
- lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
- wrapper_address,
- args,
- options,
- shared_ptr_to_me));
-
- if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
- return lldb::eExpressionSetupError;
-
- ThreadPlanCallUserExpression *user_expression_plan = static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());
-
- lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer();
-
- function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
- function_stack_top = function_stack_pointer;
-
- if (log)
- log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
-
- if (exe_ctx.GetProcessPtr())
- exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
-
- lldb::ExpressionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
- call_plan_sp,
- options,
- error_stream);
-
- if (exe_ctx.GetProcessPtr())
- exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
-
- if (log)
- log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
+ if (object_ptr)
+ args.push_back(object_ptr);
- if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint)
- {
- const char *error_desc = NULL;
-
- if (call_plan_sp)
- {
- lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
- if (real_stop_info_sp)
- error_desc = real_stop_info_sp->GetDescription();
- }
- if (error_desc)
- error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
- else
- error_stream.PutCString ("Execution was interrupted.");
-
- if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError())
- || (execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints()))
- error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
- else
- {
- if (execution_result == lldb::eExpressionHitBreakpoint)
- user_expression_plan->TransferExpressionOwnership();
- error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, "
- "use \"thread return -x\" to return to the state before expression evaluation.");
- }
+ if (m_in_objectivec_method)
+ args.push_back(cmd_ptr);
- return execution_result;
- }
- else if (execution_result == lldb::eExpressionStoppedForDebug)
- {
- error_stream.PutCString ("Execution was halted at the first instruction of the expression "
- "function because \"debug\" was requested.\n"
- "Use \"thread return -x\" to return to the state before expression evaluation.");
- return execution_result;
- }
- else if (execution_result != lldb::eExpressionCompleted)
- {
- error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
- return execution_result;
- }
- }
- if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
- {
- return lldb::eExpressionCompleted;
- }
- else
- {
- return lldb::eExpressionResultUnavailable;
- }
- }
- else
- {
- error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
- return lldb::eExpressionSetupError;
}
+ return true;
}
-lldb::ExpressionResults
-ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions& options,
- const char *expr_cstr,
- const char *expr_prefix,
- lldb::ValueObjectSP &result_valobj_sp,
- Error &error)
+void
+ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory)
{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-
- lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
- const lldb::LanguageType language = options.GetLanguage();
- const ResultType desired_type = options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny;
- lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
-
- Process *process = exe_ctx.GetProcessPtr();
-
- if (process == NULL || process->GetState() != lldb::eStateStopped)
- {
- if (execution_policy == eExecutionPolicyAlways)
- {
- if (log)
- log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
-
- error.SetErrorString ("expression needed to run but couldn't");
-
- return execution_results;
- }
- }
-
- if (process == NULL || !process->CanJIT())
- execution_policy = eExecutionPolicyNever;
-
- const char *full_prefix = NULL;
- const char *option_prefix = options.GetPrefix();
- std::string full_prefix_storage;
- if (expr_prefix && option_prefix)
- {
- full_prefix_storage.assign(expr_prefix);
- full_prefix_storage.append(option_prefix);
- if (!full_prefix_storage.empty())
- full_prefix = full_prefix_storage.c_str();
- }
- else if (expr_prefix)
- full_prefix = expr_prefix;
- else
- full_prefix = option_prefix;
-
- lldb::ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, full_prefix, language, desired_type));
-
- StreamString error_stream;
-
- if (log)
- log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
-
- const bool keep_expression_in_memory = true;
- const bool generate_debug_info = options.GetGenerateDebugInfo();
-
- if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
- {
- error.SetErrorString ("expression interrupted by callback before parse");
- result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
- return lldb::eExpressionInterrupted;
- }
-
- if (!user_expression_sp->Parse (error_stream,
- exe_ctx,
- execution_policy,
- keep_expression_in_memory,
- generate_debug_info))
- {
- execution_results = lldb::eExpressionParseError;
- if (error_stream.GetString().empty())
- error.SetExpressionError (execution_results, "expression failed to parse, unknown error");
- else
- error.SetExpressionError (execution_results, error_stream.GetString().c_str());
- }
- else
- {
- lldb::ExpressionVariableSP expr_result;
-
- if (execution_policy == eExecutionPolicyNever &&
- !user_expression_sp->CanInterpret())
- {
- if (log)
- log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
-
- if (error_stream.GetString().empty())
- error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't");
- }
- else
- {
- if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
- {
- error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution");
- result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
- return lldb::eExpressionInterrupted;
- }
-
- error_stream.GetString().clear();
-
- if (log)
- log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
-
- execution_results = user_expression_sp->Execute (error_stream,
- exe_ctx,
- options,
- user_expression_sp,
- expr_result);
-
- if (options.GetResultIsInternal() && expr_result && process)
- {
- process->GetTarget().GetPersistentVariables().RemovePersistentVariable (expr_result);
- }
-
- if (execution_results != lldb::eExpressionCompleted)
- {
- if (log)
- log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
-
- if (error_stream.GetString().empty())
- error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
- else
- error.SetExpressionError (execution_results, error_stream.GetString().c_str());
- }
- else
- {
- if (expr_result)
- {
- result_valobj_sp = expr_result->GetValueObject();
-
- if (log)
- log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==",
- result_valobj_sp->GetValueAsCString());
- }
- else
- {
- if (log)
- log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
-
- error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
- }
- }
- }
- }
-
- if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
- {
- error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete");
- return lldb::eExpressionInterrupted;
- }
+ m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
+}
- if (result_valobj_sp.get() == NULL)
- {
- result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
- }
+clang::ASTConsumer *
+ClangUserExpression::ClangUserExpressionHelper::ASTTransformer (clang::ASTConsumer *passthrough)
+{
+ m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough,
+ m_target));
- return execution_results;
+ return m_result_synthesizer_up.get();
}
+
diff --git a/lldb/source/Expression/ClangUtilityFunction.cpp b/lldb/source/Expression/ClangUtilityFunction.cpp
index de5b0c1b03f..2a07a428803 100644
--- a/lldb/source/Expression/ClangUtilityFunction.cpp
+++ b/lldb/source/Expression/ClangUtilityFunction.cpp
@@ -40,29 +40,15 @@ using namespace lldb_private;
/// @param[in] name
/// The name of the function, as used in the text.
//------------------------------------------------------------------
-ClangUtilityFunction::ClangUtilityFunction (const char *text,
+ClangUtilityFunction::ClangUtilityFunction (ExecutionContextScope &exe_scope,
+ const char *text,
const char *name) :
- ClangExpression (),
- m_expr_decl_map (),
- m_execution_unit_sp (),
- m_jit_module_wp (),
- m_function_text (ExpressionSourceCode::g_expression_prefix),
- m_function_name (name)
+ UtilityFunction (exe_scope, text, name)
{
- if (text && text[0])
- m_function_text.append (text);
}
ClangUtilityFunction::~ClangUtilityFunction ()
{
- lldb::ProcessSP process_sp (m_jit_process_wp.lock());
- if (process_sp)
- {
- lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
- if (jit_module_sp)
- process_sp->GetTarget().GetImages().Remove(jit_module_sp);
- }
-
}
//------------------------------------------------------------------
@@ -113,9 +99,9 @@ ClangUtilityFunction::Install (Stream &error_stream,
bool keep_result_in_memory = false;
- m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
+ ResetDeclMap(exe_ctx, keep_result_in_memory);
- if (!m_expr_decl_map->WillParse(exe_ctx, NULL))
+ if (!DeclMap()->WillParse(exe_ctx, NULL))
{
error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
return false;
@@ -130,7 +116,7 @@ ClangUtilityFunction::Install (Stream &error_stream,
{
error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
- m_expr_decl_map.reset();
+ ResetDeclMap();
return false;
}
@@ -176,9 +162,9 @@ ClangUtilityFunction::Install (Stream &error_stream,
m_function_text.c_str());
#endif
- m_expr_decl_map->DidParse();
+ DeclMap()->DidParse();
- m_expr_decl_map.reset();
+ ResetDeclMap();
if (jit_error.Success())
{
@@ -195,4 +181,8 @@ ClangUtilityFunction::Install (Stream &error_stream,
}
}
-
+void
+ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory)
+{
+ m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
+}
diff --git a/lldb/source/Expression/Expression.cpp b/lldb/source/Expression/Expression.cpp
new file mode 100644
index 00000000000..e5dd9c03db7
--- /dev/null
+++ b/lldb/source/Expression/Expression.cpp
@@ -0,0 +1,32 @@
+//===-- Expression.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Expression/Expression.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb_private;
+
+Expression::Expression (Target &target) :
+ m_target_wp (target.shared_from_this()),
+ m_jit_start_addr (LLDB_INVALID_ADDRESS),
+ m_jit_end_addr (LLDB_INVALID_ADDRESS)
+{
+ // Can't make any kind of expression without a target.
+ assert (m_target_wp.lock());
+}
+
+Expression::Expression (ExecutionContextScope &exe_scope) :
+ m_target_wp (exe_scope.CalculateTarget()),
+ m_jit_start_addr (LLDB_INVALID_ADDRESS),
+ m_jit_end_addr (LLDB_INVALID_ADDRESS)
+{
+ assert (m_target_wp.lock());
+}
+
diff --git a/lldb/source/Expression/ClangFunction.cpp b/lldb/source/Expression/FunctionCaller.cpp
index 3798c212059..acfc71c146e 100644
--- a/lldb/source/Expression/ClangFunction.cpp
+++ b/lldb/source/Expression/FunctionCaller.cpp
@@ -1,4 +1,4 @@
-//===-- ClangFunction.cpp ---------------------------------------*- C++ -*-===//
+//===-- FunctionCaller.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -30,7 +30,7 @@
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Expression/ASTStructExtractor.h"
#include "lldb/Expression/ClangExpressionParser.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -47,9 +47,9 @@
using namespace lldb_private;
//----------------------------------------------------------------------
-// ClangFunction constructor
+// FunctionCaller constructor
//----------------------------------------------------------------------
-ClangFunction::ClangFunction
+FunctionCaller::FunctionCaller
(
ExecutionContextScope &exe_scope,
const CompilerType &return_type,
@@ -57,6 +57,7 @@ ClangFunction::ClangFunction
const ValueList &arg_value_list,
const char *name
) :
+ Expression (exe_scope),
m_execution_unit_sp(),
m_parser(),
m_jit_module_wp(),
@@ -72,41 +73,14 @@ ClangFunction::ClangFunction
m_JITted (false)
{
m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
- // Can't make a ClangFunction without a process.
+ // Can't make a FunctionCaller without a process.
assert (m_jit_process_wp.lock());
}
-ClangFunction::ClangFunction
-(
- ExecutionContextScope &exe_scope,
- Function &function,
- ClangASTContext *ast_context,
- const ValueList &arg_value_list,
- const char *name
-) :
- m_name (name ? name : "<unknown>"),
- m_function_ptr (&function),
- m_function_addr (),
- m_function_return_type (),
- m_wrapper_function_name ("__lldb_function_caller"),
- m_wrapper_struct_name ("__lldb_caller_struct"),
- m_wrapper_args_addrs (),
- m_arg_values (arg_value_list),
- m_compiled (false),
- m_JITted (false)
-{
- m_jit_process_wp = exe_scope.CalculateProcess();
- // Can't make a ClangFunction without a process.
- assert (m_jit_process_wp.lock());
-
- m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
- m_function_return_type = m_function_ptr->GetCompilerType().GetFunctionReturnType();
-}
-
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ClangFunction::~ClangFunction()
+FunctionCaller::~FunctionCaller()
{
lldb::ProcessSP process_sp (m_jit_process_wp.lock());
if (process_sp)
@@ -117,147 +91,8 @@ ClangFunction::~ClangFunction()
}
}
-unsigned
-ClangFunction::CompileFunction (Stream &errors)
-{
- if (m_compiled)
- return 0;
-
- // FIXME: How does clang tell us there's no return value? We need to handle that case.
- unsigned num_errors = 0;
-
- std::string return_type_str (m_function_return_type.GetTypeName().AsCString(""));
-
- // Cons up the function we're going to wrap our call in, then compile it...
- // We declare the function "extern "C"" because the compiler might be in C++
- // mode which would mangle the name and then we couldn't find it again...
- m_wrapper_function_text.clear();
- m_wrapper_function_text.append ("extern \"C\" void ");
- m_wrapper_function_text.append (m_wrapper_function_name);
- m_wrapper_function_text.append (" (void *input)\n{\n struct ");
- m_wrapper_function_text.append (m_wrapper_struct_name);
- m_wrapper_function_text.append (" \n {\n");
- m_wrapper_function_text.append (" ");
- m_wrapper_function_text.append (return_type_str);
- m_wrapper_function_text.append (" (*fn_ptr) (");
-
- // Get the number of arguments. If we have a function type and it is prototyped,
- // trust that, otherwise use the values we were given.
-
- // FIXME: This will need to be extended to handle Variadic functions. We'll need
- // to pull the defined arguments out of the function, then add the types from the
- // arguments list for the variable arguments.
-
- uint32_t num_args = UINT32_MAX;
- bool trust_function = false;
- // GetArgumentCount returns -1 for an unprototyped function.
- CompilerType function_clang_type;
- if (m_function_ptr)
- {
- function_clang_type = m_function_ptr->GetCompilerType();
- if (function_clang_type)
- {
- int num_func_args = function_clang_type.GetFunctionArgumentCount();
- if (num_func_args >= 0)
- {
- trust_function = true;
- num_args = num_func_args;
- }
- }
- }
-
- if (num_args == UINT32_MAX)
- num_args = m_arg_values.GetSize();
-
- std::string args_buffer; // This one stores the definition of all the args in "struct caller".
- std::string args_list_buffer; // This one stores the argument list called from the structure.
- for (size_t i = 0; i < num_args; i++)
- {
- std::string type_name;
-
- if (trust_function)
- {
- type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i).GetTypeName().AsCString("");
- }
- else
- {
- CompilerType clang_qual_type = m_arg_values.GetValueAtIndex(i)->GetCompilerType ();
- if (clang_qual_type)
- {
- type_name = clang_qual_type.GetTypeName().AsCString("");
- }
- else
- {
- errors.Printf("Could not determine type of input value %" PRIu64 ".", (uint64_t)i);
- return 1;
- }
- }
-
- m_wrapper_function_text.append (type_name);
- if (i < num_args - 1)
- m_wrapper_function_text.append (", ");
-
- char arg_buf[32];
- args_buffer.append (" ");
- args_buffer.append (type_name);
- snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i);
- args_buffer.push_back (' ');
- args_buffer.append (arg_buf);
- args_buffer.append (";\n");
-
- args_list_buffer.append ("__lldb_fn_data->");
- args_list_buffer.append (arg_buf);
- if (i < num_args - 1)
- args_list_buffer.append (", ");
-
- }
- m_wrapper_function_text.append (");\n"); // Close off the function calling prototype.
-
- m_wrapper_function_text.append (args_buffer);
-
- m_wrapper_function_text.append (" ");
- m_wrapper_function_text.append (return_type_str);
- m_wrapper_function_text.append (" return_value;");
- m_wrapper_function_text.append ("\n };\n struct ");
- m_wrapper_function_text.append (m_wrapper_struct_name);
- m_wrapper_function_text.append ("* __lldb_fn_data = (struct ");
- m_wrapper_function_text.append (m_wrapper_struct_name);
- m_wrapper_function_text.append (" *) input;\n");
-
- m_wrapper_function_text.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
- m_wrapper_function_text.append (args_list_buffer);
- m_wrapper_function_text.append (");\n}\n");
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
-
- // Okay, now compile this expression
-
- lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
- if (jit_process_sp)
- {
- const bool generate_debug_info = true;
- m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this, generate_debug_info));
-
- num_errors = m_parser->Parse (errors);
- }
- else
- {
- errors.Printf("no process - unable to inject function");
- num_errors = 1;
- }
-
- m_compiled = (num_errors == 0);
-
- if (!m_compiled)
- return num_errors;
-
- return num_errors;
-}
-
bool
-ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
+FunctionCaller::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
{
Process *process = exe_ctx.GetProcessPtr();
@@ -310,18 +145,17 @@ ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
}
bool
-ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
+FunctionCaller::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
{
- return WriteFunctionArguments(exe_ctx, args_addr_ref, m_function_addr, m_arg_values, errors);
+ return WriteFunctionArguments(exe_ctx, args_addr_ref, m_arg_values, errors);
}
// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
bool
-ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx,
+FunctionCaller::WriteFunctionArguments (ExecutionContext &exe_ctx,
lldb::addr_t &args_addr_ref,
- Address function_address,
- ValueList &arg_values,
+ ValueList &arg_values,
Stream &errors)
{
// All the information to reconstruct the struct is provided by the
@@ -363,7 +197,7 @@ ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx,
}
// TODO: verify fun_addr needs to be a callable address
- Scalar fun_addr (function_address.GetCallableLoadAddress(exe_ctx.GetTargetPtr()));
+ Scalar fun_addr (m_function_addr.GetCallableLoadAddress(exe_ctx.GetTargetPtr()));
uint64_t first_offset = m_member_offsets[0];
process->WriteScalarToMemory(args_addr_ref + first_offset, fun_addr, process->GetAddressByteSize(), error);
@@ -404,7 +238,7 @@ ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx,
}
bool
-ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
+FunctionCaller::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
{
using namespace clang;
@@ -423,7 +257,7 @@ ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_add
}
lldb::ThreadPlanSP
-ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
+FunctionCaller::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
lldb::addr_t args_addr,
const EvaluateExpressionOptions &options,
Stream &errors)
@@ -431,7 +265,7 @@ ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
if (log)
- log->Printf("-- [ClangFunction::GetThreadPlanToCallFunction] Creating thread plan to call function \"%s\" --", m_name.c_str());
+ log->Printf("-- [FunctionCaller::GetThreadPlanToCallFunction] Creating thread plan to call function \"%s\" --", m_name.c_str());
// FIXME: Use the errors Stream for better error reporting.
Thread *thread = exe_ctx.GetThreadPtr();
@@ -458,7 +292,7 @@ ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx,
}
bool
-ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
+FunctionCaller::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
{
// Read the return value - it is the last field in the struct:
// FIXME: How does clang tell us there's no return value? We need to handle that case.
@@ -468,7 +302,7 @@ ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t arg
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
if (log)
- log->Printf("-- [ClangFunction::FetchFunctionResults] Fetching function results for \"%s\"--", m_name.c_str());
+ log->Printf("-- [FunctionCaller::FetchFunctionResults] Fetching function results for \"%s\"--", m_name.c_str());
Process *process = exe_ctx.GetProcessPtr();
@@ -492,7 +326,7 @@ ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t arg
}
void
-ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
+FunctionCaller::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
{
std::list<lldb::addr_t>::iterator pos;
pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
@@ -503,7 +337,7 @@ ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_
}
lldb::ExpressionResults
-ClangFunction::ExecuteFunction(
+FunctionCaller::ExecuteFunction(
ExecutionContext &exe_ctx,
lldb::addr_t *args_addr_ptr,
const EvaluateExpressionOptions &options,
@@ -513,7 +347,7 @@ ClangFunction::ExecuteFunction(
using namespace clang;
lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
- // ClangFunction::ExecuteFunction execution is always just to get the result. Do make sure we ignore
+ // FunctionCaller::ExecuteFunction execution is always just to get the result. Do make sure we ignore
// breakpoints, unwind on error, and don't try to debug it.
EvaluateExpressionOptions real_options = options;
real_options.SetDebug(false);
@@ -539,7 +373,7 @@ ClangFunction::ExecuteFunction(
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
if (log)
- log->Printf("== [ClangFunction::ExecuteFunction] Executing function \"%s\" ==", m_name.c_str());
+ log->Printf("== [FunctionCaller::ExecuteFunction] Executing function \"%s\" ==", m_name.c_str());
lldb::ThreadPlanSP call_plan_sp = GetThreadPlanToCallFunction (exe_ctx,
args_addr,
@@ -562,11 +396,11 @@ ClangFunction::ExecuteFunction(
{
if (return_value != lldb::eExpressionCompleted)
{
- log->Printf("== [ClangFunction::ExecuteFunction] Execution of \"%s\" completed abnormally ==", m_name.c_str());
+ log->Printf("== [FunctionCaller::ExecuteFunction] Execution of \"%s\" completed abnormally ==", m_name.c_str());
}
else
{
- log->Printf("== [ClangFunction::ExecuteFunction] Execution of \"%s\" completed normally ==", m_name.c_str());
+ log->Printf("== [FunctionCaller::ExecuteFunction] Execution of \"%s\" completed normally ==", m_name.c_str());
}
}
@@ -586,11 +420,3 @@ ClangFunction::ExecuteFunction(
return lldb::eExpressionCompleted;
}
-
-clang::ASTConsumer *
-ClangFunction::ASTTransformer (clang::ASTConsumer *passthrough)
-{
- m_struct_extractor.reset(new ASTStructExtractor(passthrough, m_wrapper_struct_name.c_str(), *this));
-
- return m_struct_extractor.get();
-}
diff --git a/lldb/source/Expression/IRDynamicChecks.cpp b/lldb/source/Expression/IRDynamicChecks.cpp
index aa5d28bb8aa..5c8d0e5288b 100644
--- a/lldb/source/Expression/IRDynamicChecks.cpp
+++ b/lldb/source/Expression/IRDynamicChecks.cpp
@@ -11,11 +11,12 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Constants.h"
@@ -52,8 +53,14 @@ bool
DynamicCheckerFunctions::Install(Stream &error_stream,
ExecutionContext &exe_ctx)
{
- m_valid_pointer_check.reset(new ClangUtilityFunction(g_valid_pointer_check_text,
- VALID_POINTER_CHECK_NAME));
+ Error error;
+ m_valid_pointer_check.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_valid_pointer_check_text,
+ lldb::eLanguageTypeC,
+ VALID_POINTER_CHECK_NAME,
+ error));
+ if (error.Fail())
+ return false;
+
if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
return false;
diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp
new file mode 100644
index 00000000000..547c02a1317
--- /dev/null
+++ b/lldb/source/Expression/UserExpression.cpp
@@ -0,0 +1,644 @@
+//===-- UserExpression.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <cstdlib>
+#include <string>
+#include <map>
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Expression/ASTResultSynthesizer.h"
+#include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "lldb/Expression/ClangExpressionParser.h"
+#include "lldb/Expression/ClangModulesDeclVendor.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
+#include "lldb/Expression/ExpressionSourceCode.h"
+#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Expression/IRInterpreter.h"
+#include "lldb/Expression/Materializer.h"
+#include "lldb/Expression/UserExpression.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanCallUserExpression.h"
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+
+using namespace lldb_private;
+
+UserExpression::UserExpression (ExecutionContextScope &exe_scope,
+ const char *expr,
+ const char *expr_prefix,
+ lldb::LanguageType language,
+ ResultType desired_type) :
+ Expression (exe_scope),
+ m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
+ m_stack_frame_top (LLDB_INVALID_ADDRESS),
+ m_expr_text (expr),
+ m_expr_prefix (expr_prefix ? expr_prefix : ""),
+ m_language (language),
+ m_transformed_text (),
+ m_desired_type (desired_type),
+ m_execution_unit_sp(),
+ m_materializer_ap(),
+ m_jit_module_wp(),
+ m_enforce_valid_object (true),
+ m_in_cplusplus_method (false),
+ m_in_objectivec_method (false),
+ m_in_static_method(false),
+ m_needs_object_ptr (false),
+ m_const_object (false),
+ m_target (NULL),
+ m_can_interpret (false),
+ m_materialized_address (LLDB_INVALID_ADDRESS)
+{
+}
+
+UserExpression::~UserExpression ()
+{
+ if (m_target)
+ {
+ lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
+ if (jit_module_sp)
+ m_target->GetImages().Remove(jit_module_sp);
+ }
+}
+
+void
+UserExpression::InstallContext (ExecutionContext &exe_ctx)
+{
+ m_jit_process_wp = exe_ctx.GetProcessSP();
+
+ lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
+
+ if (frame_sp)
+ m_address = frame_sp->GetFrameCodeAddress();
+}
+
+bool
+UserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
+ lldb::TargetSP &target_sp,
+ lldb::ProcessSP &process_sp,
+ lldb::StackFrameSP &frame_sp)
+{
+ lldb::ProcessSP expected_process_sp = m_jit_process_wp.lock();
+ process_sp = exe_ctx.GetProcessSP();
+
+ if (process_sp != expected_process_sp)
+ return false;
+
+ process_sp = exe_ctx.GetProcessSP();
+ target_sp = exe_ctx.GetTargetSP();
+ frame_sp = exe_ctx.GetFrameSP();
+
+ if (m_address.IsValid())
+ {
+ if (!frame_sp)
+ return false;
+ else
+ return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
+ }
+
+ return true;
+}
+
+bool
+UserExpression::MatchesContext (ExecutionContext &exe_ctx)
+{
+ lldb::TargetSP target_sp;
+ lldb::ProcessSP process_sp;
+ lldb::StackFrameSP frame_sp;
+
+ return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
+}
+
+lldb::addr_t
+UserExpression::GetObjectPointer (lldb::StackFrameSP frame_sp,
+ ConstString &object_name,
+ Error &err)
+{
+ err.Clear();
+
+ if (!frame_sp)
+ {
+ err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ lldb::VariableSP var_sp;
+ lldb::ValueObjectSP valobj_sp;
+
+ valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
+ lldb::eNoDynamicValues,
+ StackFrame::eExpressionPathOptionCheckPtrVsMember |
+ StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
+ StackFrame::eExpressionPathOptionsNoSyntheticChildren |
+ StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
+ var_sp,
+ err);
+
+ if (!err.Success() || !valobj_sp.get())
+ return LLDB_INVALID_ADDRESS;
+
+ lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+
+ if (ret == LLDB_INVALID_ADDRESS)
+ {
+ err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ return ret;
+}
+
+bool
+UserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
+ ExecutionContext &exe_ctx,
+ lldb::addr_t &struct_address)
+{
+ lldb::TargetSP target;
+ lldb::ProcessSP process;
+ lldb::StackFrameSP frame;
+
+ if (!LockAndCheckContext(exe_ctx,
+ target,
+ process,
+ frame))
+ {
+ error_stream.Printf("The context has changed before we could JIT the expression!\n");
+ return false;
+ }
+
+ if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
+ {
+ if (m_materialized_address == LLDB_INVALID_ADDRESS)
+ {
+ Error alloc_error;
+
+ IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
+
+ m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(),
+ m_materializer_ap->GetStructAlignment(),
+ lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+ policy,
+ alloc_error);
+
+ if (!alloc_error.Success())
+ {
+ error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
+ return false;
+ }
+ }
+
+ struct_address = m_materialized_address;
+
+ if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
+ {
+ Error alloc_error;
+
+ const size_t stack_frame_size = 512 * 1024;
+
+ m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size,
+ 8,
+ lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+ IRMemoryMap::eAllocationPolicyHostOnly,
+ alloc_error);
+
+ m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
+
+ if (!alloc_error.Success())
+ {
+ error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
+ return false;
+ }
+ }
+
+ Error materialize_error;
+
+ m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error);
+
+ if (!materialize_error.Success())
+ {
+ error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString());
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+UserExpression::FinalizeJITExecution (Stream &error_stream,
+ ExecutionContext &exe_ctx,
+ lldb::ExpressionVariableSP &result,
+ lldb::addr_t function_stack_bottom,
+ lldb::addr_t function_stack_top)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ log->Printf("-- [UserExpression::FinalizeJITExecution] Dematerializing after execution --");
+
+ if (!m_dematerializer_sp)
+ {
+ error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
+ return false;
+ }
+
+ Error dematerialize_error;
+
+ m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
+
+ if (!dematerialize_error.Success())
+ {
+ error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
+ return false;
+ }
+
+ if (result)
+ result->TransferAddress();
+
+ m_dematerializer_sp.reset();
+
+ return true;
+}
+
+lldb::ExpressionResults
+UserExpression::Execute (Stream &error_stream,
+ ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions& options,
+ lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result)
+{
+ // The expression log is quite verbose, and if you're just tracking the execution of the
+ // expression, it's quite convenient to have these logs come out with the STEP log as well.
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+
+ if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
+ {
+ lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
+
+ if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address))
+ {
+ error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
+ return lldb::eExpressionSetupError;
+ }
+
+ lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
+ lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
+
+ if (m_can_interpret)
+ {
+ llvm::Module *module = m_execution_unit_sp->GetModule();
+ llvm::Function *function = m_execution_unit_sp->GetFunction();
+
+ if (!module || !function)
+ {
+ error_stream.Printf("Supposed to interpret, but nothing is there");
+ return lldb::eExpressionSetupError;
+ }
+
+ Error interpreter_error;
+
+ std::vector<lldb::addr_t> args;
+
+ if (!AddInitialArguments(exe_ctx, args, error_stream))
+ {
+ error_stream.Printf ("Errored out in %s, couldn't AddInitialArguments", __FUNCTION__);
+ return lldb::eExpressionSetupError;
+ }
+
+ args.push_back(struct_address);
+
+ function_stack_bottom = m_stack_frame_bottom;
+ function_stack_top = m_stack_frame_top;
+
+ IRInterpreter::Interpret (*module,
+ *function,
+ args,
+ *m_execution_unit_sp.get(),
+ interpreter_error,
+ function_stack_bottom,
+ function_stack_top,
+ exe_ctx);
+
+ if (!interpreter_error.Success())
+ {
+ error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
+ return lldb::eExpressionDiscarded;
+ }
+ }
+ else
+ {
+ if (!exe_ctx.HasThreadScope())
+ {
+ error_stream.Printf("UserExpression::Execute called with no thread selected.");
+ return lldb::eExpressionSetupError;
+ }
+
+ Address wrapper_address (m_jit_start_addr);
+
+ std::vector<lldb::addr_t> args;
+
+ if (!AddInitialArguments(exe_ctx, args, error_stream))
+ {
+ error_stream.Printf ("Errored out in %s, couldn't AddInitialArguments", __FUNCTION__);
+ return lldb::eExpressionSetupError;
+ }
+
+ args.push_back(struct_address);
+
+ lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
+ wrapper_address,
+ args,
+ options,
+ shared_ptr_to_me));
+
+ if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
+ return lldb::eExpressionSetupError;
+
+ ThreadPlanCallUserExpression *user_expression_plan = static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());
+
+ lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer();
+
+ function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
+ function_stack_top = function_stack_pointer;
+
+ if (log)
+ log->Printf("-- [UserExpression::Execute] Execution of expression begins --");
+
+ if (exe_ctx.GetProcessPtr())
+ exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
+
+ lldb::ExpressionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
+ call_plan_sp,
+ options,
+ error_stream);
+
+ if (exe_ctx.GetProcessPtr())
+ exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
+
+ if (log)
+ log->Printf("-- [UserExpression::Execute] Execution of expression completed --");
+
+ if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint)
+ {
+ const char *error_desc = NULL;
+
+ if (call_plan_sp)
+ {
+ lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
+ if (real_stop_info_sp)
+ error_desc = real_stop_info_sp->GetDescription();
+ }
+ if (error_desc)
+ error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
+ else
+ error_stream.PutCString ("Execution was interrupted.");
+
+ if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError())
+ || (execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints()))
+ error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
+ else
+ {
+ if (execution_result == lldb::eExpressionHitBreakpoint)
+ user_expression_plan->TransferExpressionOwnership();
+ error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, "
+ "use \"thread return -x\" to return to the state before expression evaluation.");
+ }
+
+ return execution_result;
+ }
+ else if (execution_result == lldb::eExpressionStoppedForDebug)
+ {
+ error_stream.PutCString ("Execution was halted at the first instruction of the expression "
+ "function because \"debug\" was requested.\n"
+ "Use \"thread return -x\" to return to the state before expression evaluation.");
+ return execution_result;
+ }
+ else if (execution_result != lldb::eExpressionCompleted)
+ {
+ error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
+ return execution_result;
+ }
+ }
+
+ if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
+ {
+ return lldb::eExpressionCompleted;
+ }
+ else
+ {
+ return lldb::eExpressionResultUnavailable;
+ }
+ }
+ else
+ {
+ error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
+ return lldb::eExpressionSetupError;
+ }
+}
+
+lldb::ExpressionResults
+UserExpression::Evaluate (ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions& options,
+ const char *expr_cstr,
+ const char *expr_prefix,
+ lldb::ValueObjectSP &result_valobj_sp,
+ Error &error)
+{
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+
+ lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
+ const lldb::LanguageType language = options.GetLanguage();
+ const ResultType desired_type = options.DoesCoerceToId() ? UserExpression::eResultTypeId : UserExpression::eResultTypeAny;
+ lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
+
+ Target *target = exe_ctx.GetTargetPtr();
+ if (!target)
+ {
+ if (log)
+ log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't run expressions.");
+ return lldb::eExpressionSetupError;
+ }
+
+ Process *process = exe_ctx.GetProcessPtr();
+
+ if (process == NULL || process->GetState() != lldb::eStateStopped)
+ {
+ if (execution_policy == eExecutionPolicyAlways)
+ {
+ if (log)
+ log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
+
+ error.SetErrorString ("expression needed to run but couldn't");
+
+ return execution_results;
+ }
+ }
+
+ if (process == NULL || !process->CanJIT())
+ execution_policy = eExecutionPolicyNever;
+
+ const char *full_prefix = NULL;
+ const char *option_prefix = options.GetPrefix();
+ std::string full_prefix_storage;
+ if (expr_prefix && option_prefix)
+ {
+ full_prefix_storage.assign(expr_prefix);
+ full_prefix_storage.append(option_prefix);
+ if (!full_prefix_storage.empty())
+ full_prefix = full_prefix_storage.c_str();
+ }
+ else if (expr_prefix)
+ full_prefix = expr_prefix;
+ else
+ full_prefix = option_prefix;
+
+ lldb::UserExpressionSP user_expression_sp(target->GetUserExpressionForLanguage (expr_cstr,
+ full_prefix,
+ language,
+ desired_type,
+ error));
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf ("== [UserExpression::Evaluate] Getting expression: %s ==", error.AsCString());
+ return lldb::eExpressionSetupError;
+ }
+
+ StreamString error_stream;
+
+ if (log)
+ log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
+
+ const bool keep_expression_in_memory = true;
+ const bool generate_debug_info = options.GetGenerateDebugInfo();
+
+ if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
+ {
+ error.SetErrorString ("expression interrupted by callback before parse");
+ result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
+ return lldb::eExpressionInterrupted;
+ }
+
+ if (!user_expression_sp->Parse (error_stream,
+ exe_ctx,
+ execution_policy,
+ keep_expression_in_memory,
+ generate_debug_info))
+ {
+ execution_results = lldb::eExpressionParseError;
+ if (error_stream.GetString().empty())
+ error.SetExpressionError (execution_results, "expression failed to parse, unknown error");
+ else
+ error.SetExpressionError (execution_results, error_stream.GetString().c_str());
+ }
+ else
+ {
+ lldb::ExpressionVariableSP expr_result;
+
+ if (execution_policy == eExecutionPolicyNever &&
+ !user_expression_sp->CanInterpret())
+ {
+ if (log)
+ log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
+
+ if (error_stream.GetString().empty())
+ error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't");
+ }
+ else
+ {
+ if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
+ {
+ error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution");
+ result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
+ return lldb::eExpressionInterrupted;
+ }
+
+ error_stream.GetString().clear();
+
+ if (log)
+ log->Printf("== [UserExpression::Evaluate] Executing expression ==");
+
+ execution_results = user_expression_sp->Execute (error_stream,
+ exe_ctx,
+ options,
+ user_expression_sp,
+ expr_result);
+
+ if (options.GetResultIsInternal() && expr_result && process)
+ {
+ process->GetTarget().GetPersistentVariables().RemovePersistentVariable (expr_result);
+ }
+
+ if (execution_results != lldb::eExpressionCompleted)
+ {
+ if (log)
+ log->Printf("== [UserExpression::Evaluate] Execution completed abnormally ==");
+
+ if (error_stream.GetString().empty())
+ error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
+ else
+ error.SetExpressionError (execution_results, error_stream.GetString().c_str());
+ }
+ else
+ {
+ if (expr_result)
+ {
+ result_valobj_sp = expr_result->GetValueObject();
+
+ if (log)
+ log->Printf("== [UserExpression::Evaluate] Execution completed normally with result %s ==",
+ result_valobj_sp->GetValueAsCString());
+ }
+ else
+ {
+ if (log)
+ log->Printf("== [UserExpression::Evaluate] Execution completed normally with no result ==");
+
+ error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
+ }
+ }
+ }
+ }
+
+ if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
+ {
+ error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete");
+ return lldb::eExpressionInterrupted;
+ }
+
+ if (result_valobj_sp.get() == NULL)
+ {
+ result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
+ }
+
+ return execution_results;
+}
diff --git a/lldb/source/Expression/UtilityFunction.cpp b/lldb/source/Expression/UtilityFunction.cpp
new file mode 100644
index 00000000000..fad6e2f2568
--- /dev/null
+++ b/lldb/source/Expression/UtilityFunction.cpp
@@ -0,0 +1,123 @@
+//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+// C++ Includes
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
+#include "lldb/Expression/ExpressionSourceCode.h"
+#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+//------------------------------------------------------------------
+/// Constructor
+///
+/// @param[in] text
+/// The text of the function. Must be a full translation unit.
+///
+/// @param[in] name
+/// The name of the function, as used in the text.
+//------------------------------------------------------------------
+UtilityFunction::UtilityFunction (ExecutionContextScope &exe_scope,
+ const char *text,
+ const char *name) :
+ Expression (exe_scope),
+ m_execution_unit_sp (),
+ m_jit_module_wp (),
+ m_function_text (ExpressionSourceCode::g_expression_prefix),
+ m_function_name (name)
+{
+ if (text && text[0])
+ m_function_text.append (text);
+}
+
+UtilityFunction::~UtilityFunction ()
+{
+ lldb::ProcessSP process_sp (m_jit_process_wp.lock());
+ if (process_sp)
+ {
+ lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
+ if (jit_module_sp)
+ process_sp->GetTarget().GetImages().Remove(jit_module_sp);
+ }
+
+}
+
+// FIXME: We should check that every time this is called it is called with the same return type & arguments...
+
+FunctionCaller *
+UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const ValueList &arg_value_list, Error &error)
+{
+ if (m_caller_up)
+ return m_caller_up.get();
+
+ ProcessSP process_sp = m_jit_process_wp.lock();
+ if (!process_sp)
+ return nullptr;
+
+ Address impl_code_address;
+ impl_code_address.SetOffset(StartAddress());
+ std::string name(m_function_name);
+ name.append("-caller");
+
+ m_caller_up.reset (process_sp->GetTarget().GetFunctionCallerForLanguage (Language(),
+ return_type,
+ impl_code_address,
+ arg_value_list,
+ name.c_str(),
+ error));
+ if (error.Fail())
+ {
+
+ return nullptr;
+ }
+ if (m_caller_up)
+ {
+ StreamString errors;
+ errors.Clear();
+ unsigned num_errors = m_caller_up->CompileFunction(errors);
+ if (num_errors)
+ {
+ error.SetErrorStringWithFormat ("Error compiling %s caller function: \"%s\".",
+ m_function_name.c_str(),
+ errors.GetData());
+ m_caller_up.reset();
+ return nullptr;
+ }
+
+ errors.Clear();
+ ExecutionContext exe_ctx(process_sp);
+
+ if (!m_caller_up->WriteFunctionWrapper(exe_ctx, errors))
+ {
+ error.SetErrorStringWithFormat ("Error inserting caller function for %s: \"%s\".",
+ m_function_name.c_str(),
+ errors.GetData());
+ m_caller_up.reset();
+ return nullptr;
+ }
+ }
+ return m_caller_up.get();
+}
diff --git a/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp b/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
index bc7a93314c4..14123af27ca 100644
--- a/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
+++ b/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
@@ -25,7 +25,7 @@ lldb_private::formatters::CMTimeSummaryProvider (ValueObject& valobj, Stream& st
if (!type.IsValid())
return false;
- TypeSystem *type_system = valobj.GetExecutionContextRef().GetTargetSP()->GetTypeSystemForLanguage(lldb::eLanguageTypeC);
+ TypeSystem *type_system = valobj.GetExecutionContextRef().GetTargetSP()->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC);
if (!type_system)
return false;
diff --git a/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/lldb/source/Plugins/Language/ObjC/NSArray.cpp
index d5466ed4c8d..c6db27e93d4 100644
--- a/lldb/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSArray.cpp
@@ -15,6 +15,7 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 7a519532036..925e49883b5 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -8,7 +8,9 @@
//===----------------------------------------------------------------------===//
#include "AppleObjCClassDescriptorV2.h"
+
#include "lldb/Core/Log.h"
+#include "lldb/Expression/FunctionCaller.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 81ae61841ae..b4b725ea3cc 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -1,4 +1,4 @@
-//===-- AppleObjCRuntime.cpp --------------------------------------*- C++ -*-===//
+//===-- AppleObjCRuntime.cpp -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -22,7 +22,8 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ExecutionContext.h"
@@ -39,6 +40,10 @@ using namespace lldb_private;
#define PO_FUNCTION_TIMEOUT_USEC 15*1000*1000
+AppleObjCRuntime::~AppleObjCRuntime()
+{
+}
+
AppleObjCRuntime::AppleObjCRuntime(Process *process) :
ObjCLanguageRuntime (process),
m_read_objc_library (false),
@@ -135,16 +140,36 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon
}
// Now we're ready to call the function:
- ClangFunction func (*exe_ctx.GetBestExecutionContextScope(),
- return_clang_type,
- *function_address,
- arg_value_list,
- "objc-object-description");
-
- StreamString error_stream;
+ StreamString error_stream;
lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
- func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
+
+ if (!m_print_object_caller_up)
+ {
+ Error error;
+ m_print_object_caller_up.reset(exe_scope->CalculateTarget()->GetFunctionCallerForLanguage (eLanguageTypeObjC,
+ return_clang_type,
+ *function_address,
+ arg_value_list,
+ "objc-object-description",
+ error));
+ if (error.Fail())
+ {
+ m_print_object_caller_up.reset();
+ strm.Printf("Could not get function runner to call print for debugger function: %s.", error.AsCString());
+ return false;
+ }
+ m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
+ }
+ else
+ {
+ m_print_object_caller_up->WriteFunctionArguments(exe_ctx,
+ wrapper_struct_addr,
+ arg_value_list,
+ error_stream);
+ }
+
+
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
@@ -153,11 +178,11 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon
options.SetIgnoreBreakpoints(true);
options.SetTimeoutUsec(PO_FUNCTION_TIMEOUT_USEC);
- ExpressionResults results = func.ExecuteFunction (exe_ctx,
- &wrapper_struct_addr,
- options,
- error_stream,
- ret);
+ ExpressionResults results = m_print_object_caller_up->ExecuteFunction (exe_ctx,
+ &wrapper_struct_addr,
+ options,
+ error_stream,
+ ret);
if (results != eExpressionCompleted)
{
strm.Printf("Error evaluating Print Object function: %d.\n", results);
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
index f8f73bae865..424058ee0b7 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
@@ -20,7 +20,6 @@
#include "lldb/lldb-private.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Core/ValueObject.h"
#include "AppleObjCTrampolineHandler.h"
#include "AppleThreadPlanStepThroughObjCTrampoline.h"
@@ -31,7 +30,7 @@ class AppleObjCRuntime :
{
public:
- virtual ~AppleObjCRuntime() { }
+ virtual ~AppleObjCRuntime();
// These are generic runtime functions:
bool
@@ -127,6 +126,7 @@ protected:
std::unique_ptr<lldb_private::AppleObjCTrampolineHandler> m_objc_trampoline_handler_ap;
lldb::BreakpointSP m_objc_exception_bp_sp;
lldb::ModuleWP m_objc_module_wp;
+ std::unique_ptr<FunctionCaller> m_print_object_caller_up;
llvm::Optional<uint32_t> m_Foundation_major;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 17aa03e4a64..85729e827f5 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -21,8 +21,8 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
@@ -143,7 +143,7 @@ struct BufStruct {
char contents[2048];
};
-ClangUtilityFunction *
+UtilityFunction *
AppleObjCRuntimeV1::CreateObjectChecker(const char *name)
{
std::unique_ptr<BufStruct> buf(new BufStruct);
@@ -170,7 +170,8 @@ AppleObjCRuntimeV1::CreateObjectChecker(const char *name)
"} \n",
name) < (int)sizeof(buf->contents));
- return new ClangUtilityFunction(buf->contents, name);
+ Error error;
+ return GetTargetRef().GetUtilityFunctionForLanguage(buf->contents, eLanguageTypeObjC, name, error);
}
AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ValueObject &isa_pointer)
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
index f98f065f6a7..73e8607286f 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
@@ -102,7 +102,7 @@ public:
TypeAndOrName &class_type_or_name,
Address &address);
- virtual ClangUtilityFunction *
+ virtual UtilityFunction *
CreateObjectChecker (const char *);
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 4817d57a353..ac643064415 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -28,8 +28,8 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObjectVariable.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
@@ -348,11 +348,9 @@ ExtractRuntimeGlobalSymbol (Process* process,
AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process,
const ModuleSP &objc_module_sp) :
AppleObjCRuntime (process),
- m_get_class_info_function(),
m_get_class_info_code(),
m_get_class_info_args (LLDB_INVALID_ADDRESS),
m_get_class_info_args_mutex (Mutex::eMutexTypeNormal),
- m_get_shared_cache_class_info_function(),
m_get_shared_cache_class_info_code(),
m_get_shared_cache_class_info_args (LLDB_INVALID_ADDRESS),
m_get_shared_cache_class_info_args_mutex (Mutex::eMutexTypeNormal),
@@ -722,7 +720,7 @@ AppleObjCRuntimeV2::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bo
return resolver_sp;
}
-ClangUtilityFunction *
+UtilityFunction *
AppleObjCRuntimeV2::CreateObjectChecker(const char *name)
{
char check_function_code[2048];
@@ -780,7 +778,8 @@ AppleObjCRuntimeV2::CreateObjectChecker(const char *name)
assert (len < (int)sizeof(check_function_code));
- return new ClangUtilityFunction(check_function_code, name);
+ Error error;
+ return GetTargetRef().GetUtilityFunctionForLanguage(check_function_code, eLanguageTypeObjC, name, error);
}
size_t
@@ -1248,75 +1247,74 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
CompilerType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
CompilerType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+ ValueList arguments;
+ FunctionCaller *get_class_info_function = nullptr;
+
if (!m_get_class_info_code.get())
{
- m_get_class_info_code.reset (new ClangUtilityFunction (g_get_dynamic_class_info_body,
- g_get_dynamic_class_info_name));
-
- errors.Clear();
-
- if (!m_get_class_info_code->Install(errors, exe_ctx))
+ Error error;
+ m_get_class_info_code.reset (GetTargetRef().GetUtilityFunctionForLanguage (g_get_dynamic_class_info_body,
+ eLanguageTypeObjC,
+ g_get_dynamic_class_info_name,
+ error));
+ if (error.Fail())
{
if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ log->Printf ("Failed to get Utility Function for implementation lookup: %s", error.AsCString());
m_get_class_info_code.reset();
}
- }
-
- if (m_get_class_info_code.get())
- function_address.SetOffset(m_get_class_info_code->StartAddress());
- else
- return false;
-
- ValueList arguments;
-
- // Next make the runner function for our implementation utility function.
- if (!m_get_class_info_function.get())
- {
+ else
+ {
+ errors.Clear();
+
+ if (!m_get_class_info_code->Install(errors, exe_ctx))
+ {
+ if (log)
+ log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ m_get_class_info_code.reset();
+ }
+ }
+ if (!m_get_class_info_code.get())
+ return false;
+
+ // Next make the runner function for our implementation utility function.
Value value;
value.SetValueType (Value::eValueTypeScalar);
-// value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
value.SetCompilerType (clang_void_pointer_type);
arguments.PushValue (value);
arguments.PushValue (value);
value.SetValueType (Value::eValueTypeScalar);
-// value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
value.SetCompilerType (clang_uint32_t_type);
arguments.PushValue (value);
- m_get_class_info_function.reset(new ClangFunction (*m_process,
- clang_uint32_t_type,
- function_address,
- arguments,
- "objc-v2-isa-to-descriptor"));
-
- if (m_get_class_info_function.get() == NULL)
- return false;
-
- errors.Clear();
+ get_class_info_function = m_get_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
+ arguments,
+ error);
- unsigned num_errors = m_get_class_info_function->CompileFunction(errors);
- if (num_errors)
+ if (error.Fail())
{
if (log)
- log->Printf ("Error compiling function: \"%s\".", errors.GetData());
+ log->Printf("Failed to make function caller for implementation lookup: %s.", error.AsCString());
return false;
}
-
- errors.Clear();
-
- if (!m_get_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
+ }
+ else
+ {
+ get_class_info_function = m_get_class_info_code->GetFunctionCaller();
+ if (!get_class_info_function)
{
if (log)
- log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+ log->Printf ("Failed to get implementation lookup function caller: %s.", errors.GetData());
return false;
}
+ arguments = get_class_info_function->GetArgumentValues();
}
- else
- {
- arguments = m_get_class_info_function->GetArgumentValues ();
- }
+
+
+
+
+ errors.Clear();
const uint32_t class_info_byte_size = addr_size + 4;
const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
@@ -1339,9 +1337,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
errors.Clear();
// Write our function arguments into the process so we can run our function
- if (m_get_class_info_function->WriteFunctionArguments (exe_ctx,
+ if (get_class_info_function->WriteFunctionArguments (exe_ctx,
m_get_class_info_args,
- function_address,
arguments,
errors))
{
@@ -1361,11 +1358,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
errors.Clear();
// Run the function
- ExpressionResults results = m_get_class_info_function->ExecuteFunction (exe_ctx,
- &m_get_class_info_args,
- options,
- errors,
- return_value);
+ ExpressionResults results = get_class_info_function->ExecuteFunction (exe_ctx,
+ &m_get_class_info_args,
+ options,
+ errors,
+ return_value);
if (results == eExpressionCompleted)
{
@@ -1502,31 +1499,38 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
CompilerType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
CompilerType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+ ValueList arguments;
+ FunctionCaller *get_shared_cache_class_info_function = nullptr;
+
if (!m_get_shared_cache_class_info_code.get())
{
- m_get_shared_cache_class_info_code.reset (new ClangUtilityFunction (g_get_shared_cache_class_info_body,
- g_get_shared_cache_class_info_name));
-
- errors.Clear();
-
- if (!m_get_shared_cache_class_info_code->Install(errors, exe_ctx))
+ Error error;
+ m_get_shared_cache_class_info_code.reset (GetTargetRef().GetUtilityFunctionForLanguage (g_get_shared_cache_class_info_body,
+ eLanguageTypeObjC,
+ g_get_shared_cache_class_info_name,
+ error));
+ if (error.Fail())
{
if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ log->Printf ("Failed to get Utility function for implementation lookup: %s.", error.AsCString());
m_get_shared_cache_class_info_code.reset();
}
- }
-
- if (m_get_shared_cache_class_info_code.get())
- function_address.SetOffset(m_get_shared_cache_class_info_code->StartAddress());
- else
- return DescriptorMapUpdateResult::Fail();
-
- ValueList arguments;
+ else
+ {
+ errors.Clear();
+
+ if (!m_get_shared_cache_class_info_code->Install(errors, exe_ctx))
+ {
+ if (log)
+ log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ m_get_shared_cache_class_info_code.reset();
+ }
+ }
+
+ if (!m_get_shared_cache_class_info_code.get())
+ return DescriptorMapUpdateResult::Fail();
- // Next make the runner function for our implementation utility function.
- if (!m_get_shared_cache_class_info_function.get())
- {
+ // Next make the function caller for our implementation utility function.
Value value;
value.SetValueType (Value::eValueTypeScalar);
//value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
@@ -1539,39 +1543,24 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
value.SetCompilerType (clang_uint32_t_type);
arguments.PushValue (value);
- m_get_shared_cache_class_info_function.reset(new ClangFunction (*m_process,
- clang_uint32_t_type,
- function_address,
- arguments,
- "objc-isa-to-descriptor-shared-cache"));
-
- if (m_get_shared_cache_class_info_function.get() == NULL)
- return DescriptorMapUpdateResult::Fail();
-
- errors.Clear();
-
- unsigned num_errors = m_get_shared_cache_class_info_function->CompileFunction(errors);
- if (num_errors)
- {
- if (log)
- log->Printf ("Error compiling function: \"%s\".", errors.GetData());
- return DescriptorMapUpdateResult::Fail();
- }
-
- errors.Clear();
+ get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
+ arguments,
+ error);
- if (!m_get_shared_cache_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
- {
- if (log)
- log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+ if (get_shared_cache_class_info_function == nullptr)
return DescriptorMapUpdateResult::Fail();
- }
+
}
else
{
- arguments = m_get_shared_cache_class_info_function->GetArgumentValues ();
+ get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->GetFunctionCaller();
+ if (get_shared_cache_class_info_function == nullptr)
+ return DescriptorMapUpdateResult::Fail();
+ arguments = get_shared_cache_class_info_function->GetArgumentValues();
}
+ errors.Clear();
+
const uint32_t class_info_byte_size = addr_size + 4;
const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
lldb::addr_t class_infos_addr = process->AllocateMemory (class_infos_byte_size,
@@ -1594,11 +1583,10 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
errors.Clear();
// Write our function arguments into the process so we can run our function
- if (m_get_shared_cache_class_info_function->WriteFunctionArguments (exe_ctx,
- m_get_shared_cache_class_info_args,
- function_address,
- arguments,
- errors))
+ if (get_shared_cache_class_info_function->WriteFunctionArguments (exe_ctx,
+ m_get_shared_cache_class_info_args,
+ arguments,
+ errors))
{
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
@@ -1616,11 +1604,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
errors.Clear();
// Run the function
- ExpressionResults results = m_get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
- &m_get_shared_cache_class_info_args,
- options,
- errors,
- return_value);
+ ExpressionResults results = get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
+ &m_get_shared_cache_class_info_args,
+ options,
+ errors,
+ return_value);
if (results == eExpressionCompleted)
{
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 6d981f72d8c..feaf9d4d6f0 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -39,7 +39,7 @@ public:
TypeAndOrName &class_type_or_name,
Address &address);
- virtual ClangUtilityFunction *
+ virtual UtilityFunction *
CreateObjectChecker (const char *);
@@ -299,22 +299,20 @@ private:
friend class ClassDescriptorV2;
- std::unique_ptr<ClangFunction> m_get_class_info_function;
- std::unique_ptr<ClangUtilityFunction> m_get_class_info_code;
+ std::unique_ptr<UtilityFunction> m_get_class_info_code;
lldb::addr_t m_get_class_info_args;
Mutex m_get_class_info_args_mutex;
- std::unique_ptr<ClangFunction> m_get_shared_cache_class_info_function;
- std::unique_ptr<ClangUtilityFunction> m_get_shared_cache_class_info_code;
+ std::unique_ptr<UtilityFunction> m_get_shared_cache_class_info_code;
lldb::addr_t m_get_shared_cache_class_info_args;
Mutex m_get_shared_cache_class_info_args_mutex;
- std::unique_ptr<DeclVendor> m_decl_vendor_ap;
+ std::unique_ptr<DeclVendor> m_decl_vendor_ap;
lldb::addr_t m_isa_hash_table_ptr;
HashTableSignature m_hash_signature;
bool m_has_object_getClass;
bool m_loaded_objc_opt;
- std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_ap;
+ std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_ap;
std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_ap;
EncodingToTypeSP m_encoding_to_type_sp;
bool m_noclasses_warning_emitted;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index db5b7f0a406..d38a076ad5d 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -22,9 +22,9 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
@@ -741,10 +741,10 @@ lldb::addr_t
AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &dispatch_values)
{
ExecutionContext exe_ctx (thread.shared_from_this());
- Address impl_code_address;
StreamString errors;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+ FunctionCaller *impl_function_caller = nullptr;
// Scope for mutex locker:
{
@@ -752,38 +752,23 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
// First stage is to make the ClangUtility to hold our injected function:
- #define USE_BUILTIN_FUNCTION 0 // Define this to 1 and we will use the get_implementation function found in the target.
- // This is useful for debugging additions to the get_impl function 'cause you don't have
- // to bother with string-ifying the code into g_lookup_implementation_function_code.
-
- if (USE_BUILTIN_FUNCTION)
- {
- ConstString our_utility_function_name("__lldb_objc_find_implementation_for_selector");
- SymbolContextList sc_list;
-
- exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
- if (sc_list.GetSize() == 1)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(0, sc);
- if (sc.symbol != NULL)
- impl_code_address = sc.symbol->GetAddress();
-
- //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
- //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
- }
- else
- {
- //printf ("Could not find implementation function address.\n");
- return args_addr;
- }
- }
- else if (!m_impl_code.get())
+ if (!m_impl_code.get())
{
if (g_lookup_implementation_function_code != NULL)
{
- m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code,
- g_lookup_implementation_function_name));
+ Error error;
+ m_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_lookup_implementation_function_code,
+ eLanguageTypeObjC,
+ g_lookup_implementation_function_name,
+ error));
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf ("Failed to get Utility Function for implementation lookup: %s.", error.AsCString());
+ m_impl_code.reset();
+ return args_addr;
+ }
+
if (!m_impl_code->Install(errors, exe_ctx))
{
if (log)
@@ -800,43 +785,26 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
return LLDB_INVALID_ADDRESS;
}
- impl_code_address.Clear();
- impl_code_address.SetOffset(m_impl_code->StartAddress());
- }
- else
- {
- impl_code_address.Clear();
- impl_code_address.SetOffset(m_impl_code->StartAddress());
- }
- // Next make the runner function for our implementation utility function.
- if (!m_impl_function.get())
- {
+ // Next make the runner function for our implementation utility function.
ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- m_impl_function.reset(new ClangFunction (thread,
- clang_void_ptr_type,
- impl_code_address,
- dispatch_values,
- "objc-dispatch-lookup"));
+ Error error;
- errors.Clear();
- unsigned num_errors = m_impl_function->CompileFunction(errors);
- if (num_errors)
+ impl_function_caller = m_impl_code->MakeFunctionCaller(clang_void_ptr_type,
+ dispatch_values,
+ error);
+ if (error.Fail())
{
if (log)
- log->Printf ("Error compiling function: \"%s\".", errors.GetData());
- return args_addr;
- }
-
- errors.Clear();
- if (!m_impl_function->WriteFunctionWrapper(exe_ctx, errors))
- {
- if (log)
- log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+ log->Printf ("Error getting function caller for dispatch lookup: \"%s\".", error.AsCString());
return args_addr;
}
}
+ else
+ {
+ impl_function_caller = m_impl_code->GetFunctionCaller();
+ }
}
errors.Clear();
@@ -845,7 +813,7 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (!m_impl_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, dispatch_values, errors))
+ if (impl_function_caller->WriteFunctionArguments (exe_ctx, args_addr, dispatch_values, errors))
{
if (log)
log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
@@ -1169,8 +1137,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool sto
return ret_plan_sp;
}
-ClangFunction *
-AppleObjCTrampolineHandler::GetLookupImplementationWrapperFunction ()
+FunctionCaller *
+AppleObjCTrampolineHandler::GetLookupImplementationFunctionCaller ()
{
- return m_impl_function.get();
+ return m_impl_code->GetFunctionCaller();
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
index c9d0e19ed2b..0ddb540439d 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
@@ -35,8 +35,8 @@ public:
GetStepThroughDispatchPlan (Thread &thread,
bool stop_others);
- ClangFunction *
- GetLookupImplementationWrapperFunction ();
+ FunctionCaller *
+ GetLookupImplementationFunctionCaller ();
bool
AddrIsMsgForward (lldb::addr_t addr) const
@@ -198,8 +198,7 @@ private:
MsgsendMap m_msgSend_map;
lldb::ProcessWP m_process_wp;
lldb::ModuleSP m_objc_module_sp;
- std::unique_ptr<ClangFunction> m_impl_function;
- std::unique_ptr<ClangUtilityFunction> m_impl_code;
+ std::unique_ptr<UtilityFunction> m_impl_code;
Mutex m_impl_function_mutex;
lldb::addr_t m_impl_fn_addr;
lldb::addr_t m_impl_stret_fn_addr;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index fe364faefe3..285786a09db 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -15,8 +15,8 @@
#include "AppleObjCTrampolineHandler.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
@@ -67,11 +67,11 @@ AppleThreadPlanStepThroughObjCTrampoline::DidPush ()
{
// Setting up the memory space for the called function text might require allocations,
// i.e. a nested function call. This needs to be done as a PreResumeAction.
- m_thread.GetProcess()->AddPreResumeAction (PreResumeInitializeClangFunction, (void *) this);
+ m_thread.GetProcess()->AddPreResumeAction (PreResumeInitializeFunctionCaller, (void *) this);
}
bool
-AppleThreadPlanStepThroughObjCTrampoline::InitializeClangFunction ()
+AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller ()
{
if (!m_func_sp)
{
@@ -82,7 +82,7 @@ AppleThreadPlanStepThroughObjCTrampoline::InitializeClangFunction ()
{
return false;
}
- m_impl_function = m_trampoline_handler->GetLookupImplementationWrapperFunction();
+ m_impl_function = m_trampoline_handler->GetLookupImplementationFunctionCaller();
ExecutionContext exc_ctx;
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
@@ -100,10 +100,10 @@ AppleThreadPlanStepThroughObjCTrampoline::InitializeClangFunction ()
}
bool
-AppleThreadPlanStepThroughObjCTrampoline::PreResumeInitializeClangFunction(void *void_myself)
+AppleThreadPlanStepThroughObjCTrampoline::PreResumeInitializeFunctionCaller(void *void_myself)
{
AppleThreadPlanStepThroughObjCTrampoline *myself = static_cast<AppleThreadPlanStepThroughObjCTrampoline *>(void_myself);
- return myself->InitializeClangFunction();
+ return myself->InitializeFunctionCaller();
}
void
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
index 253190991ce..2ad181e553f 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
@@ -66,7 +66,7 @@ public:
DidPush();
static bool
- PreResumeInitializeClangFunction(void *myself);
+ PreResumeInitializeFunctionCaller(void *myself);
virtual bool
WillStop();
@@ -82,7 +82,7 @@ protected:
private:
bool
- InitializeClangFunction ();
+ InitializeFunctionCaller ();
//------------------------------------------------------------------
// For AppleThreadPlanStepThroughObjCTrampoline only
@@ -96,7 +96,7 @@ private:
lldb::ThreadPlanSP m_func_sp; // This is the function call plan. We fill it at start, then set it
// to NULL when this plan is done. That way we know to go to:
lldb::ThreadPlanSP m_run_to_sp; // The plan that runs to the target.
- ClangFunction *m_impl_function; // This is a pointer to a impl function that
+ FunctionCaller *m_impl_function; // This is a pointer to a impl function that
// is owned by the client that pushes this plan.
bool m_stop_others;
};
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
index a882b7e3e87..66b8b8bcf59 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
@@ -22,9 +22,8 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
@@ -101,7 +100,6 @@ extern \"C\"
AppleGetItemInfoHandler::AppleGetItemInfoHandler (Process *process) :
m_process (process),
- m_get_item_info_function (),
m_get_item_info_impl_code (),
m_get_item_info_function_mutex(),
m_get_item_info_return_buffer_addr (LLDB_INVALID_ADDRESS),
@@ -140,49 +138,33 @@ lldb::addr_t
AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &get_item_info_arglist)
{
ExecutionContext exe_ctx (thread.shared_from_this());
- Address impl_code_address;
StreamString errors;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+ FunctionCaller *get_item_info_caller = nullptr;
// Scope for mutex locker:
{
Mutex::Locker locker(m_get_item_info_function_mutex);
- // First stage is to make the ClangUtility to hold our injected function:
+ // First stage is to make the UtilityFunction to hold our injected function:
-#define USE_BUILTIN_FUNCTION 0 // Define this to 1 and we will use the get_implementation function found in the target.
- // This is useful for debugging additions to the get_impl function 'cause you don't have
- // to bother with string-ifying the code into g_get_item_info_function_code.
-
- if (USE_BUILTIN_FUNCTION)
- {
- ConstString our_utility_function_name("__lldb_backtrace_recording_get_item_info");
- SymbolContextList sc_list;
-
- exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
- if (sc_list.GetSize() == 1)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(0, sc);
- if (sc.symbol != NULL)
- impl_code_address = sc.symbol->GetAddress();
-
- //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
- //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
- }
- else
- {
- //printf ("Could not find queues introspection function address.\n");
- return args_addr;
- }
- }
- else if (!m_get_item_info_impl_code.get())
+ if (!m_get_item_info_impl_code.get())
{
if (g_get_item_info_function_code != NULL)
{
- m_get_item_info_impl_code.reset (new ClangUtilityFunction (g_get_item_info_function_code,
- g_get_item_info_function_name));
+ Error error;
+ m_get_item_info_impl_code.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_get_item_info_function_code,
+ eLanguageTypeObjC,
+ g_get_item_info_function_name,
+ error));
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf ("Failed to get utility function: %s.", error.AsCString());
+ return args_addr;
+ }
+
if (!m_get_item_info_impl_code->Install(errors, exe_ctx))
{
if (log)
@@ -198,41 +180,32 @@ AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &ge
errors.Printf ("No get-item-info introspection code found.");
return LLDB_INVALID_ADDRESS;
}
-
- impl_code_address.Clear();
- impl_code_address.SetOffset(m_get_item_info_impl_code->StartAddress());
- }
- else
- {
- impl_code_address.Clear();
- impl_code_address.SetOffset(m_get_item_info_impl_code->StartAddress());
- }
- // Next make the runner function for our implementation utility function.
- if (!m_get_item_info_function.get())
- {
- ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_item_info_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- m_get_item_info_function.reset(new ClangFunction (thread,
- get_item_info_return_type,
- impl_code_address,
- get_item_info_arglist,
- "queue-bt-item-info"));
+ // Next make the runner function for our implementation utility function.
+ Error error;
+
+ TypeSystem *type_system = thread.GetProcess()->GetTarget().GetScratchTypeSystemForLanguage(eLanguageTypeC);
+ CompilerType get_item_info_return_type = type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
- errors.Clear();
- unsigned num_errors = m_get_item_info_function->CompileFunction(errors);
- if (num_errors)
+ get_item_info_caller = m_get_item_info_impl_code->MakeFunctionCaller(get_item_info_return_type,
+ get_item_info_arglist,
+ error);
+ if (error.Fail())
{
if (log)
- log->Printf ("Error compiling get-item-info function: \"%s\".", errors.GetData());
+ log->Printf ("Error Inserting get-item-info function: \"%s\".", error.AsCString());
return args_addr;
}
-
- errors.Clear();
- if (!m_get_item_info_function->WriteFunctionWrapper(exe_ctx, errors))
+ }
+ else
+ {
+ // If it's already made, then we can just retrieve the caller:
+ get_item_info_caller = m_get_item_info_impl_code->GetFunctionCaller();
+ if (!get_item_info_caller)
{
if (log)
- log->Printf ("Error Inserting get-item-info function: \"%s\".", errors.GetData());
+ log->Printf ("Failed to get get-item-info introspection caller.");
+ m_get_item_info_impl_code.reset();
return args_addr;
}
}
@@ -244,7 +217,7 @@ AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &ge
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (!m_get_item_info_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_item_info_arglist, errors))
+ if (!get_item_info_caller->WriteFunctionArguments (exe_ctx, args_addr, get_item_info_arglist, errors))
{
if (log)
log->Printf ("Error writing get-item-info function arguments: \"%s\".", errors.GetData());
@@ -364,7 +337,7 @@ AppleGetItemInfoHandler::GetItemInfo (Thread &thread, uint64_t item, addr_t page
options.SetTryAllThreads (false);
thread.CalculateExecutionContext (exe_ctx);
- if (m_get_item_info_function == NULL)
+ if (!m_get_item_info_impl_code)
{
error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_item_get_info");
return return_value;
@@ -373,7 +346,16 @@ AppleGetItemInfoHandler::GetItemInfo (Thread &thread, uint64_t item, addr_t page
ExpressionResults func_call_ret;
Value results;
- func_call_ret = m_get_item_info_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+ FunctionCaller *func_caller = m_get_item_info_impl_code->GetFunctionCaller();
+ if (!func_caller)
+ {
+ if (log)
+ log->Printf ("Could not retrieve function caller for __introspection_dispatch_queue_item_get_info.");
+ error.SetErrorString("Could not retrieve function caller for __introspection_dispatch_queue_item_get_info.");
+ return return_value;
+ }
+
+ func_call_ret = func_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
if (func_call_ret != eExpressionCompleted || !error.Success())
{
if (log)
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
index 5c086c61978..51182a62493 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
@@ -18,11 +18,11 @@
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/CompilerType.h"
-// This class will insert a ClangUtilityFunction into the inferior process for
+// This class will insert a UtilityFunction into the inferior process for
// calling libBacktraceRecording's __introspection_dispatch_queue_item_get_info()
// function. The function in the inferior will return a struct by value
// with these members:
@@ -37,7 +37,7 @@
// space (item_buffer_size in size) which must be mach_vm_deallocate'd by
// lldb.
//
-// The AppleGetItemInfoHandler object should persist so that the ClangUtilityFunction
+// The AppleGetItemInfoHandler object should persist so that the UtilityFunction
// can be reused multiple times.
namespace lldb_private
@@ -104,8 +104,7 @@ private:
static const char *g_get_item_info_function_code;
lldb_private::Process *m_process;
- std::unique_ptr<ClangFunction> m_get_item_info_function;
- std::unique_ptr<ClangUtilityFunction> m_get_item_info_impl_code;
+ std::unique_ptr<UtilityFunction> m_get_item_info_impl_code;
Mutex m_get_item_info_function_mutex;
lldb::addr_t m_get_item_info_return_buffer_addr;
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
index c3e68eaa0a6..3e3a2620013 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
@@ -22,9 +22,8 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
@@ -105,7 +104,6 @@ extern \"C\"
AppleGetPendingItemsHandler::AppleGetPendingItemsHandler (Process *process) :
m_process (process),
- m_get_pending_items_function (),
m_get_pending_items_impl_code (),
m_get_pending_items_function_mutex(),
m_get_pending_items_return_buffer_addr (LLDB_INVALID_ADDRESS),
@@ -144,49 +142,33 @@ lldb::addr_t
AppleGetPendingItemsHandler::SetupGetPendingItemsFunction (Thread &thread, ValueList &get_pending_items_arglist)
{
ExecutionContext exe_ctx (thread.shared_from_this());
- Address impl_code_address;
StreamString errors;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
-
+ FunctionCaller *get_pending_items_caller = nullptr;
+
// Scope for mutex locker:
{
Mutex::Locker locker(m_get_pending_items_function_mutex);
// First stage is to make the ClangUtility to hold our injected function:
-#define USE_BUILTIN_FUNCTION 0 // Define this to 1 and we will use the get_implementation function found in the target.
- // This is useful for debugging additions to the get_impl function 'cause you don't have
- // to bother with string-ifying the code into g_get_pending_items_function_code.
-
- if (USE_BUILTIN_FUNCTION)
- {
- ConstString our_utility_function_name("__lldb_backtrace_recording_get_pending_items");
- SymbolContextList sc_list;
-
- exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
- if (sc_list.GetSize() == 1)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(0, sc);
- if (sc.symbol != NULL)
- impl_code_address = sc.symbol->GetAddress();
-
- //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
- //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
- }
- else
- {
- //printf ("Could not find queues introspection function address.\n");
- return args_addr;
- }
- }
- else if (!m_get_pending_items_impl_code.get())
+ if (!m_get_pending_items_impl_code.get())
{
if (g_get_pending_items_function_code != NULL)
{
- m_get_pending_items_impl_code.reset (new ClangUtilityFunction (g_get_pending_items_function_code,
- g_get_pending_items_function_name));
+ Error error;
+ m_get_pending_items_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_get_pending_items_function_code,
+ eLanguageTypeObjC,
+ g_get_pending_items_function_name,
+ error));
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf ("Failed to get UtilityFunction for pending-items introspection: %s.", error.AsCString());
+ return args_addr;
+ }
+
if (!m_get_pending_items_impl_code->Install(errors, exe_ctx))
{
if (log)
@@ -203,43 +185,22 @@ AppleGetPendingItemsHandler::SetupGetPendingItemsFunction (Thread &thread, Value
return LLDB_INVALID_ADDRESS;
}
- impl_code_address.Clear();
- impl_code_address.SetOffset(m_get_pending_items_impl_code->StartAddress());
- }
- else
- {
- impl_code_address.Clear();
- impl_code_address.SetOffset(m_get_pending_items_impl_code->StartAddress());
- }
-
- // Next make the runner function for our implementation utility function.
- if (!m_get_pending_items_function.get())
- {
+ // Next make the runner function for our implementation utility function.
+ Error error;
ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
CompilerType get_pending_items_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- m_get_pending_items_function.reset(new ClangFunction (thread,
- get_pending_items_return_type,
- impl_code_address,
- get_pending_items_arglist,
- "queue-pending-items"));
-
- errors.Clear();
- unsigned num_errors = m_get_pending_items_function->CompileFunction(errors);
- if (num_errors)
+ get_pending_items_caller = m_get_pending_items_impl_code->MakeFunctionCaller (get_pending_items_return_type,
+ get_pending_items_arglist,
+ error);
+ if (error.Fail())
{
if (log)
- log->Printf ("Error compiling pending-items function: \"%s\".", errors.GetData());
- return args_addr;
- }
-
- errors.Clear();
- if (!m_get_pending_items_function->WriteFunctionWrapper(exe_ctx, errors))
- {
- if (log)
- log->Printf ("Error Inserting pending-items function: \"%s\".", errors.GetData());
+ log->Printf ("Failed to install pending-items introspection function caller: %s.", error.AsCString());
+ m_get_pending_items_impl_code.reset();
return args_addr;
}
}
+
}
errors.Clear();
@@ -248,7 +209,7 @@ AppleGetPendingItemsHandler::SetupGetPendingItemsFunction (Thread &thread, Value
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (!m_get_pending_items_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_pending_items_arglist, errors))
+ if (!get_pending_items_caller->WriteFunctionArguments (exe_ctx, args_addr, get_pending_items_arglist, errors))
{
if (log)
log->Printf ("Error writing pending-items function arguments: \"%s\".", errors.GetData());
@@ -362,6 +323,8 @@ AppleGetPendingItemsHandler::GetPendingItems (Thread &thread, addr_t queue, addr
StreamString errors;
ExecutionContext exe_ctx;
+ FunctionCaller *get_pending_items_caller = m_get_pending_items_impl_code->GetFunctionCaller();
+
EvaluateExpressionOptions options;
options.SetUnwindOnError (true);
options.SetIgnoreBreakpoints (true);
@@ -370,7 +333,7 @@ AppleGetPendingItemsHandler::GetPendingItems (Thread &thread, addr_t queue, addr
options.SetTryAllThreads (false);
thread.CalculateExecutionContext (exe_ctx);
- if (m_get_pending_items_function == NULL)
+ if (get_pending_items_caller == NULL)
{
error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_get_pending_items");
return return_value;
@@ -379,7 +342,7 @@ AppleGetPendingItemsHandler::GetPendingItems (Thread &thread, addr_t queue, addr
ExpressionResults func_call_ret;
Value results;
- func_call_ret = m_get_pending_items_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+ func_call_ret = get_pending_items_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
if (func_call_ret != eExpressionCompleted || !error.Success())
{
if (log)
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
index 22ab1f6132c..445c4a0fb82 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
@@ -18,11 +18,10 @@
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
-#include "lldb/Expression/ClangFunction.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/CompilerType.h"
-// This class will insert a ClangUtilityFunction into the inferior process for
+// This class will insert a UtilityFunction into the inferior process for
// calling libBacktraceRecording's __introspection_dispatch_queue_get_pending_items()
// function. The function in the inferior will return a struct by value
// with these members:
@@ -38,7 +37,7 @@
// space (items_buffer_size in size) which must be mach_vm_deallocate'd by
// lldb. count is the number of items that were stored in the buffer.
//
-// The AppleGetPendingItemsHandler object should persist so that the ClangUtilityFunction
+// The AppleGetPendingItemsHandler object should persist so that the UtilityFunction
// can be reused multiple times.
namespace lldb_private
@@ -107,8 +106,7 @@ private:
static const char *g_get_pending_items_function_code;
lldb_private::Process *m_process;
- std::unique_ptr<ClangFunction> m_get_pending_items_function;
- std::unique_ptr<ClangUtilityFunction> m_get_pending_items_impl_code;
+ std::unique_ptr<UtilityFunction> m_get_pending_items_impl_code;
Mutex m_get_pending_items_function_mutex;
lldb::addr_t m_get_pending_items_return_buffer_addr;
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
index d5b1380e273..6d7eaf72191 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
@@ -21,9 +21,8 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
@@ -101,8 +100,7 @@ extern \"C\"
AppleGetQueuesHandler::AppleGetQueuesHandler (Process *process) :
m_process (process),
- m_get_queues_function (),
- m_get_queues_impl_code (),
+ m_get_queues_impl_code_up (),
m_get_queues_function_mutex(),
m_get_queues_return_buffer_addr (LLDB_INVALID_ADDRESS),
m_get_queues_retbuffer_mutex()
@@ -156,6 +154,8 @@ AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_qu
StreamString errors;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+
+ FunctionCaller *get_queues_caller = nullptr;
// Scope for mutex locker:
{
@@ -163,43 +163,27 @@ AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_qu
// First stage is to make the ClangUtility to hold our injected function:
-#define USE_BUILTIN_FUNCTION 0 // Define this to 1 and we will use the get_implementation function found in the target.
- // This is useful for debugging additions to the get_impl function 'cause you don't have
- // to bother with string-ifying the code into g_get_current_queues_function_code.
-
- if (USE_BUILTIN_FUNCTION)
- {
- ConstString our_utility_function_name("__lldb_backtrace_recording_get_current_queues");
- SymbolContextList sc_list;
-
- exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
- if (sc_list.GetSize() == 1)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(0, sc);
- if (sc.symbol != NULL)
- impl_code_address = sc.symbol->GetAddress();
-
- //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
- //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
- }
- else
- {
- //printf ("Could not find queues introspection function address.\n");
- return args_addr;
- }
- }
- else if (!m_get_queues_impl_code.get())
+ if (!m_get_queues_impl_code_up.get())
{
if (g_get_current_queues_function_code != NULL)
{
- m_get_queues_impl_code.reset (new ClangUtilityFunction (g_get_current_queues_function_code,
- g_get_current_queues_function_name));
- if (!m_get_queues_impl_code->Install(errors, exe_ctx))
+ Error error;
+ m_get_queues_impl_code_up.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_get_current_queues_function_code,
+ eLanguageTypeC,
+ g_get_current_queues_function_name,
+ error));
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf ("Failed to get UtilityFunction for queues introspection: %s.", error.AsCString());
+ return args_addr;
+ }
+
+ if (!m_get_queues_impl_code_up->Install(errors, exe_ctx))
{
if (log)
log->Printf ("Failed to install queues introspection: %s.", errors.GetData());
- m_get_queues_impl_code.reset();
+ m_get_queues_impl_code_up.reset();
return args_addr;
}
}
@@ -210,43 +194,20 @@ AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_qu
errors.Printf ("No queues introspection code found.");
return LLDB_INVALID_ADDRESS;
}
-
- impl_code_address.Clear();
- impl_code_address.SetOffset(m_get_queues_impl_code->StartAddress());
- }
- else
- {
- impl_code_address.Clear();
- impl_code_address.SetOffset(m_get_queues_impl_code->StartAddress());
}
-
+
// Next make the runner function for our implementation utility function.
- if (!m_get_queues_function.get())
+ ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+ CompilerType get_queues_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Error error;
+ get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller (get_queues_return_type,
+ get_queues_arglist,
+ error);
+ if (error.Fail())
{
- ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
- CompilerType get_queues_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- m_get_queues_function.reset(new ClangFunction (thread,
- get_queues_return_type,
- impl_code_address,
- get_queues_arglist,
- "queue-fetch-queues"));
-
- errors.Clear();
- unsigned num_errors = m_get_queues_function->CompileFunction(errors);
- if (num_errors)
- {
- if (log)
- log->Printf ("Error compiling get-queues function: \"%s\".", errors.GetData());
- return args_addr;
- }
-
- errors.Clear();
- if (!m_get_queues_function->WriteFunctionWrapper(exe_ctx, errors))
- {
- if (log)
- log->Printf ("Error Inserting get-queues function: \"%s\".", errors.GetData());
- return args_addr;
- }
+ if (log)
+ log->Printf ("Could not get function caller for get-queues function: %s.", error.AsCString());
+ return args_addr;
}
}
@@ -256,7 +217,7 @@ AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_qu
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (!m_get_queues_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_queues_arglist, errors))
+ if (!get_queues_caller->WriteFunctionArguments (exe_ctx, args_addr, get_queues_arglist, errors))
{
if (log)
log->Printf ("Error writing get-queues function arguments: \"%s\".", errors.GetData());
@@ -360,9 +321,17 @@ AppleGetQueuesHandler::GetCurrentQueues (Thread &thread, addr_t page_to_free, ui
addr_t args_addr = SetupGetQueuesFunction (thread, argument_values);
- if (m_get_queues_function == NULL)
+ if (!m_get_queues_impl_code_up)
+ {
+ error.SetErrorString ("Unable to compile __introspection_dispatch_get_queues.");
+ return return_value;
+ }
+
+ FunctionCaller *get_queues_caller = m_get_queues_impl_code_up->GetFunctionCaller();
+
+ if (get_queues_caller == NULL)
{
- error.SetErrorString ("Unable to compile function to call __introspection_dispatch_get_queues");
+ error.SetErrorString ("Unable to get caller for call __introspection_dispatch_get_queues");
return return_value;
}
@@ -378,7 +347,7 @@ AppleGetQueuesHandler::GetCurrentQueues (Thread &thread, addr_t page_to_free, ui
ExpressionResults func_call_ret;
Value results;
- func_call_ret = m_get_queues_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+ func_call_ret = get_queues_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
if (func_call_ret != eExpressionCompleted || !error.Success())
{
if (log)
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
index 83730b58374..6f3df5f6280 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
@@ -18,11 +18,10 @@
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
-#include "lldb/Expression/ClangFunction.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/CompilerType.h"
-// This class will insert a ClangUtilityFunction into the inferior process for
+// This class will insert a UtilityFunction into the inferior process for
// calling libBacktraceRecording's introspection_get_dispatch_queues()
// function. The function in the inferior will return a struct by value
// with these members:
@@ -38,7 +37,7 @@
// space (queues_buffer_size in size) which must be mach_vm_deallocate'd by
// lldb. count is the number of queues that were stored in the buffer.
//
-// The AppleGetQueuesHandler object should persist so that the ClangUtilityFunction
+// The AppleGetQueuesHandler object should persist so that the UtilityFunction
// can be reused multiple times.
namespace lldb_private
@@ -104,8 +103,7 @@ private:
static const char *g_get_current_queues_function_code;
lldb_private::Process *m_process;
- std::unique_ptr<ClangFunction> m_get_queues_function;
- std::unique_ptr<ClangUtilityFunction> m_get_queues_impl_code;
+ std::unique_ptr<UtilityFunction> m_get_queues_impl_code_up;
Mutex m_get_queues_function_mutex;
lldb::addr_t m_get_queues_return_buffer_addr;
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
index 2509b3ba0ef..ea7014147b6 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
@@ -17,18 +17,20 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
+#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/Expression.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
@@ -105,7 +107,6 @@ extern \"C\"
AppleGetThreadItemInfoHandler::AppleGetThreadItemInfoHandler (Process *process) :
m_process (process),
- m_get_thread_item_info_function (),
m_get_thread_item_info_impl_code (),
m_get_thread_item_info_function_mutex(),
m_get_thread_item_info_return_buffer_addr (LLDB_INVALID_ADDRESS),
@@ -148,6 +149,7 @@ AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, V
StreamString errors;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+ FunctionCaller *get_thread_item_info_caller = nullptr;
// Scope for mutex locker:
{
@@ -155,38 +157,24 @@ AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, V
// First stage is to make the ClangUtility to hold our injected function:
-#define USE_BUILTIN_FUNCTION 0 // Define this to 1 and we will use the get_implementation function found in the target.
- // This is useful for debugging additions to the get_impl function 'cause you don't have
- // to bother with string-ifying the code into g_get_thread_item_info_function_code.
-
- if (USE_BUILTIN_FUNCTION)
- {
- ConstString our_utility_function_name("__lldb_backtrace_recording_get_thread_item_info");
- SymbolContextList sc_list;
-
- exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
- if (sc_list.GetSize() == 1)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(0, sc);
- if (sc.symbol != NULL)
- impl_code_address = sc.symbol->GetAddress();
-
- //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
- //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
- }
- else
- {
- //printf ("Could not find queues introspection function address.\n");
- return args_addr;
- }
- }
- else if (!m_get_thread_item_info_impl_code.get())
+ if (!m_get_thread_item_info_impl_code.get())
{
+ Error error;
if (g_get_thread_item_info_function_code != NULL)
{
- m_get_thread_item_info_impl_code.reset (new ClangUtilityFunction (g_get_thread_item_info_function_code,
- g_get_thread_item_info_function_name));
+ m_get_thread_item_info_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_get_thread_item_info_function_code,
+ eLanguageTypeC,
+ g_get_thread_item_info_function_name,
+ error));
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf ("Failed to get UtilityFunction for get-thread-item-info introspection: %s.",
+ error.AsCString());
+ m_get_thread_item_info_impl_code.reset();
+ return args_addr;
+ }
+
if (!m_get_thread_item_info_impl_code->Install(errors, exe_ctx))
{
if (log)
@@ -203,42 +191,26 @@ AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, V
return LLDB_INVALID_ADDRESS;
}
- impl_code_address.Clear();
- impl_code_address.SetOffset(m_get_thread_item_info_impl_code->StartAddress());
- }
- else
- {
- impl_code_address.Clear();
- impl_code_address.SetOffset(m_get_thread_item_info_impl_code->StartAddress());
- }
-
- // Next make the runner function for our implementation utility function.
- if (!m_get_thread_item_info_function.get())
- {
+ // Also make the FunctionCaller for this UtilityFunction:
+
ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
CompilerType get_thread_item_info_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- m_get_thread_item_info_function.reset(new ClangFunction (thread,
- get_thread_item_info_return_type,
- impl_code_address,
- get_thread_item_info_arglist,
- "queue-thread-item-info"));
- errors.Clear();
- unsigned num_errors = m_get_thread_item_info_function->CompileFunction(errors);
- if (num_errors)
+ get_thread_item_info_caller = m_get_thread_item_info_impl_code->MakeFunctionCaller (get_thread_item_info_return_type,
+ get_thread_item_info_arglist,
+ error);
+ if (error.Fail())
{
if (log)
- log->Printf ("Error compiling get-thread-item-info function: \"%s\".", errors.GetData());
+ log->Printf ("Failed to install get-thread-item-info introspection caller: %s.", error.AsCString());
+ m_get_thread_item_info_impl_code.reset();
return args_addr;
}
- errors.Clear();
- if (!m_get_thread_item_info_function->WriteFunctionWrapper(exe_ctx, errors))
- {
- if (log)
- log->Printf ("Error Inserting get-thread-item-info function: \"%s\".", errors.GetData());
- return args_addr;
- }
+ }
+ else
+ {
+ get_thread_item_info_caller = m_get_thread_item_info_impl_code->GetFunctionCaller();
}
}
@@ -248,7 +220,7 @@ AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, V
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (!m_get_thread_item_info_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_thread_item_info_arglist, errors))
+ if (!get_thread_item_info_caller->WriteFunctionArguments (exe_ctx, args_addr, get_thread_item_info_arglist, errors))
{
if (log)
log->Printf ("Error writing get-thread-item-info function arguments: \"%s\".", errors.GetData());
@@ -360,6 +332,8 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo (Thread &thread, tid_t thread_i
StreamString errors;
ExecutionContext exe_ctx;
EvaluateExpressionOptions options;
+ FunctionCaller *get_thread_item_info_caller = nullptr;
+
options.SetUnwindOnError (true);
options.SetIgnoreBreakpoints (true);
options.SetStopOthers (true);
@@ -367,16 +341,23 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo (Thread &thread, tid_t thread_i
options.SetTryAllThreads (false);
thread.CalculateExecutionContext (exe_ctx);
- if (m_get_thread_item_info_function == NULL)
+ if (!m_get_thread_item_info_impl_code)
{
error.SetErrorString ("Unable to compile function to call __introspection_dispatch_thread_get_item_info");
return return_value;
}
+ get_thread_item_info_caller = m_get_thread_item_info_impl_code->GetFunctionCaller();
+
+ if (!get_thread_item_info_caller)
+ {
+ error.SetErrorString ("Unable to compile function caller for __introspection_dispatch_thread_get_item_info");
+ return return_value;
+ }
ExpressionResults func_call_ret;
Value results;
- func_call_ret = m_get_thread_item_info_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+ func_call_ret = get_thread_item_info_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
if (func_call_ret != eExpressionCompleted || !error.Success())
{
if (log)
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
index 6ced39ae851..c1798fb515b 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
@@ -18,11 +18,10 @@
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Core/Error.h"
-#include "lldb/Expression/ClangFunction.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/CompilerType.h"
-// This class will insert a ClangUtilityFunction into the inferior process for
+// This class will insert a UtilityFunction into the inferior process for
// calling libBacktraceRecording's __introspection_dispatch_thread_get_item_info()
// function. The function in the inferior will return a struct by value
// with these members:
@@ -37,7 +36,7 @@
// space (item_buffer_size in size) which must be mach_vm_deallocate'd by
// lldb.
//
-// The AppleGetThreadItemInfoHandler object should persist so that the ClangUtilityFunction
+// The AppleGetThreadItemInfoHandler object should persist so that the UtilityFunction
// can be reused multiple times.
namespace lldb_private
@@ -101,8 +100,7 @@ private:
static const char *g_get_thread_item_info_function_code;
lldb_private::Process *m_process;
- std::unique_ptr<ClangFunction> m_get_thread_item_info_function;
- std::unique_ptr<ClangUtilityFunction> m_get_thread_item_info_impl_code;
+ std::unique_ptr<UtilityFunction> m_get_thread_item_info_impl_code;
Mutex m_get_thread_item_info_function_mutex;
lldb::addr_t m_get_thread_item_info_return_buffer_addr;
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 90271f29c71..11b47df87d0 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -17,8 +17,6 @@
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index b7157bd9aac..ccff1c19431 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -69,14 +69,20 @@
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Expression/ASTDumper.h"
+#include "lldb/Expression/ASTResultSynthesizer.h"
+#include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/ClangFunctionCaller.h"
+#include "lldb/Expression/ClangUtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/VerifyDecl.h"
#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
@@ -8942,3 +8948,49 @@ ClangASTContext::DeclContextGetClangASTContext (const CompilerDeclContext &dc)
return nullptr;
}
+ClangASTContextForExpressions::ClangASTContextForExpressions (Target &target) :
+ ClangASTContext (target.GetArchitecture().GetTriple().getTriple().c_str()),
+ m_target_wp(target.shared_from_this())
+{
+}
+
+UserExpression *
+ClangASTContextForExpressions::GetUserExpression (const char *expr,
+ const char *expr_prefix,
+ lldb::LanguageType language,
+ Expression::ResultType desired_type)
+{
+ TargetSP target_sp = m_target_wp.lock();
+ if (!target_sp)
+ return nullptr;
+
+ return new ClangUserExpression(*target_sp.get(), expr, expr_prefix, language, desired_type);
+}
+
+FunctionCaller *
+ClangASTContextForExpressions::GetFunctionCaller (const CompilerType &return_type,
+ const Address& function_address,
+ const ValueList &arg_value_list,
+ const char *name)
+{
+ TargetSP target_sp = m_target_wp.lock();
+ if (!target_sp)
+ return nullptr;
+
+ Process *process = target_sp->GetProcessSP().get();
+ if (!process)
+ return nullptr;
+
+ return new ClangFunctionCaller (*process, return_type, function_address, arg_value_list, name);
+}
+
+UtilityFunction *
+ClangASTContextForExpressions::GetUtilityFunction (const char *text,
+ const char *name)
+{
+ TargetSP target_sp = m_target_wp.lock();
+ if (!target_sp)
+ return nullptr;
+
+ return new ClangUtilityFunction(*target_sp.get(), text, name);
+}
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 0fd8d53a24e..e2bb2e48c41 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -18,7 +18,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/IRDynamicChecks.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Host.h"
@@ -1917,6 +1917,7 @@ Process::LoadImage (const FileSpec &image_spec, Error &error)
expr_options.SetIgnoreBreakpoints(true);
expr_options.SetExecutionPolicy(eExecutionPolicyAlways);
expr_options.SetResultIsInternal(true);
+ expr_options.SetLanguage(eLanguageTypeC_plus_plus);
StreamString expr;
expr.Printf(R"(
@@ -1939,12 +1940,12 @@ Process::LoadImage (const FileSpec &image_spec, Error &error)
)";
lldb::ValueObjectSP result_valobj_sp;
Error expr_error;
- ClangUserExpression::Evaluate (exe_ctx,
- expr_options,
- expr.GetData(),
- prefix,
- result_valobj_sp,
- expr_error);
+ UserExpression::Evaluate (exe_ctx,
+ expr_options,
+ expr.GetData(),
+ prefix,
+ result_valobj_sp,
+ expr_error);
if (expr_error.Success())
{
error = result_valobj_sp->GetError();
@@ -2044,17 +2045,19 @@ Process::UnloadImage (uint32_t image_token)
expr_options.SetUnwindOnError(true);
expr_options.SetIgnoreBreakpoints(true);
expr_options.SetExecutionPolicy(eExecutionPolicyAlways);
+ expr_options.SetLanguage(eLanguageTypeC_plus_plus);
+
StreamString expr;
expr.Printf("dlclose ((void *)0x%" PRIx64 ")", image_addr);
const char *prefix = "extern \"C\" int dlclose(void* handle);\n";
lldb::ValueObjectSP result_valobj_sp;
Error expr_error;
- ClangUserExpression::Evaluate (exe_ctx,
- expr_options,
- expr.GetData(),
- prefix,
- result_valobj_sp,
- expr_error);
+ UserExpression::Evaluate (exe_ctx,
+ expr_options,
+ expr.GetData(),
+ prefix,
+ result_valobj_sp,
+ expr_error);
if (result_valobj_sp->GetError().Success())
{
Scalar scalar;
diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp
index 00fd79aa8fd..fc1cb9af238 100644
--- a/lldb/source/Target/StopInfo.cpp
+++ b/lldb/source/Target/StopInfo.cpp
@@ -23,7 +23,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObject.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
@@ -770,12 +770,13 @@ protected:
expr_options.SetIgnoreBreakpoints(true);
ValueObjectSP result_value_sp;
Error error;
- result_code = ClangUserExpression::Evaluate (exe_ctx,
- expr_options,
- wp_sp->GetConditionText(),
- NULL,
- result_value_sp,
- error);
+ result_code = UserExpression::Evaluate (exe_ctx,
+ expr_options,
+ wp_sp->GetConditionText(),
+ NULL,
+ result_value_sp,
+ error);
+
if (result_code == eExpressionCompleted)
{
if (result_value_sp)
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index aca6605f2af..993706fa889 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -33,7 +33,7 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/ClangASTSource.h"
#include "lldb/Expression/ClangPersistentVariables.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/ClangModulesDeclVendor.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
@@ -46,6 +46,7 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/Language.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
@@ -1891,13 +1892,95 @@ Target::ImageSearchPathsChanged
target->SetExecutableModule (exe_module_sp, true);
}
+TypeSystem *
+Target::GetScratchTypeSystemForLanguage (lldb::LanguageType language, bool create_on_demand)
+{
+ if (Language::LanguageIsC(language)
+ || Language::LanguageIsObjC(language)
+ || Language::LanguageIsCPlusPlus(language)
+ || language == eLanguageTypeUnknown)
+ return GetScratchClangASTContext(create_on_demand);
+ else
+ return NULL;
+}
+
+UserExpression *
+Target::GetUserExpressionForLanguage(const char *expr,
+ const char *expr_prefix,
+ lldb::LanguageType language,
+ Expression::ResultType desired_type,
+ Error &error)
+{
+ TypeSystem *type_system = GetScratchTypeSystemForLanguage (language);
+ UserExpression *user_expr = nullptr;
+
+ if (!type_system)
+ {
+ error.SetErrorStringWithFormat("Could not find type system for language: %s", Language::GetNameForLanguageType(language));
+ return nullptr;
+ }
+
+ user_expr = type_system->GetUserExpression(expr, expr_prefix, language, desired_type);
+ if (!user_expr)
+ error.SetErrorStringWithFormat("Could not create an expression for language %s", Language::GetNameForLanguageType(language));
+
+ return user_expr;
+}
+
+FunctionCaller *
+Target::GetFunctionCallerForLanguage (lldb::LanguageType language,
+ const CompilerType &return_type,
+ const Address& function_address,
+ const ValueList &arg_value_list,
+ const char *name,
+ Error &error)
+{
+ TypeSystem *type_system = GetScratchTypeSystemForLanguage (language);
+ FunctionCaller *persistent_fn = nullptr;
+
+ if (!type_system)
+ {
+ error.SetErrorStringWithFormat("Could not find type system for language: %s", Language::GetNameForLanguageType(language));
+ return persistent_fn;
+ }
+
+ persistent_fn = type_system->GetFunctionCaller (return_type, function_address, arg_value_list, name);
+ if (!persistent_fn)
+ error.SetErrorStringWithFormat("Could not create an expression for language %s", Language::GetNameForLanguageType(language));
+
+ return persistent_fn;
+}
+
+UtilityFunction *
+Target::GetUtilityFunctionForLanguage (const char *text,
+ lldb::LanguageType language,
+ const char *name,
+ Error &error)
+{
+ TypeSystem *type_system = GetScratchTypeSystemForLanguage (language);
+ UtilityFunction *utility_fn = nullptr;
+
+ if (!type_system)
+ {
+ error.SetErrorStringWithFormat("Could not find type system for language: %s", Language::GetNameForLanguageType(language));
+ return utility_fn;
+ }
+
+ utility_fn = type_system->GetUtilityFunction (text, name);
+ if (!utility_fn)
+ error.SetErrorStringWithFormat("Could not create an expression for language %s", Language::GetNameForLanguageType(language));
+
+ return utility_fn;
+}
+
+
ClangASTContext *
Target::GetScratchClangASTContext(bool create_on_demand)
{
// Now see if we know the target triple, and if so, create our scratch AST context:
if (m_scratch_ast_context_ap.get() == NULL && m_arch.IsValid() && create_on_demand)
{
- m_scratch_ast_context_ap.reset (new ClangASTContext(m_arch.GetTriple().str().c_str()));
+ m_scratch_ast_context_ap.reset (new ClangASTContextForExpressions(*this));
m_scratch_ast_source_ap.reset (new ClangASTSource(shared_from_this()));
m_scratch_ast_source_ap->InstallASTContext(m_scratch_ast_context_ap->getASTContext());
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(m_scratch_ast_source_ap->CreateProxy());
@@ -1906,27 +1989,6 @@ Target::GetScratchClangASTContext(bool create_on_demand)
return m_scratch_ast_context_ap.get();
}
-TypeSystem*
-Target::GetTypeSystemForLanguage (lldb::LanguageType language)
-{
- switch (language)
- {
- case lldb::eLanguageTypeC:
- case lldb::eLanguageTypeC11:
- case lldb::eLanguageTypeC89:
- case lldb::eLanguageTypeC99:
- case lldb::eLanguageTypeC_plus_plus:
- case lldb::eLanguageTypeC_plus_plus_03:
- case lldb::eLanguageTypeC_plus_plus_11:
- case lldb::eLanguageTypeC_plus_plus_14:
- case lldb::eLanguageTypeObjC:
- case lldb::eLanguageTypeObjC_plus_plus:
- return GetScratchClangASTContext(true);
- default:
- return nullptr;
- }
-}
-
ClangASTImporter *
Target::GetClangASTImporter()
{
@@ -2067,12 +2129,12 @@ Target::EvaluateExpression
{
const char *prefix = GetExpressionPrefixContentsAsCString();
Error error;
- execution_results = ClangUserExpression::Evaluate (exe_ctx,
- options,
- expr_cstr,
- prefix,
- result_valobj_sp,
- error);
+ execution_results = UserExpression::Evaluate (exe_ctx,
+ options,
+ expr_cstr,
+ prefix,
+ result_valobj_sp,
+ error);
}
m_suppress_stop_hooks = old_suppress_value;
diff --git a/lldb/source/Target/ThreadPlanCallUserExpression.cpp b/lldb/source/Target/ThreadPlanCallUserExpression.cpp
index 3ec3284afb4..b24f74b10df 100644
--- a/lldb/source/Target/ThreadPlanCallUserExpression.cpp
+++ b/lldb/source/Target/ThreadPlanCallUserExpression.cpp
@@ -19,7 +19,7 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/IRDynamicChecks.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/LanguageRuntime.h"
@@ -41,7 +41,7 @@ ThreadPlanCallUserExpression::ThreadPlanCallUserExpression (Thread &thread,
Address &function,
llvm::ArrayRef<lldb::addr_t> args,
const EvaluateExpressionOptions &options,
- lldb::ClangUserExpressionSP &user_expression_sp) :
+ lldb::UserExpressionSP &user_expression_sp) :
ThreadPlanCallFunction (thread, function, CompilerType(), args, options),
m_user_expression_sp (user_expression_sp)
{
OpenPOWER on IntegriCloud