summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Expression/ClangExpressionVariable.h9
-rw-r--r--lldb/include/lldb/Target/CPPLanguageRuntime.h3
-rw-r--r--lldb/include/lldb/Target/LanguageRuntime.h5
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj1
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp50
-rw-r--r--lldb/source/Commands/CommandObjectExpression.h1
-rw-r--r--lldb/source/Expression/ClangExpressionVariable.cpp23
-rw-r--r--lldb/source/Expression/ClangFunction.cpp3
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp73
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h3
-rw-r--r--lldb/source/Target/CPPLanguageRuntime.cpp7
-rw-r--r--lldb/source/Target/ObjCLanguageRuntime.cpp3
12 files changed, 133 insertions, 48 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionVariable.h b/lldb/include/lldb/Expression/ClangExpressionVariable.h
index 8de5fa03249..2554fd84ff6 100644
--- a/lldb/include/lldb/Expression/ClangExpressionVariable.h
+++ b/lldb/include/lldb/Expression/ClangExpressionVariable.h
@@ -65,17 +65,22 @@ struct ClangExpressionVariable
ClangExpressionVariable(const ClangExpressionVariable &cev);
//----------------------------------------------------------------------
- /// If the variable contains its own data, make a Value point at it
+ /// If the variable contains its own data, make a Value point at it.
+ /// If \a exe_ctx in not NULL, the value will be resolved in with
+ /// that execution context.
///
/// @param[in] value
/// The value to point at the data.
///
+ /// @param[in] exe_ctx
+ /// The execution context to use to resolve \a value.
+ ///
/// @return
/// True on success; false otherwise (in particular, if this variable
/// does not contain its own data).
//----------------------------------------------------------------------
bool
- PointValueAtData(Value &value);
+ PointValueAtData(Value &value, ExecutionContext *exe_ctx);
//----------------------------------------------------------------------
/// The following values should stay valid for the life of the variable
diff --git a/lldb/include/lldb/Target/CPPLanguageRuntime.h b/lldb/include/lldb/Target/CPPLanguageRuntime.h
index e4906f9d716..4d98f1d9cf1 100644
--- a/lldb/include/lldb/Target/CPPLanguageRuntime.h
+++ b/lldb/include/lldb/Target/CPPLanguageRuntime.h
@@ -39,6 +39,9 @@ public:
virtual bool
GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope);
+ virtual bool
+ GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope);
+
protected:
//------------------------------------------------------------------
// Classes that inherit from CPPLanguageRuntime can see and modify these
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index 3066b9258da..eff5a0a9abd 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -17,6 +17,8 @@
#include "lldb/lldb-include.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/lldb-private.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/Value.h"
#include "lldb/Target/ExecutionContextScope.h"
namespace lldb_private {
@@ -37,6 +39,9 @@ public:
virtual bool
GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope) = 0;
+ virtual bool
+ GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope) = 0;
+
virtual lldb::ValueObjectSP
GetDynamicValue (lldb::ValueObjectSP in_value, ExecutionContextScope *exe_scope) = 0;
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index 1b2fa64627b..9ad57b1b26f 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -2431,7 +2431,6 @@
isa = PBXProject;
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
compatibilityVersion = "Xcode 3.1";
- developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 1e2d0235598..0060a71570a 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -16,6 +16,7 @@
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/InputReader.h"
+#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Expression/ClangExpressionVariable.h"
#include "lldb/Expression/ClangUserExpression.h"
#include "lldb/Expression/ClangFunction.h"
@@ -24,6 +25,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/Process.h"
@@ -69,6 +71,10 @@ CommandObjectExpression::CommandOptions::SetOptionValue (int option_idx, const c
case 'f':
error = Args::StringToFormat(option_arg, format);
break;
+
+ case 'o':
+ print_object = true;
+ break;
default:
error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
@@ -85,6 +91,7 @@ CommandObjectExpression::CommandOptions::ResetOptionValues ()
//language.Clear();
debug = false;
format = eFormatDefault;
+ print_object = false;
show_types = true;
show_summary = true;
}
@@ -230,16 +237,36 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream
{
StreamString ss;
- Error rc = expr_result->Print (ss,
- m_exe_ctx,
- m_options.format,
- m_options.show_types,
- m_options.show_summary,
- m_options.debug);
-
- if (rc.Fail()) {
- error_stream.Printf ("Couldn't print result : %s\n", rc.AsCString());
- return false;
+ if (m_options.print_object)
+ {
+ Value result_value;
+ if (expr_result->PointValueAtData(result_value, &m_exe_ctx))
+ {
+ bool obj_result;
+ ObjCLanguageRuntime *runtime = m_exe_ctx.process->GetObjCLanguageRuntime();
+ obj_result = runtime->GetObjectDescription (ss, result_value, m_exe_ctx.GetBestExecutionContextScope());
+ if (!obj_result)
+ {
+ error_stream.Printf ("Could not get object description: %s.\n", ss.GetData());
+ return false;
+ }
+ // Sometimes the description doesn't have a newline on the end. For now, I'll just add one here, if
+ ss.Printf("\n");
+ }
+ }
+ else
+ {
+ Error rc = expr_result->Print (ss,
+ m_exe_ctx,
+ m_options.format,
+ m_options.show_types,
+ m_options.show_summary,
+ m_options.debug);
+
+ if (rc.Fail()) {
+ error_stream.Printf ("Couldn't print result : %s\n", rc.AsCString());
+ return false;
+ }
}
output_stream.PutCString(ss.GetString().c_str());
@@ -345,7 +372,8 @@ lldb::OptionDefinition
CommandObjectExpression::CommandOptions::g_option_table[] =
{
//{ LLDB_OPT_SET_ALL, false, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."},
-{ LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."},
+{ LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."},
+{ LLDB_OPT_SET_2, false, "object-description", 'o', no_argument, NULL, 0, NULL, "Print the object description of the value resulting from the expression"},
{ LLDB_OPT_SET_ALL, false, "debug", 'g', no_argument, NULL, 0, NULL, "Enable verbose debug logging of the expression parsing and evaluation."},
{ LLDB_OPT_SET_ALL, false, "use-ir", 'i', no_argument, NULL, 0, NULL, "[Temporary] Instructs the expression evaluator to use IR instead of ASTs."},
{ 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL }
diff --git a/lldb/source/Commands/CommandObjectExpression.h b/lldb/source/Commands/CommandObjectExpression.h
index 4aed304a793..3229a427bec 100644
--- a/lldb/source/Commands/CommandObjectExpression.h
+++ b/lldb/source/Commands/CommandObjectExpression.h
@@ -50,6 +50,7 @@ public:
lldb::Encoding encoding;
lldb::Format format;
bool debug;
+ bool print_object;
bool show_types;
bool show_summary;
};
diff --git a/lldb/source/Expression/ClangExpressionVariable.cpp b/lldb/source/Expression/ClangExpressionVariable.cpp
index 37fc6c2354b..f406583dd72 100644
--- a/lldb/source/Expression/ClangExpressionVariable.cpp
+++ b/lldb/source/Expression/ClangExpressionVariable.cpp
@@ -50,23 +50,14 @@ ClangExpressionVariable::Print (Stream &output_stream,
{
Error err;
- if (!m_data_vars.get() || !m_data_vars->m_data)
+ Value val;
+ if (!PointValueAtData (val, &exe_ctx))
{
err.SetErrorToGenericError();
err.SetErrorStringWithFormat("Variable doesn't contain a value");
return err;
}
- Value val;
-
- clang::ASTContext *ast_context = m_user_type.GetASTContext();
-
- val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ());
- val.SetValueType (Value::eValueTypeHostAddress);
- val.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes ();
-
- val.ResolveValue (&exe_ctx, ast_context);
-
if (val.GetContextType () == Value::eContextTypeInvalid &&
val.GetValueType () == Value::eValueTypeScalar &&
format == lldb::eFormatDefault)
@@ -77,6 +68,8 @@ ClangExpressionVariable::Print (Stream &output_stream,
return err;
}
+ clang::ASTContext *ast_context = m_user_type.GetASTContext();
+
// The expression result is more complex and requires special handling
DataExtractor data;
Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0);
@@ -165,14 +158,18 @@ ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &
}
bool
-ClangExpressionVariable::PointValueAtData(Value &value)
+ClangExpressionVariable::PointValueAtData(Value &value, ExecutionContext *exe_ctx)
{
- if (!m_data_vars.get())
+ if (!m_data_vars.get() || !m_data_vars->m_data)
return false;
value.SetContext(Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType());
value.SetValueType(Value::eValueTypeHostAddress);
value.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes();
+ clang::ASTContext *ast_context = m_user_type.GetASTContext();
+
+ if (exe_ctx)
+ value.ResolveValue (exe_ctx, ast_context);
return true;
}
diff --git a/lldb/source/Expression/ClangFunction.cpp b/lldb/source/Expression/ClangFunction.cpp
index aaff16dbb6f..7f8d3ae77df 100644
--- a/lldb/source/Expression/ClangFunction.cpp
+++ b/lldb/source/Expression/ClangFunction.cpp
@@ -667,7 +667,8 @@ ClangFunction::ExecuteFunction (
// Thread we ran the function in may have gone away because we ran the target
// Check that it's still there.
exe_ctx.thread = exe_ctx.process->GetThreadList().FindThreadByIndexID(tid, true).get();
- exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex(0).get();
+ if (exe_ctx.thread)
+ exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex(0).get();
// Also restore the current process'es selected frame & thread, since this function calling may
// be done behind the user's back.
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp
index 346dc5411ca..e4acd960323 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp
@@ -10,6 +10,8 @@
#include "AppleObjCRuntimeV2.h"
#include "AppleObjCTrampolineHandler.h"
+#include "clang/AST/Type.h"
+
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
@@ -38,6 +40,28 @@ bool
AppleObjCRuntimeV2::GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope)
{
+ // ObjC objects can only be pointers:
+ if (!ClangASTContext::IsPointerType (object.GetClangType()))
+ return NULL;
+
+ // Make the argument list: we pass one arg, the address of our pointer, to the print function.
+ Scalar scalar;
+
+ if (!ClangASTType::GetValueAsScalar (object.GetClangAST(),
+ object.GetClangType(),
+ object.GetDataExtractor(),
+ 0,
+ object.GetByteSize(),
+ scalar))
+ return NULL;
+
+ Value val(scalar);
+ return GetObjectDescription(str, val, exe_scope);
+
+}
+bool
+AppleObjCRuntimeV2::GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope)
+{
if (!m_read_objc_library)
return false;
@@ -50,32 +74,41 @@ AppleObjCRuntimeV2::GetObjectDescription (Stream &str, ValueObject &object, Exec
// We need other parts of the exe_ctx, but the processes have to match.
assert (m_process == exe_ctx.process);
- // ObjC objects can only be pointers:
- if (!ClangASTContext::IsPointerType (object.GetClangType()))
- return NULL;
-
// Get the function address for the print function.
const Address *function_address = GetPrintForDebuggerAddr();
if (!function_address)
return false;
- // Make the argument list: we pass one arg, the address of our pointer, to the print function.
- Scalar scalar;
-
- if (!ClangASTType::GetValueAsScalar (object.GetClangAST(),
- object.GetClangType(),
- object.GetDataExtractor(),
- 0,
- object.GetByteSize(),
- scalar))
- return NULL;
-
- Value val(scalar);
- val.SetContext(Value::eContextTypeOpaqueClangQualType,
- ClangASTContext::GetVoidPtrType(object.GetClangAST(), false));
-
+ if (value.GetClangType())
+ {
+ clang::QualType value_type = clang::QualType::getFromOpaquePtr (value.GetClangType());
+ if (!value_type->isObjCObjectPointerType())
+ {
+ str.Printf ("Value doesn't point to an ObjC object.\n");
+ return false;
+ }
+ // FIXME: If we use the real types here then we end up crashing in the expression parser.
+ // For now, forcing this to be a generic pointer makes it work...
+#if 1
+ ClangASTContext *ast_context = exe_ctx.target->GetScratchClangASTContext();
+ if (value.GetContextType() == Value::eContextTypeOpaqueClangQualType)
+ {
+ value.SetContext(Value::eContextTypeOpaqueClangQualType, ast_context->GetVoidPtrType(false));
+ }
+#endif
+ }
+ else
+ {
+ // If it is not a pointer, see if we can make it into a pointer.
+ ClangASTContext *ast_context = exe_ctx.target->GetScratchClangASTContext();
+ void *opaque_type_ptr = ast_context->GetBuiltInType_objc_id();
+ if (opaque_type_ptr == NULL)
+ opaque_type_ptr = ast_context->GetVoidPtrType(false);
+ value.SetContext(Value::eContextTypeOpaqueClangQualType, opaque_type_ptr);
+ }
+
ValueList arg_value_list;
- arg_value_list.PushValue(val);
+ arg_value_list.PushValue(value);
// This is the return value:
const char *target_triple = exe_ctx.process->GetTargetTriple().GetCString();
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h
index 17c94bcf538..fcd1ec26ee1 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h
@@ -31,6 +31,9 @@ public:
// These are generic runtime functions:
virtual bool
+ GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope);
+
+ virtual bool
GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope);
virtual lldb::ValueObjectSP
diff --git a/lldb/source/Target/CPPLanguageRuntime.cpp b/lldb/source/Target/CPPLanguageRuntime.cpp
index d694b7702b3..d0fc7af8609 100644
--- a/lldb/source/Target/CPPLanguageRuntime.cpp
+++ b/lldb/source/Target/CPPLanguageRuntime.cpp
@@ -33,3 +33,10 @@ CPPLanguageRuntime::GetObjectDescription (Stream &str, ValueObject &object, Exec
// C++ has no generic way to do this.
return false;
}
+
+bool
+CPPLanguageRuntime::GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope)
+{
+ // C++ has no generic way to do this.
+ return false;
+}
diff --git a/lldb/source/Target/ObjCLanguageRuntime.cpp b/lldb/source/Target/ObjCLanguageRuntime.cpp
index 0a136336a26..7f4de245116 100644
--- a/lldb/source/Target/ObjCLanguageRuntime.cpp
+++ b/lldb/source/Target/ObjCLanguageRuntime.cpp
@@ -6,9 +6,12 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/Type.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
using namespace lldb;
OpenPOWER on IntegriCloud