summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2011-12-13 01:42:04 +0000
committerSean Callanan <scallanan@apple.com>2011-12-13 01:42:04 +0000
commitd5cc132b9848dc368717b3ff203fe77f89801ff5 (patch)
treedfdebcf5ce751a425f4fcc18d8560ae869f2e221
parent7a084fdd39babbd2bafd3ee7174361fb0df8b86d (diff)
downloadbcm5719-llvm-d5cc132b9848dc368717b3ff203fe77f89801ff5.tar.gz
bcm5719-llvm-d5cc132b9848dc368717b3ff203fe77f89801ff5.zip
I have modified the part of the code that finds and
validates the "self," "this," and "_cmd" pointers that get passed into expressions. It used to check them aggressively for validity before allowing the expression to run as an object method; now, this functionality is gated by a bool and off by default. Now the default is that when LLDB is stopped in a method of a class, code entered using "expr" will always masquerade as an instance method. If for some reason "self," "this," or "_cmd" is unavailable it will be reported as NULL. This may cause the expression to crash if it relies on those pointers, but for example getting the addresses of ivars will now work as the user would expect. llvm-svn: 146465
-rw-r--r--lldb/include/lldb/Expression/ClangUserExpression.h1
-rw-r--r--lldb/source/Expression/ClangUserExpression.cpp93
2 files changed, 51 insertions, 43 deletions
diff --git a/lldb/include/lldb/Expression/ClangUserExpression.h b/lldb/include/lldb/Expression/ClangUserExpression.h
index 9e57eedaec5..6ce1c374d63 100644
--- a/lldb/include/lldb/Expression/ClangUserExpression.h
+++ b/lldb/include/lldb/Expression/ClangUserExpression.h
@@ -354,6 +354,7 @@ private:
std::auto_ptr<ASTResultSynthesizer> m_result_synthesizer; ///< The result synthesizer, if one is needed.
+ bool m_enforce_valid_object; ///< True if the expression parser should enforce the presence of a valid class pointer in order to generate the expression as a method.
bool m_cplusplus; ///< True if the expression is compiled as a C++ member function (true if it was parsed when exe_ctx was in a C++ method).
bool m_objectivec; ///< True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was in an Objective-C method).
bool m_static_method; ///< True if the expression is compiled as a static (or class) method (currently true if it was parsed when exe_ctx was in an Objective-C class method).
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp
index 04d5c32d1f2..e749d027bf7 100644
--- a/lldb/source/Expression/ClangUserExpression.cpp
+++ b/lldb/source/Expression/ClangUserExpression.cpp
@@ -59,7 +59,8 @@ ClangUserExpression::ClangUserExpression (const char *expr,
m_static_method(false),
m_target (NULL),
m_evaluated_statically (false),
- m_const_result ()
+ m_const_result (),
+ m_enforce_valid_object (false)
{
switch (m_language)
{
@@ -128,26 +129,29 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
{
if (m_allow_cxx && method_decl->isInstance())
{
- VariableList *vars = frame->GetVariableList(false);
-
- const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
-
- if (!vars)
- {
- err.SetErrorToGenericError();
- err.SetErrorString(thisErrorString);
- return;
- }
-
- lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
-
- if (!this_var ||
- !this_var->IsInScope(frame) ||
- !this_var->LocationIsValidForFrame (frame))
+ if (m_enforce_valid_object)
{
- err.SetErrorToGenericError();
- err.SetErrorString(thisErrorString);
- return;
+ VariableList *vars = frame->GetVariableList(false);
+
+ const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
+
+ if (!vars)
+ {
+ err.SetErrorToGenericError();
+ err.SetErrorString(thisErrorString);
+ return;
+ }
+
+ lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
+
+ if (!this_var ||
+ !this_var->IsInScope(frame) ||
+ !this_var->LocationIsValidForFrame (frame))
+ {
+ err.SetErrorToGenericError();
+ err.SetErrorString(thisErrorString);
+ return;
+ }
}
m_cplusplus = true;
@@ -169,26 +173,29 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
{
if (m_allow_objc)
{
- VariableList *vars = frame->GetVariableList(false);
-
- const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
-
- if (!vars)
+ if (m_enforce_valid_object)
{
- err.SetErrorToGenericError();
- err.SetErrorString(selfErrorString);
- return;
- }
-
- lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
-
- if (!self_var ||
- !self_var->IsInScope(frame) ||
- !self_var->LocationIsValidForFrame (frame))
- {
- err.SetErrorToGenericError();
- err.SetErrorString(selfErrorString);
- return;
+ VariableList *vars = frame->GetVariableList(false);
+
+ const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
+
+ if (!vars)
+ {
+ err.SetErrorToGenericError();
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
+
+ if (!self_var ||
+ !self_var->IsInScope(frame) ||
+ !self_var->LocationIsValidForFrame (frame))
+ {
+ err.SetErrorToGenericError();
+ err.SetErrorString(selfErrorString);
+ return;
+ }
}
m_objectivec = true;
@@ -400,8 +407,8 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
if (!(m_expr_decl_map->GetObjectPointer(object_ptr, object_name, exe_ctx, materialize_error)))
{
- error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
- return false;
+ error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", materialize_error.AsCString());
+ object_ptr = 0;
}
if (m_objectivec)
@@ -410,8 +417,8 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
if (!(m_expr_decl_map->GetObjectPointer(cmd_ptr, cmd_name, exe_ctx, materialize_error, true)))
{
- error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
- return false;
+ error_stream.Printf("warning: couldn't get object pointer (substituting NULL): %s\n", materialize_error.AsCString());
+ cmd_ptr = 0;
}
}
}
OpenPOWER on IntegriCloud