diff options
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/include/lldb/Expression/ClangUserExpression.h | 35 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Target.h | 9 | ||||
-rw-r--r-- | lldb/source/API/SBFrame.cpp | 8 | ||||
-rw-r--r-- | lldb/source/Breakpoint/BreakpointOptions.cpp | 6 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectExpression.cpp | 7 | ||||
-rw-r--r-- | lldb/source/Expression/ClangUserExpression.cpp | 18 | ||||
-rw-r--r-- | lldb/source/Target/Target.cpp | 88 |
7 files changed, 143 insertions, 28 deletions
diff --git a/lldb/include/lldb/Expression/ClangUserExpression.h b/lldb/include/lldb/Expression/ClangUserExpression.h index 68ea2beab25..35871bcdf88 100644 --- a/lldb/include/lldb/Expression/ClangUserExpression.h +++ b/lldb/include/lldb/Expression/ClangUserExpression.h @@ -45,8 +45,16 @@ class ClangUserExpression : public ClangExpression public: //------------------------------------------------------------------ /// Constructor + /// + /// @param[in] expr + /// The expression to parse. + /// + /// @param[in] expr_prefix + /// If non-NULL, a C string containing translation-unit level + /// definitions to be included when the expression is parsed. //------------------------------------------------------------------ - ClangUserExpression (const char *expr); + ClangUserExpression (const char *expr, + const char *expr_prefix); //------------------------------------------------------------------ /// Destructor @@ -189,9 +197,23 @@ public: return true; } - + //------------------------------------------------------------------ + /// Evaluate one expression and return its result. + /// + /// @param[in] exe_ctx + /// The execution context to use when evaluating the expression. + /// + /// @param[in] expr_cstr + /// A C string containing the expression to be evaluated. + /// + /// @param[in] expr_prefix + /// If non-NULL, a C string containing translation-unit level + /// definitions to be included when the expression is parsed. + //------------------------------------------------------------------ static lldb::ValueObjectSP - Evaluate (ExecutionContext &exe_ctx, const char *expr_cstr); + Evaluate (ExecutionContext &exe_ctx, + const char *expr_cstr, + const char *expr_prefix); private: //------------------------------------------------------------------ @@ -202,11 +224,12 @@ private: bool PrepareToExecuteJITExpression (Stream &error_stream, - ExecutionContext &exe_ctx, - lldb::addr_t &struct_address, - lldb::addr_t &object_ptr); + ExecutionContext &exe_ctx, + lldb::addr_t &struct_address, + lldb::addr_t &object_ptr); std::string m_expr_text; ///< The text of the expression, as typed by the user + std::string m_expr_prefix; ///< The text of the translation-level definitions, as provided by the user std::string m_transformed_text; ///< The text of the expression, as send to the parser std::auto_ptr<ClangExpressionDeclMap> m_expr_decl_map; ///< The map to use when parsing and materializing the expression. diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 1f73249680c..debdd84853d 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -70,9 +70,9 @@ protected: const ConstString CreateInstanceName (); - -private: - + + std::string m_expr_prefix_path; + std::string m_expr_prefix_contents; }; class Target : @@ -437,6 +437,9 @@ public: ClangASTContext * GetScratchClangASTContext(); + const char * + GetExpressionPrefixContentsAsCString (); + protected: friend class lldb::SBTarget; diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index c0eb134952f..028c869b674 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -547,7 +547,13 @@ SBFrame::EvaluateExpression (const char *expr) { ExecutionContext exe_ctx; m_opaque_sp->CalculateExecutionContext (exe_ctx); - *expr_result_value = ClangUserExpression::Evaluate (exe_ctx, expr); + + const char *prefix = NULL; + + if (exe_ctx.target) + prefix = exe_ctx.target->GetExpressionPrefixContentsAsCString(); + + *expr_result_value = ClangUserExpression::Evaluate (exe_ctx, expr, prefix); } return expr_result_value; } diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp index b3aa1152761..713c2e90c50 100644 --- a/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -59,7 +59,7 @@ BreakpointOptions::BreakpointOptions(const BreakpointOptions& rhs) : if (rhs.m_thread_spec_ap.get() != NULL) m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get())); if (rhs.m_condition_ap.get()) - m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText())); + m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText(), NULL)); } //---------------------------------------------------------------------- @@ -76,7 +76,7 @@ BreakpointOptions::operator=(const BreakpointOptions& rhs) if (rhs.m_thread_spec_ap.get() != NULL) m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); if (rhs.m_condition_ap.get()) - m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText())); + m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText(), NULL)); return *this; } @@ -165,7 +165,7 @@ BreakpointOptions::SetCondition (const char *condition) } else { - m_condition_ap.reset(new ClangUserExpression (condition)); + m_condition_ap.reset(new ClangUserExpression (condition, NULL)); } } diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index 178ca530f10..7f7c780978a 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -233,7 +233,12 @@ CommandObjectExpression::EvaluateExpression m_exe_ctx.process->SetDynamicCheckers(dynamic_checkers); } - lldb::ValueObjectSP result_valobj_sp (ClangUserExpression::Evaluate (m_exe_ctx, expr)); + const char *prefix = NULL; + + if (m_exe_ctx.target) + prefix = m_exe_ctx.target->GetExpressionPrefixContentsAsCString(); + + lldb::ValueObjectSP result_valobj_sp (ClangUserExpression::Evaluate (m_exe_ctx, expr, prefix)); assert (result_valobj_sp.get()); if (result_valobj_sp->GetError().Success()) { diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index 60f3e754a26..bd67bbdae62 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -35,8 +35,10 @@ using namespace lldb_private; -ClangUserExpression::ClangUserExpression (const char *expr) : +ClangUserExpression::ClangUserExpression (const char *expr, + const char *expr_prefix) : m_expr_text(expr), + m_expr_prefix(expr_prefix), m_transformed_text(), m_jit_addr(LLDB_INVALID_ADDRESS), m_cplusplus(false), @@ -129,12 +131,14 @@ ClangUserExpression::Parse (Stream &error_stream, ExecutionContext &exe_ctx) if (m_cplusplus) { - m_transformed_stream.Printf("typedef unsigned short unichar; \n" + m_transformed_stream.Printf("%s \n" + "typedef unsigned short unichar; \n" "void \n" "$__lldb_class::%s(void *$__lldb_arg) \n" "{ \n" " %s; \n" "} \n", + m_expr_prefix.c_str(), FunctionName(), m_expr_text.c_str()); @@ -142,12 +146,14 @@ ClangUserExpression::Parse (Stream &error_stream, ExecutionContext &exe_ctx) } else { - m_transformed_stream.Printf("typedef unsigned short unichar;\n" + m_transformed_stream.Printf("%s \n" + "typedef unsigned short unichar;\n" "void \n" "%s(void *$__lldb_arg) \n" "{ \n" " %s; \n" "} \n", + m_expr_prefix.c_str(), FunctionName(), m_expr_text.c_str()); } @@ -425,11 +431,13 @@ ClangUserExpression::DwarfOpcodeStream () lldb::ValueObjectSP -ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, const char *expr_cstr) +ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, + const char *expr_cstr, + const char *expr_prefix) { Error error; lldb::ValueObjectSP result_valobj_sp; - ClangUserExpression user_expression (expr_cstr); + ClangUserExpression user_expression (expr_cstr, expr_prefix); StreamString error_stream; diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index f9242b1972b..e8ed69d2834 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -17,6 +17,7 @@ #include "lldb/Breakpoint/BreakpointResolverAddress.h" #include "lldb/Breakpoint/BreakpointResolverFileLine.h" #include "lldb/Breakpoint/BreakpointResolverName.h" +#include "lldb/Core/DataBufferMemoryMap.h" #include "lldb/Core/Event.h" #include "lldb/Core/Log.h" #include "lldb/Core/Timer.h" @@ -853,6 +854,12 @@ Target::UpdateInstanceName () } } +const char * +Target::GetExpressionPrefixContentsAsCString () +{ + return m_expr_prefix_contents.c_str(); +} + //-------------------------------------------------------------- // class Target::SettingsController //-------------------------------------------------------------- @@ -976,6 +983,7 @@ TargetInstanceSettings::operator= (const TargetInstanceSettings &rhs) return *this; } +#define EXPR_PREFIX_STRING "expr-prefix" void TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name, @@ -987,14 +995,64 @@ TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_n Error &err, bool pending) { - // Currently 'target' does not have any instance settings. + static ConstString expr_prefix_str (EXPR_PREFIX_STRING); + + if (var_name == expr_prefix_str) + { + switch (op) + { + default: + err.SetErrorToGenericError (); + err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); + return; + case lldb::eVarSetOperationAssign: + { + FileSpec file_spec(value, true); + + if (!file_spec.Exists()) + { + err.SetErrorToGenericError (); + err.SetErrorStringWithFormat ("%s does not exist.\n", value); + return; + } + + DataBufferMemoryMap buf; + + if (!buf.MemoryMapFromFileSpec(&file_spec) && + buf.GetError().Fail()) + { + err.SetErrorToGenericError (); + err.SetErrorStringWithFormat ("Couldn't read from %s: %s\n", value, buf.GetError().AsCString()); + return; + } + + m_expr_prefix_path = value; + m_expr_prefix_contents.assign(reinterpret_cast<const char *>(buf.GetBytes()), buf.GetByteSize()); + } + return; + case lldb::eVarSetOperationAppend: + err.SetErrorToGenericError (); + err.SetErrorString ("Cannot append to a path.\n"); + return; + case lldb::eVarSetOperationClear: + m_expr_prefix_path.clear (); + m_expr_prefix_contents.clear (); + return; + } + } } void TargetInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, - bool pending) + bool pending) { - // Currently 'target' does not have any instance settings. + TargetInstanceSettings *new_settings_ptr = static_cast <TargetInstanceSettings *> (new_settings.get()); + + if (!new_settings_ptr) + return; + + m_expr_prefix_path = new_settings_ptr->m_expr_prefix_path; + m_expr_prefix_contents = new_settings_ptr->m_expr_prefix_contents; } bool @@ -1003,9 +1061,20 @@ TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, StringList &value, Error *err) { - if (err) - err->SetErrorString ("'target' does not have any instance settings"); - return false; + static ConstString expr_prefix_str (EXPR_PREFIX_STRING); + + if (var_name == expr_prefix_str) + { + value.AppendString (m_expr_prefix_path.c_str(), m_expr_prefix_path.size()); + } + else + { + if (err) + err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString()); + return false; + } + + return true; } const ConstString @@ -1028,14 +1097,15 @@ TargetInstanceSettings::CreateInstanceName () SettingEntry Target::SettingsController::global_settings_table[] = { - //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"}, - { "default-arch", eSetVarTypeString, NULL, NULL, false, false, "Default architecture to choose, when there's a choice." }, + //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, + { "default-arch", eSetVarTypeString, NULL, NULL, false, false, "Default architecture to choose, when there's a choice." }, { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } }; SettingEntry Target::SettingsController::instance_settings_table[] = { - //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, + //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"}, + { EXPR_PREFIX_STRING, eSetVarTypeString, NULL, NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." }, { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL } }; |