diff options
author | Greg Clayton <gclayton@apple.com> | 2010-12-14 02:59:59 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2010-12-14 02:59:59 +0000 |
commit | 8b2fe6dcbdf27b0df84ef4bdf514f9bc577c5804 (patch) | |
tree | 9816fbd1612d4cb872b44f996c47f67f9fc6470f /lldb/source | |
parent | 12960558416a6797ea7504e7d9934bb11a5b1f42 (diff) | |
download | bcm5719-llvm-8b2fe6dcbdf27b0df84ef4bdf514f9bc577c5804.tar.gz bcm5719-llvm-8b2fe6dcbdf27b0df84ef4bdf514f9bc577c5804.zip |
Modified LLDB expressions to not have to JIT and run code just to see variable
values or persistent expression variables. Now if an expression consists of
a value that is a child of a variable, or of a persistent variable only, we
will create a value object for it and make a ValueObjectConstResult from it to
freeze the value (for program variables only, not persistent variables) and
avoid running JITed code. For everything else we still parse up and JIT code
and run it in the inferior.
There was also a lot of clean up in the expression code. I made the
ClangExpressionVariables be stored in collections of shared pointers instead
of in collections of objects. This will help stop a lot of copy constructors on
these large objects and also cleans up the code considerably. The persistent
clang expression variables were moved over to the Target to ensure they persist
across process executions.
Added the ability for lldb_private::Target objects to evaluate expressions.
We want to evaluate expressions at the target level in case we aren't running
yet, or we have just completed running. We still want to be able to access the
persistent expression variables between runs, and also evaluate constant
expressions.
Added extra logging to the dynamic loader plug-in for MacOSX. ModuleList objects
can now dump their contents with the UUID, arch and full paths being logged with
appropriate prefix values.
Thread hardened the Communication class a bit by making the connection auto_ptr
member into a shared pointer member and then making a local copy of the shared
pointer in each method that uses it to make sure another thread can't nuke the
connection object while it is being used by another thread.
Added a new file to the lldb/test/load_unload test that causes the test a.out file
to link to the libd.dylib file all the time. This will allow us to test using
the DYLD_LIBRARY_PATH environment variable after moving libd.dylib somewhere else.
llvm-svn: 121745
Diffstat (limited to 'lldb/source')
24 files changed, 1070 insertions, 470 deletions
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index a20d2d03967..2d685fa75f3 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -570,16 +570,10 @@ SBFrame::EvaluateExpression (const char *expr) if (m_opaque_sp) { - ExecutionContext exe_ctx; - m_opaque_sp->CalculateExecutionContext (exe_ctx); - - const char *prefix = NULL; - const bool discard_on_error = true; - - if (exe_ctx.target) - prefix = exe_ctx.target->GetExpressionPrefixContentsAsCString(); - - ClangUserExpression::Evaluate (exe_ctx, discard_on_error, expr, prefix, *expr_result); + lldb::ExecutionResults exe_results; + const bool unwind_on_error = true; + + exe_results = m_opaque_sp->GetThread().GetProcess().GetTarget().EvaluateExpression(expr, m_opaque_sp.get(), unwind_on_error, *expr_result); } if (expr_log) diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index c58f3f529c8..d0e9ef9ed27 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -232,55 +232,55 @@ CommandObjectExpression::EvaluateExpression CommandReturnObject *result ) { - if (!m_exe_ctx.process) - { - error_stream.Printf ("Execution context doesn't contain a process\n"); - return false; - } - - const char *prefix = NULL; - if (m_exe_ctx.target) - prefix = m_exe_ctx.target->GetExpressionPrefixContentsAsCString(); - - lldb::ValueObjectSP result_valobj_sp; - Process::ExecutionResults execution_results = ClangUserExpression::Evaluate (m_exe_ctx, m_options.unwind_on_error, expr, prefix, result_valobj_sp); - assert (result_valobj_sp.get()); - if (result_valobj_sp->GetError().Success()) { - if (m_options.format != eFormatDefault) - result_valobj_sp->SetFormat (m_options.format); - - ValueObject::DumpValueObject (output_stream, - m_exe_ctx.GetBestExecutionContextScope(), - result_valobj_sp.get(), // Variable object to dump - result_valobj_sp->GetName().AsCString(),// Root object name - 0, // Pointer depth to traverse (zero means stop at pointers) - 0, // Current depth, this is the top most, so zero... - UINT32_MAX, // Max depth to go when dumping concrete types, dump everything... - m_options.show_types, // Show types when dumping? - false, // Show locations of variables, no since this is a host address which we don't care to see - m_options.print_object, // Print the objective C object? - true, // Scope is already checked. Const results are always in scope. - false); // Don't flatten output - if (result) - result->SetStatus (eReturnStatusSuccessFinishResult); - } - else - { - error_stream.PutCString(result_valobj_sp->GetError().AsCString()); - // If we've been interrupted, display state information. - if (execution_results == Process::eExecutionInterrupted && !m_options.unwind_on_error) + lldb::ValueObjectSP result_valobj_sp; + + lldb::ExecutionResults exe_results; + exe_results = m_exe_ctx.target->EvaluateExpression(expr, m_exe_ctx.frame, m_options.unwind_on_error, result_valobj_sp); + + if (exe_results == eExecutionInterrupted && !m_options.unwind_on_error) { if (m_exe_ctx.thread) lldb_private::DisplayThreadInfo (m_interpreter, result->GetOutputStream(), m_exe_ctx.thread, false, true); else - { lldb_private::DisplayThreadsInfo (m_interpreter, &m_exe_ctx, *result, true, true); + } + + if (result_valobj_sp) + { + if (result_valobj_sp->GetError().Success()) + { + if (m_options.format != eFormatDefault) + result_valobj_sp->SetFormat (m_options.format); + + ValueObject::DumpValueObject (output_stream, + m_exe_ctx.GetBestExecutionContextScope(), + result_valobj_sp.get(), // Variable object to dump + result_valobj_sp->GetName().GetCString(),// Root object name + 0, // Pointer depth to traverse (zero means stop at pointers) + 0, // Current depth, this is the top most, so zero... + UINT32_MAX, // Max depth to go when dumping concrete types, dump everything... + m_options.show_types, // Show types when dumping? + false, // Show locations of variables, no since this is a host address which we don't care to see + m_options.print_object, // Print the objective C object? + true, // Scope is already checked. Const results are always in scope. + false); // Don't flatten output + if (result) + result->SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + error_stream.PutCString(result_valobj_sp->GetError().AsCString()); + if (result) + result->SetStatus (eReturnStatusFailed); } } - if (result) - result->SetStatus (eReturnStatusFailed); + } + else + { + error_stream.Printf ("error: invalid execution context for expression\n"); + return false; } return true; diff --git a/lldb/source/Core/Communication.cpp b/lldb/source/Core/Communication.cpp index 3ecdb4e8ec0..99c619da606 100644 --- a/lldb/source/Core/Communication.cpp +++ b/lldb/source/Core/Communication.cpp @@ -27,7 +27,7 @@ using namespace lldb_private; //---------------------------------------------------------------------- Communication::Communication(const char *name) : Broadcaster (name), - m_connection_ap (), + m_connection_sp (), m_read_thread (LLDB_INVALID_HOST_THREAD), m_read_thread_enabled (false), m_bytes(), @@ -65,8 +65,9 @@ Communication::BytesAvailable (uint32_t timeout_usec, Error *error_ptr) { lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::BytesAvailable (timeout_usec = %u)", this, timeout_usec); - if (m_connection_ap.get()) - return m_connection_ap->BytesAvailable (timeout_usec, error_ptr); + lldb::ConnectionSP connection_sp (m_connection_sp); + if (connection_sp.get()) + return connection_sp->BytesAvailable (timeout_usec, error_ptr); if (error_ptr) error_ptr->SetErrorString("Invalid connection."); return eConnectionStatusNoConnection; @@ -79,8 +80,9 @@ Communication::Connect (const char *url, Error *error_ptr) lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Connect (url = %s)", this, url); - if (m_connection_ap.get()) - return m_connection_ap->Connect (url, error_ptr); + lldb::ConnectionSP connection_sp (m_connection_sp); + if (connection_sp.get()) + return connection_sp->Connect (url, error_ptr); if (error_ptr) error_ptr->SetErrorString("Invalid connection."); return eConnectionStatusNoConnection; @@ -91,10 +93,11 @@ Communication::Disconnect (Error *error_ptr) { lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Disconnect ()", this); - if (m_connection_ap.get()) + lldb::ConnectionSP connection_sp (m_connection_sp); + if (connection_sp.get()) { - ConnectionStatus status = m_connection_ap->Disconnect (error_ptr); - // We currently don't protect m_connection_ap with any mutex for + ConnectionStatus status = connection_sp->Disconnect (error_ptr); + // We currently don't protect connection_sp with any mutex for // multi-threaded environments. So lets not nuke our connection class // without putting some multi-threaded protections in. We also probably // don't want to pay for the overhead it might cause if every time we @@ -103,7 +106,7 @@ Communication::Disconnect (Error *error_ptr) // This auto_ptr will cleanup after itself when this object goes away, // so there is no need to currently have it destroy itself immediately // upon disconnnect. - //m_connection_ap.reset(); + //connection_sp.reset(); return status; } return eConnectionStatusNoConnection; @@ -112,23 +115,28 @@ Communication::Disconnect (Error *error_ptr) bool Communication::IsConnected () const { - if (m_connection_ap.get()) - return m_connection_ap->IsConnected (); + lldb::ConnectionSP connection_sp (m_connection_sp); + if (connection_sp.get()) + return connection_sp->IsConnected (); return false; } bool Communication::HasConnection () const { - return m_connection_ap.get() != NULL; + return m_connection_sp.get() != NULL; } size_t Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr) { lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, - "%p Communication::Write (dst = %p, dst_len = %zu, timeout_usec = %u) connection = %p", - this, dst, dst_len, timeout_usec, m_connection_ap.get()); + "%p Communication::Read (dst = %p, dst_len = %zu, timeout_usec = %u) connection = %p", + this, + dst, + dst_len, + timeout_usec, + m_connection_sp.get()); if (m_read_thread != LLDB_INVALID_HOST_THREAD) { @@ -140,7 +148,7 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio return cached_bytes; } - if (m_connection_ap.get() == NULL) + if (m_connection_sp.get() == NULL) { if (error_ptr) error_ptr->SetErrorString("Invalid connection."); @@ -177,11 +185,12 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio // We aren't using a read thread, just read the data synchronously in this // thread. - if (m_connection_ap.get()) + lldb::ConnectionSP connection_sp (m_connection_sp); + if (connection_sp.get()) { - status = m_connection_ap->BytesAvailable (timeout_usec, error_ptr); + status = connection_sp->BytesAvailable (timeout_usec, error_ptr); if (status == eConnectionStatusSuccess) - return m_connection_ap->Read (dst, dst_len, status, error_ptr); + return connection_sp->Read (dst, dst_len, status, error_ptr); } if (error_ptr) @@ -194,12 +203,17 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio size_t Communication::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr) { + lldb::ConnectionSP connection_sp (m_connection_sp); + lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, - "%p Communication::Write (src = %p, src_len = %zu) connection = %p", - this, src, src_len, m_connection_ap.get()); + "%p Communication::Write (src = %p, src_len = %zu) connection = %p", + this, + src, + src_len, + connection_sp.get()); - if (m_connection_ap.get()) - return m_connection_ap->Write (src, src_len, status, error_ptr); + if (connection_sp.get()) + return connection_sp->Write (src, src_len, status, error_ptr); if (error_ptr) error_ptr->SetErrorString("Invalid connection."); @@ -294,8 +308,9 @@ Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broad size_t Communication::ReadFromConnection (void *dst, size_t dst_len, ConnectionStatus &status, Error *error_ptr) { - if (m_connection_ap.get()) - return m_connection_ap->Read (dst, dst_len, status, error_ptr); + lldb::ConnectionSP connection_sp (m_connection_sp); + if (connection_sp.get()) + return connection_sp->Read (dst, dst_len, status, error_ptr); return 0; } @@ -376,7 +391,7 @@ Communication::SetConnection (Connection *connection) { StopReadThread(NULL); Disconnect (NULL); - m_connection_ap.reset(connection); + m_connection_sp.reset(connection); } const char * diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index d829123401e..aca9a973f95 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -13,6 +13,7 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Host/Symbols.h" #include "lldb/Symbol/ObjectFile.h" @@ -374,6 +375,29 @@ ModuleList::Dump(Stream *s) const } } +void +ModuleList::LogUUIDAndPaths (LogSP &log_sp, const char *prefix_cstr) +{ + if (log_sp) + { + Mutex::Locker locker(m_modules_mutex); + char uuid_cstr[256]; + collection::const_iterator pos, begin = m_modules.begin(), end = m_modules.end(); + for (pos = begin; pos != end; ++pos) + { + Module *module = pos->get(); + module->GetUUID().GetAsCString (uuid_cstr, sizeof(uuid_cstr)); + const FileSpec &module_file_spec = module->GetFileSpec(); + log_sp->Printf ("%s[%u] %s (%s) \"%s/%s\"", + prefix_cstr ? prefix_cstr : "", + (uint32_t)std::distance (begin, pos), + uuid_cstr, + module->GetArchitecture().AsCString(), + module_file_spec.GetDirectory().GetCString(), + module_file_spec.GetFilename().GetCString()); + } + } +} bool ModuleList::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp index 920c467333e..c346371a5e9 100644 --- a/lldb/source/Core/Value.cpp +++ b/lldb/source/Core/Value.cpp @@ -162,34 +162,6 @@ Value::GetProxyTarget() return NULL; } -//#include "clang/Lex/LiteralSupport.h" -//#include "clang/AST/ASTContext.h" -//#include "clang/Frontend/CompilerInstance.h" -// -//Value::Value (const char *data, llvm::CompilerInstance *compiler) -//{ -// clang::NumericLiteralParser parser(data, data + strlen(data), clang::SourceLocation(), -// compiler->getPreprocessor()); -// if (parser.had_error) -// { -// } -// else if (parser.isBool) -// { -// APInt value; -// parser.GetIntegerValue(value); -// } -// else if (parser.isLong) -// { -// } -// else if (parser.isLongLong) -// { -// } -// else if (parser.isFloat) -// { -// } -// -//} -// void Value::Dump (Stream* strm) { @@ -484,6 +456,34 @@ Value::GetValueDefaultFormat () return eFormatHex; } +bool +Value::GetData (DataExtractor &data) +{ + switch (m_value_type) + { + default: + break; + + case eValueTypeScalar: + if (m_value.GetData (data)) + return true; + break; + + case eValueTypeLoadAddress: + case eValueTypeFileAddress: + case eValueTypeHostAddress: + if (m_data_buffer.GetByteSize()) + { + data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(), data.GetByteOrder()); + return true; + } + break; + } + + return false; + +} + Error Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context, DataExtractor &data, uint32_t data_offset) { diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 64c646ba567..60b1009ad7a 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -21,6 +21,7 @@ #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/StreamString.h" #include "lldb/Core/ValueObjectChild.h" +#include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Symbol/ClangASTType.h" @@ -62,7 +63,8 @@ ValueObject::ValueObject (ValueObject *parent) : m_value_is_valid (false), m_value_did_change (false), m_children_count_valid (false), - m_old_value_valid (false) + m_old_value_valid (false), + m_pointers_point_to_load_addrs (false) { } @@ -281,7 +283,7 @@ ValueObject::GetIndexOfChildWithName (const ConstString &name) bool omit_empty_base_classes = true; return ClangASTContext::GetIndexOfChildWithName (GetClangAST(), GetClangType(), - name.AsCString(), + name.GetCString(), omit_empty_base_classes); } @@ -297,7 +299,7 @@ ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create) bool omit_empty_base_classes = true; const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast, clang_type, - name.AsCString(), + name.GetCString(), omit_empty_base_classes, child_indexes); ValueObjectSP child_sp; @@ -370,7 +372,7 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3 clang_type_t clang_type = GetClangType(); clang_type_t child_clang_type; child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast, - GetName().AsCString(), + GetName().GetCString(), clang_type, idx, transparent_pointers, @@ -399,6 +401,8 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class)); + if (m_pointers_point_to_load_addrs) + valobj_sp->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs); } return valobj_sp; } @@ -418,8 +422,8 @@ ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope) StreamString sstr; clang_type_t elem_or_pointee_clang_type; const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, - GetClangAST(), - &elem_or_pointee_clang_type)); + GetClangAST(), + &elem_or_pointee_clang_type)); if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) && ClangASTContext::IsCharType (elem_or_pointee_clang_type)) @@ -721,6 +725,10 @@ ValueObject::GetPointerValue (lldb::AddressType &address_type, bool scalar_is_lo } break; } + + if (m_pointers_point_to_load_addrs) + address_type = eAddressTypeLoad; + return address; } @@ -956,7 +964,7 @@ ValueObject::GetExpressionPath (Stream &s) } else { - const char *name = GetName().AsCString(); + const char *name = GetName().GetCString(); if (name) s.PutCString(name); } @@ -1001,7 +1009,7 @@ ValueObject::DumpValueObject // Always show the type for the top level items. if (show_types || curr_depth == 0) - s.Printf("(%s) ", valobj->GetTypeName().AsCString()); + s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>")); if (flat_output) @@ -1163,3 +1171,197 @@ ValueObject::DumpValueObject } } + +ValueObjectSP +ValueObject::CreateConstantValue (ExecutionContextScope *exe_scope, const ConstString &name) +{ + ValueObjectSP valobj_sp; + + if (UpdateValueIfNeeded(exe_scope) && m_error.Success()) + { + ExecutionContext exe_ctx; + exe_scope->CalculateExecutionContext(exe_ctx); + + clang::ASTContext *ast = GetClangAST (); + + DataExtractor data; + data.SetByteOrder (m_data.GetByteOrder()); + data.SetAddressByteSize(m_data.GetAddressByteSize()); + + m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0); + + valobj_sp.reset (new ValueObjectConstResult (ast, + GetClangType(), + name, + data)); + } + else + { + valobj_sp.reset (new ValueObjectConstResult (m_error)); + } + return valobj_sp; +} + +lldb::ValueObjectSP +ValueObject::Dereference (ExecutionContextScope *exe_scope, Error *error_ptr) +{ + lldb::ValueObjectSP valobj_sp; + if (IsPointerType()) + { + bool omit_empty_base_classes = true; + + std::string child_name_str; + uint32_t child_byte_size = 0; + int32_t child_byte_offset = 0; + uint32_t child_bitfield_bit_size = 0; + uint32_t child_bitfield_bit_offset = 0; + bool child_is_base_class = false; + const bool transparent_pointers = false; + clang::ASTContext *clang_ast = GetClangAST(); + clang_type_t clang_type = GetClangType(); + clang_type_t child_clang_type; + child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast, + GetName().GetCString(), + clang_type, + 0, + transparent_pointers, + omit_empty_base_classes, + child_name_str, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class); + if (child_clang_type) + { + ConstString child_name; + if (!child_name_str.empty()) + child_name.SetCString (child_name_str.c_str()); + + valobj_sp.reset (new ValueObjectChild (this, + clang_ast, + child_clang_type, + child_name, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class)); + } + } + else + { + if (error_ptr) + error_ptr->SetErrorString("can't dereference a non-pointer value"); + } + + return valobj_sp; +} + + + +//lldb::ValueObjectSP +//ValueObject::Dereference (ExecutionContextScope *exe_scope, Error *error_ptr) +//{ +// lldb::ValueObjectSP valobj_sp; +// if (IsPointerType()) +// { +// UpdateValueIfNeeded(exe_scope); +// if (m_error.Success()) +// { +// lldb::AddressType address_type = eAddressTypeInvalid; +// const bool scalar_is_load_address = true; +// lldb::addr_t addr = GetPointerValue (address_type, scalar_is_load_address); +// if (addr != LLDB_INVALID_ADDRESS) +// { +// switch (address_type) +// { +// case eAddressTypeInvalid: +// if (error_ptr) +// error_ptr->SetErrorString("value is not in memory"); +// break; +// case eAddressTypeFile: +// case eAddressTypeLoad: +// case eAddressTypeHost: +// { +// clang::ASTContext *ast = GetClangAST(); +// clang_type_t clang_type = ClangASTType::GetPointeeType (GetClangType()); +// if (ast && clang_type) +// { +// std::string name (1, '*'); +// name.append (m_name.AsCString("")); +// valobj_sp.reset (new ValueObjectConstResult (ast, +// ClangASTContext::CreatePointerType (ast, clang_type), +// ConstString (name.c_str()), +// addr, +// address_type, +// m_data.GetAddressByteSize())); +// } +// else +// { +// if (error_ptr) +// error_ptr->SetErrorString("invalid clang type info"); +// } +// } +// break; +// } +// } +// else +// { +// if (error_ptr) +// error_ptr->SetErrorString("failed to extract pointer value"); +// } +// } +// else +// { +// if (error_ptr) +// *error_ptr = m_error; +// } +// } +// else +// { +// if (error_ptr) +// error_ptr->SetErrorString("can't dereference a non-pointer value"); +// } +// +// return valobj_sp; +//} + +lldb::ValueObjectSP +ValueObject::AddressOf () +{ + lldb::ValueObjectSP valobj_sp; + + lldb::AddressType address_type = eAddressTypeInvalid; + const bool scalar_is_load_address = false; + lldb::addr_t addr = GetAddressOf (address_type, scalar_is_load_address); + if (addr != LLDB_INVALID_ADDRESS) + { + switch (address_type) + { + case eAddressTypeInvalid: + break; + case eAddressTypeFile: + case eAddressTypeLoad: + case eAddressTypeHost: + { + clang::ASTContext *ast = GetClangAST(); + clang_type_t clang_type = GetClangType(); + if (ast && clang_type) + { + std::string name (1, '&'); + name.append (m_name.AsCString("")); + valobj_sp.reset (new ValueObjectConstResult (ast, + ClangASTContext::CreatePointerType (ast, clang_type), + ConstString (name.c_str()), + addr, + address_type, + m_data.GetAddressByteSize())); + } + } + break; + } + } + return valobj_sp; +} + diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp index b8966da73ba..6c785c5656d 100644 --- a/lldb/source/Core/ValueObjectChild.cpp +++ b/lldb/source/Core/ValueObjectChild.cpp @@ -125,7 +125,8 @@ ValueObjectChild::UpdateValue (ExecutionContextScope *exe_scope) else { m_value.GetScalar() += m_byte_offset; - if (value_type == Value::eValueTypeScalar || + if (m_pointers_point_to_load_addrs || + value_type == Value::eValueTypeScalar || value_type == Value::eValueTypeFileAddress) m_value.SetValueType (Value::eValueTypeLoadAddress); } diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp index ef7c7b9e3b1..7e122ab5bf9 100644 --- a/lldb/source/Core/ValueObjectConstResult.cpp +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -28,6 +28,45 @@ using namespace lldb_private; ValueObjectConstResult::ValueObjectConstResult ( + ByteOrder byte_order, + uint32_t addr_byte_size +) : + ValueObject (NULL), + m_clang_ast (NULL), + m_type_name (), + m_byte_size (0) +{ + SetIsConstant (); + SetValueIsValid(true); + m_data.SetByteOrder(byte_order); + m_data.SetAddressByteSize(addr_byte_size); + m_pointers_point_to_load_addrs = true; +} + +ValueObjectConstResult::ValueObjectConstResult +( + clang::ASTContext *clang_ast, + void *clang_type, + const ConstString &name, + const DataExtractor &data +) : + ValueObject (NULL), + m_clang_ast (clang_ast), + m_type_name (), + m_byte_size (0) +{ + m_data = data; + m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); + m_value.SetValueType(Value::eValueTypeHostAddress); + m_value.SetContext(Value::eContextTypeClangType, clang_type); + m_name = name; + SetIsConstant (); + SetValueIsValid(true); + m_pointers_point_to_load_addrs = true; +} + +ValueObjectConstResult::ValueObjectConstResult +( clang::ASTContext *clang_ast, void *clang_type, const ConstString &name, @@ -37,7 +76,8 @@ ValueObjectConstResult::ValueObjectConstResult ) : ValueObject (NULL), m_clang_ast (clang_ast), - m_type_name () + m_type_name (), + m_byte_size (0) { m_data.SetByteOrder(data_byte_order); m_data.SetAddressByteSize(data_addr_size); @@ -48,15 +88,51 @@ ValueObjectConstResult::ValueObjectConstResult m_name = name; SetIsConstant (); SetValueIsValid(true); + m_pointers_point_to_load_addrs = true; +} + +ValueObjectConstResult::ValueObjectConstResult +( + clang::ASTContext *clang_ast, + void *clang_type, + const ConstString &name, + lldb::addr_t address, + lldb::AddressType address_type, + uint8_t addr_byte_size +) : + ValueObject (NULL), + m_clang_ast (clang_ast), + m_type_name (), + m_byte_size (0) +{ + m_value.GetScalar() = address; + m_data.SetAddressByteSize(addr_byte_size); + m_value.GetScalar().GetData (m_data, addr_byte_size); + //m_value.SetValueType(Value::eValueTypeHostAddress); + switch (address_type) + { + default: + case eAddressTypeInvalid: m_value.SetValueType(Value::eValueTypeScalar); break; + case eAddressTypeFile: m_value.SetValueType(Value::eValueTypeFileAddress); break; + case eAddressTypeLoad: m_value.SetValueType(Value::eValueTypeLoadAddress); break; + case eAddressTypeHost: m_value.SetValueType(Value::eValueTypeHostAddress); break; + } + m_value.SetContext(Value::eContextTypeClangType, clang_type); + m_name = name; + SetIsConstant (); + SetValueIsValid(true); + m_pointers_point_to_load_addrs = true; } ValueObjectConstResult::ValueObjectConstResult (const Error& error) : ValueObject (NULL), m_clang_ast (NULL), - m_type_name () + m_type_name (), + m_byte_size (0) { m_error = error; SetIsConstant (); + m_pointers_point_to_load_addrs = true; } ValueObjectConstResult::~ValueObjectConstResult() @@ -78,8 +154,18 @@ ValueObjectConstResult::GetValueType() const size_t ValueObjectConstResult::GetByteSize() { - // We stored all the data for this const object in our data - return m_data.GetByteSize(); + if (m_byte_size == 0) + { + uint64_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetClangType()); + m_byte_size = (bit_width + 7 ) / 8; + } + return m_byte_size; +} + +void +ValueObjectConstResult::SetByteSize (size_t size) +{ + m_byte_size = size; } uint32_t @@ -105,7 +191,6 @@ ValueObjectConstResult::GetTypeName() void ValueObjectConstResult::UpdateValue (ExecutionContextScope *exe_scope) { - m_error.Clear(); // Const value is always valid SetValueIsValid (true); } diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index b210d49821b..be6d709bdb1 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -59,7 +59,8 @@ ClangExpressionDeclMap::~ClangExpressionDeclMap() DisableStructVars(); } -void ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx) +void +ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx) { EnableParserVars(); m_parser_vars->m_exe_ctx = &exe_ctx; @@ -69,32 +70,35 @@ void ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx) else if (exe_ctx.thread) m_parser_vars->m_sym_ctx = exe_ctx.thread->GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything); - if (exe_ctx.process) - m_parser_vars->m_persistent_vars = &exe_ctx.process->GetPersistentVariables(); + if (exe_ctx.target) + m_parser_vars->m_persistent_vars = &exe_ctx.target->GetPersistentVariables(); } -void ClangExpressionDeclMap::DidParse() +void +ClangExpressionDeclMap::DidParse() { if (m_parser_vars.get()) { - for (uint64_t entity_index = 0, num_entities = m_found_entities.Size(); + for (size_t entity_index = 0, num_entities = m_found_entities.GetSize(); entity_index < num_entities; ++entity_index) { - ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index)); - if (entity.m_parser_vars.get() && - entity.m_parser_vars->m_lldb_value) - delete entity.m_parser_vars->m_lldb_value; + ClangExpressionVariableSP var_sp(m_found_entities.GetVariableAtIndex(entity_index)); + if (var_sp && + var_sp->m_parser_vars.get() && + var_sp->m_parser_vars->m_lldb_value) + delete var_sp->m_parser_vars->m_lldb_value; - entity.DisableParserVars(); + var_sp->DisableParserVars(); } - for (uint64_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->Size(); + for (size_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->GetSize(); pvar_index < num_pvars; ++pvar_index) { - ClangExpressionVariable &pvar(m_parser_vars->m_persistent_vars->VariableAtIndex(pvar_index)); - pvar.DisableParserVars(); + ClangExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index)); + if (pvar_sp) + pvar_sp->DisableParserVars(); } DisableParserVars(); @@ -108,10 +112,12 @@ ClangExpressionDeclMap::GetPersistentResultName () { assert (m_struct_vars.get()); assert (m_parser_vars.get()); - if (!m_struct_vars->m_result_name) - m_parser_vars->m_persistent_vars->GetNextResultName(m_struct_vars->m_result_name); - + { + Target *target = m_parser_vars->GetTarget(); + assert (target); + m_struct_vars->m_result_name = target->GetPersistentVariables().GetNextPersistentVariableName(); + } return m_struct_vars->m_result_name; } @@ -132,18 +138,21 @@ ClangExpressionDeclMap::AddPersistentVariable parser_type.GetOpaqueQualType()), context); - if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (name, user_type)) + if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (name, + user_type, + m_parser_vars->m_exe_ctx->process->GetByteOrder(), + m_parser_vars->m_exe_ctx->process->GetAddressByteSize())) return false; - ClangExpressionVariable *var = m_parser_vars->m_persistent_vars->GetVariable(name); + ClangExpressionVariableSP var_sp (m_parser_vars->m_persistent_vars->GetVariable(name)); - if (!var) + if (!var_sp) return false; - var->EnableParserVars(); + var_sp->EnableParserVars(); - var->m_parser_vars->m_named_decl = decl; - var->m_parser_vars->m_parser_type = parser_type; + var_sp->m_parser_vars->m_named_decl = decl; + var_sp->m_parser_vars->m_parser_type = parser_type; return true; } @@ -168,29 +177,29 @@ ClangExpressionDeclMap::AddValueToStruct if (m_struct_members.GetVariable(decl)) return true; - ClangExpressionVariable *var = m_found_entities.GetVariable(decl); + ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl)); - if (!var) - var = m_parser_vars->m_persistent_vars->GetVariable(decl); + if (!var_sp) + var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl); - if (!var) + if (!var_sp) return false; if (log) log->Printf("Adding value for decl %p [%s - %s] to the structure", decl, name.GetCString(), - var->m_name.GetCString()); + var_sp->GetName().GetCString()); // We know entity->m_parser_vars is valid because we used a parser variable // to find it - var->m_parser_vars->m_llvm_value = value; + var_sp->m_parser_vars->m_llvm_value = value; - var->EnableJITVars(); - var->m_jit_vars->m_alignment = alignment; - var->m_jit_vars->m_size = size; + var_sp->EnableJITVars(); + var_sp->m_jit_vars->m_alignment = alignment; + var_sp->m_jit_vars->m_size = size; - m_struct_members.AddVariable(*var); + m_struct_members.AddVariable(var_sp); return true; } @@ -208,23 +217,25 @@ ClangExpressionDeclMap::DoStructLayout () m_struct_vars->m_struct_alignment = 0; m_struct_vars->m_struct_size = 0; - for (uint64_t member_index = 0, num_members = m_struct_members.Size(); + for (size_t member_index = 0, num_members = m_struct_members.GetSize(); member_index < num_members; ++member_index) { - ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index)); - - if (!member.m_jit_vars.get()) + ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index)); + if (!member_sp) + return false; + + if (!member_sp->m_jit_vars.get()) return false; if (member_index == 0) - m_struct_vars->m_struct_alignment = member.m_jit_vars->m_alignment; + m_struct_vars->m_struct_alignment = member_sp->m_jit_vars->m_alignment; - if (cursor % member.m_jit_vars->m_alignment) - cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment)); + if (cursor % member_sp->m_jit_vars->m_alignment) + cursor += (member_sp->m_jit_vars->m_alignment - (cursor % member_sp->m_jit_vars->m_alignment)); - member.m_jit_vars->m_offset = cursor; - cursor += member.m_jit_vars->m_size; + member_sp->m_jit_vars->m_offset = cursor; + cursor += member_sp->m_jit_vars->m_size; } m_struct_vars->m_struct_size = cursor; @@ -245,7 +256,7 @@ bool ClangExpressionDeclMap::GetStructInfo if (!m_struct_vars->m_struct_laid_out) return false; - num_elements = m_struct_members.Size(); + num_elements = m_struct_members.GetSize(); size = m_struct_vars->m_struct_size; alignment = m_struct_vars->m_struct_alignment; @@ -267,19 +278,20 @@ ClangExpressionDeclMap::GetStructElement if (!m_struct_vars->m_struct_laid_out) return false; - if (index >= m_struct_members.Size()) + if (index >= m_struct_members.GetSize()) return false; - ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index)); + ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index)); - if (!member.m_parser_vars.get() || - !member.m_jit_vars.get()) + if (!member_sp || + !member_sp->m_parser_vars.get() || + !member_sp->m_jit_vars.get()) return false; - decl = member.m_parser_vars->m_named_decl; - value = member.m_parser_vars->m_llvm_value; - offset = member.m_jit_vars->m_offset; - name = member.m_name; + decl = member_sp->m_parser_vars->m_named_decl; + value = member_sp->m_parser_vars->m_llvm_value; + offset = member_sp->m_jit_vars->m_offset; + name = member_sp->GetName(); return true; } @@ -292,16 +304,16 @@ ClangExpressionDeclMap::GetFunctionInfo uint64_t &ptr ) { - ClangExpressionVariable *entity = m_found_entities.GetVariable(decl); + ClangExpressionVariableSP entity_sp(m_found_entities.GetVariable(decl)); - if (!entity) + if (!entity_sp) return false; // We know m_parser_vars is valid since we searched for the variable by // its NamedDecl - value = &entity->m_parser_vars->m_llvm_value; - ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong(); + value = &entity_sp->m_parser_vars->m_llvm_value; + ptr = entity_sp->m_parser_vars->m_lldb_value->GetScalar().ULongLong(); return true; } @@ -453,11 +465,11 @@ bool ClangExpressionDeclMap::Dematerialize ( ExecutionContext &exe_ctx, - ClangExpressionVariable *&result, + ClangExpressionVariableSP &result_sp, Error &err ) { - return DoMaterialize(true, exe_ctx, &result, err); + return DoMaterialize(true, exe_ctx, &result_sp, err); DidDematerialize(); } @@ -527,26 +539,29 @@ ClangExpressionDeclMap::DumpMaterializedStruct DataExtractor extractor(data, exe_ctx.process->GetByteOrder(), exe_ctx.target->GetArchitecture().GetAddressByteSize()); - for (uint64_t member_index = 0, num_members = m_struct_members.Size(); - member_index < num_members; - ++member_index) + for (size_t member_idx = 0, num_members = m_struct_members.GetSize(); + member_idx < num_members; + ++member_idx) { - ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index)); + ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_idx)); - s.Printf("[%s]\n", member.m_name.GetCString()); + if (!member_sp) + return false; + + s.Printf("[%s]\n", member_sp->GetName().GetCString()); - if (!member.m_jit_vars.get()) + if (!member_sp->m_jit_vars.get()) return false; - extractor.Dump(&s, // stream - member.m_jit_vars->m_offset, // offset - lldb::eFormatBytesWithASCII, // format - 1, // byte size of individual entries - member.m_jit_vars->m_size, // number of entries - 16, // entries per line - m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, // address to print - 0, // bit size (bitfields only; 0 means ignore) - 0); // bit alignment (bitfields only; 0 means ignore) + extractor.Dump (&s, // stream + member_sp->m_jit_vars->m_offset, // offset + lldb::eFormatBytesWithASCII, // format + 1, // byte size of individual entries + member_sp->m_jit_vars->m_size, // number of entries + 16, // entries per line + m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, // address to print + 0, // bit size (bitfields only; 0 means ignore) + 0); // bit alignment (bitfields only; 0 means ignore) s.PutChar('\n'); } @@ -559,10 +574,13 @@ ClangExpressionDeclMap::DoMaterialize ( bool dematerialize, ExecutionContext &exe_ctx, - ClangExpressionVariable **result, + lldb::ClangExpressionVariableSP *result_sp_ptr, Error &err ) { + if (result_sp_ptr) + result_sp_ptr->reset(); + assert (m_struct_vars.get()); lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -579,7 +597,7 @@ ClangExpressionDeclMap::DoMaterialize return LLDB_INVALID_ADDRESS; } - ClangPersistentVariables &persistent_vars = exe_ctx.process->GetPersistentVariables(); + ClangPersistentVariables &persistent_vars = exe_ctx.target->GetPersistentVariables(); if (!m_struct_vars->m_struct_size) { @@ -619,26 +637,20 @@ ClangExpressionDeclMap::DoMaterialize if (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment) m_material_vars->m_materialized_location += (m_struct_vars->m_struct_alignment - (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment)); - for (uint64_t member_index = 0, num_members = m_struct_members.Size(); + for (uint64_t member_index = 0, num_members = m_struct_members.GetSize(); member_index < num_members; ++member_index) { - ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index)); - - ClangExpressionVariable *entity = NULL; + ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index)); - /* - if (member.m_parser_vars.get()) - entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl); - */ - - entity = m_found_entities.GetVariable(member.m_name); + ClangExpressionVariableSP entity_sp (m_found_entities.GetVariable(member_sp->GetName())); - ClangExpressionVariable *persistent_variable = persistent_vars.GetVariable(member.m_name); + ClangExpressionVariableSP persistent_var_sp (persistent_vars.GetVariable(member_sp->GetName())); - if (entity) + if (entity_sp) { - if (entity->m_register_info) + RegisterInfo *reg_info = entity_sp->GetRegisterInfo (); + if (reg_info) { // This is a register variable @@ -647,21 +659,32 @@ ClangExpressionDeclMap::DoMaterialize if (!reg_ctx) return false; - if (!DoMaterializeOneRegister(dematerialize, exe_ctx, *reg_ctx, *entity->m_register_info, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err)) + if (!DoMaterializeOneRegister (dematerialize, + exe_ctx, + *reg_ctx, + *reg_info, + m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, + err)) return false; } else { - if (!member.m_jit_vars.get()) + if (!member_sp->m_jit_vars.get()) return false; - if (!DoMaterializeOneVariable(dematerialize, exe_ctx, sym_ctx, member.m_name, member.m_user_type, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err)) + if (!DoMaterializeOneVariable (dematerialize, + exe_ctx, + sym_ctx, + member_sp->GetName(), + member_sp->GetTypeFromUser(), + m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, + err)) return false; } } - else if (persistent_variable) + else if (persistent_var_sp) { - if (member.m_name == m_struct_vars->m_result_name) + if (member_sp->GetName() == m_struct_vars->m_result_name) { if (!dematerialize) continue; @@ -669,18 +692,23 @@ ClangExpressionDeclMap::DoMaterialize if (log) log->PutCString("Found result member in the struct"); - *result = &member; + if (result_sp_ptr) + *result_sp_ptr = member_sp; } if (log) - log->Printf("Searched for persistent variable %s and found %s", member.m_name.GetCString(), persistent_variable->m_name.GetCString()); + log->Printf("Searched for persistent variable %s and found %s", member_sp->GetName().GetCString(), persistent_var_sp->GetName().GetCString()); - if (!DoMaterializeOnePersistentVariable(dematerialize, exe_ctx, persistent_variable->m_name, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err)) + if (!DoMaterializeOnePersistentVariable (dematerialize, + exe_ctx, + persistent_var_sp, + m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, + err)) return false; } else { - err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.GetCString()); + err.SetErrorStringWithFormat("Unexpected variable %s", member_sp->GetName().GetCString()); return false; } } @@ -693,32 +721,29 @@ ClangExpressionDeclMap::DoMaterializeOnePersistentVariable ( bool dematerialize, ExecutionContext &exe_ctx, - const ConstString &name, + ClangExpressionVariableSP &var_sp, lldb::addr_t addr, Error &err ) { - ClangPersistentVariables &persistent_vars = exe_ctx.process->GetPersistentVariables(); - - ClangExpressionVariable *pvar(persistent_vars.GetVariable(name)); - - if (!pvar) + if (!var_sp) { - err.SetErrorStringWithFormat("Undefined persistent variable %s", name.GetCString()); + err.SetErrorString("Invalid persistent variable"); return LLDB_INVALID_ADDRESS; } - size_t pvar_size = pvar->Size(); + const size_t pvar_byte_size = var_sp->GetByteSize(); - if (!pvar->m_data_sp.get()) + uint8_t *pvar_data = var_sp->GetValueBytes(); + if (pvar_data == NULL) return false; - uint8_t *pvar_data = pvar->m_data_sp->GetBytes(); Error error; if (dematerialize) { - if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size) + var_sp->ValueUpdated (); + if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_byte_size, error) != pvar_byte_size) { err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString()); return false; @@ -726,7 +751,7 @@ ClangExpressionDeclMap::DoMaterializeOnePersistentVariable } else { - if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size) + if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_byte_size, error) != pvar_byte_size) { err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString()); return false; @@ -1201,11 +1226,7 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString { clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl); if (clang_namespace_decl) - { - // TODO: is this how we get the decl lookups to be called for - // this namespace?? clang_namespace_decl->setHasExternalLexicalStorage(); - } } } } @@ -1312,12 +1333,12 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString return; } - - ClangExpressionVariable *pvar(m_parser_vars->m_persistent_vars->GetVariable(name)); + + ClangExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariable(name)); - if (pvar) + if (pvar_sp) { - AddOneVariable(context, pvar); + AddOneVariable(context, pvar_sp); return; } @@ -1493,17 +1514,18 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, return; NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType()); - - ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable())); std::string decl_name(context.m_decl_name.getAsString()); - entity.m_name.SetCString (decl_name.c_str()); - entity.m_user_type = ut; - - entity.EnableParserVars(); - entity.m_parser_vars->m_parser_type = pt; - entity.m_parser_vars->m_named_decl = var_decl; - entity.m_parser_vars->m_llvm_value = NULL; - entity.m_parser_vars->m_lldb_value = var_location; + ConstString entity_name(decl_name.c_str()); + ClangExpressionVariableSP entity(m_found_entities.CreateVariable (entity_name, + ut, + m_parser_vars->m_exe_ctx->process->GetByteOrder(), + m_parser_vars->m_exe_ctx->process->GetAddressByteSize())); + assert (entity.get()); + entity->EnableParserVars(); + entity->m_parser_vars->m_parser_type = pt; + entity->m_parser_vars->m_named_decl = var_decl; + entity->m_parser_vars->m_llvm_value = NULL; + entity->m_parser_vars->m_lldb_value = var_location; if (log) { @@ -1518,24 +1540,24 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, - ClangExpressionVariable *pvar) + ClangExpressionVariableSP &pvar_sp) { lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - TypeFromUser user_type = pvar->m_user_type; + TypeFromUser user_type (pvar_sp->GetTypeFromUser()); - TypeFromParser parser_type(GuardedCopyType(context.GetASTContext(), - user_type.GetASTContext(), - user_type.GetOpaqueQualType()), - context.GetASTContext()); + TypeFromParser parser_type (GuardedCopyType(context.GetASTContext(), + user_type.GetASTContext(), + user_type.GetOpaqueQualType()), + context.GetASTContext()); NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType()); - pvar->EnableParserVars(); - pvar->m_parser_vars->m_parser_type = parser_type; - pvar->m_parser_vars->m_named_decl = var_decl; - pvar->m_parser_vars->m_llvm_value = NULL; - pvar->m_parser_vars->m_lldb_value = NULL; + pvar_sp->EnableParserVars(); + pvar_sp->m_parser_vars->m_parser_type = parser_type; + pvar_sp->m_parser_vars->m_named_decl = var_decl; + pvar_sp->m_parser_vars->m_llvm_value = NULL; + pvar_sp->m_parser_vars->m_lldb_value = NULL; if (log) { @@ -1544,13 +1566,13 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, var_decl->print(var_decl_print_stream); var_decl_print_stream.flush(); - log->Printf("Added pvar %s, returned %s", pvar->m_name.GetCString(), var_decl_print_string.c_str()); + log->Printf("Added pvar %s, returned %s", pvar_sp->GetName().GetCString(), var_decl_print_string.c_str()); } } void -ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, - const RegisterInfo *reg_info) +ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context, + const RegisterInfo *reg_info) { lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -1564,21 +1586,22 @@ ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, return; } - TypeFromParser parser_type(ast_type, - context.GetASTContext()); + TypeFromParser parser_type (ast_type, + context.GetASTContext()); NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType()); - ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable())); + ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->process->GetByteOrder(), + m_parser_vars->m_exe_ctx->process->GetAddressByteSize())); + assert (entity.get()); std::string decl_name(context.m_decl_name.getAsString()); - entity.m_name.SetCString (decl_name.c_str()); - entity.m_register_info = reg_info; - - entity.EnableParserVars(); - entity.m_parser_vars->m_parser_type = parser_type; - entity.m_parser_vars->m_named_decl = var_decl; - entity.m_parser_vars->m_llvm_value = NULL; - entity.m_parser_vars->m_lldb_value = NULL; + entity->SetName (ConstString (decl_name.c_str())); + entity->SetRegisterInfo (reg_info); + entity->EnableParserVars(); + entity->m_parser_vars->m_parser_type = parser_type; + entity->m_parser_vars->m_named_decl = var_decl; + entity->m_parser_vars->m_llvm_value = NULL; + entity->m_parser_vars->m_lldb_value = NULL; if (log) { @@ -1666,15 +1689,18 @@ ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, fun_location->SetValueType(Value::eValueTypeLoadAddress); fun_location->GetScalar() = load_addr; - ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable())); + ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->process->GetByteOrder(), + m_parser_vars->m_exe_ctx->process->GetAddressByteSize())); + assert (entity.get()); std::string decl_name(context.m_decl_name.getAsString()); - entity.m_name.SetCString(decl_name.c_str()); - entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);; - - entity.EnableParserVars(); - entity.m_parser_vars->m_named_decl = fun_decl; - entity.m_parser_vars->m_llvm_value = NULL; - entity.m_parser_vars->m_lldb_value = fun_location.release(); + entity->SetName(ConstString(decl_name.c_str())); + entity->SetClangType (fun_opaque_type); + entity->SetClangAST (fun_ast_context); + + entity->EnableParserVars(); + entity->m_parser_vars->m_named_decl = fun_decl; + entity->m_parser_vars->m_llvm_value = NULL; + entity->m_parser_vars->m_lldb_value = fun_location.release(); if (log) { diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp index be7a4e9d309..80ce515ea75 100644 --- a/lldb/source/Expression/ClangExpressionParser.cpp +++ b/lldb/source/Expression/ClangExpressionParser.cpp @@ -367,7 +367,7 @@ ClangExpressionParser::MakeDWARF () return err; } - ClangExpressionVariableStore *local_variables = m_expr.LocalVariables(); + ClangExpressionVariableList *local_variables = m_expr.LocalVariables(); ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); if (!local_variables) diff --git a/lldb/source/Expression/ClangExpressionVariable.cpp b/lldb/source/Expression/ClangExpressionVariable.cpp index a85bc249879..79a7e4f2fb9 100644 --- a/lldb/source/Expression/ClangExpressionVariable.cpp +++ b/lldb/source/Expression/ClangExpressionVariable.cpp @@ -25,116 +25,109 @@ using namespace lldb_private; using namespace clang; -ClangExpressionVariable::ClangExpressionVariable() : - m_name(), - m_user_type (TypeFromUser(NULL, NULL)), - m_store (NULL), - m_register_info (NULL), - m_index (0), +ClangExpressionVariable::ClangExpressionVariable(lldb::ByteOrder byte_order, uint32_t addr_byte_size) : m_parser_vars(), m_jit_vars (), - m_data_sp () + m_valojb_sp (new ValueObjectConstResult(byte_order, addr_byte_size)) { } -void -ClangExpressionVariable::DisableDataVars() +ClangExpressionVariable::ClangExpressionVariable (const lldb::ValueObjectSP &valobj_sp) : + m_parser_vars(), + m_jit_vars (), + m_valojb_sp (valobj_sp) { - m_data_sp.reset(); } +//---------------------------------------------------------------------- +/// Return the variable's size in bytes +//---------------------------------------------------------------------- +size_t +ClangExpressionVariable::GetByteSize () +{ + return m_valojb_sp->GetByteSize(); +} -ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &rhs) : - m_name(rhs.m_name), - m_user_type(rhs.m_user_type), - m_store(rhs.m_store), - m_register_info(rhs.m_register_info), - m_index(rhs.m_index) +const ConstString & +ClangExpressionVariable::GetName () { - if (rhs.m_parser_vars.get()) - { - // TODO: Sean, can m_parser_vars be a shared pointer??? We are copy - // constructing it here. That is ok if we need to, but do we really - // need to? - m_parser_vars.reset(new struct ParserVars); - *m_parser_vars.get() = *rhs.m_parser_vars.get(); - } - - if (rhs.m_jit_vars.get()) - { - // TODO: Sean, can m_jit_vars be a shared pointer??? We are copy - // constructing it here. That is ok if we need to, but do we really - // need to? - m_jit_vars.reset(new struct JITVars); - *m_jit_vars.get() = *rhs.m_jit_vars.get(); - } - - if (rhs.m_data_sp) - { - // TODO: Sean, does m_data_sp need to be copy constructed? Or can it - // shared the data? - - m_data_sp.reset(new DataBufferHeap (rhs.m_data_sp->GetBytes(), - rhs.m_data_sp->GetByteSize())); - } + return m_valojb_sp->GetName(); +} + +lldb::ValueObjectSP +ClangExpressionVariable::GetValueObject() +{ + return m_valojb_sp; } -bool -ClangExpressionVariable::PointValueAtData(Value &value, ExecutionContext *exe_ctx) +lldb::RegisterInfo * +ClangExpressionVariable::GetRegisterInfo() { - if (m_data_sp.get() == NULL) - return false; - - value.SetContext(Value::eContextTypeClangType, m_user_type.GetOpaqueQualType()); - value.SetValueType(Value::eValueTypeHostAddress); - value.GetScalar() = (uintptr_t)m_data_sp->GetBytes(); - clang::ASTContext *ast_context = m_user_type.GetASTContext(); - - if (exe_ctx) - value.ResolveValue (exe_ctx, ast_context); - - return true; + return m_valojb_sp->GetValue().GetRegisterInfo(); } -void -ClangExpressionVariable::EnableDataVars() +void +ClangExpressionVariable::SetRegisterInfo (const lldb::RegisterInfo *reg_info) { - if (!m_data_sp.get()) - m_data_sp.reset(new DataBufferHeap); + return m_valojb_sp->GetValue().SetContext (Value::eContextTypeRegisterInfo, const_cast<lldb::RegisterInfo *>(reg_info)); } -lldb::ValueObjectSP -ClangExpressionVariable::GetExpressionResult (ExecutionContext *exe_ctx) +lldb::clang_type_t +ClangExpressionVariable::GetClangType() +{ + return m_valojb_sp->GetClangType(); +} + +void +ClangExpressionVariable::SetClangType(lldb::clang_type_t clang_type) +{ + m_valojb_sp->GetValue().SetContext(Value::eContextTypeClangType, clang_type); +} + +clang::ASTContext * +ClangExpressionVariable::GetClangAST() +{ + return m_valojb_sp->GetClangAST(); +} + +void +ClangExpressionVariable::SetClangAST (clang::ASTContext *ast) +{ + m_valojb_sp->SetClangAST (ast); +} + +TypeFromUser +ClangExpressionVariable::GetTypeFromUser() +{ + TypeFromUser tfu (m_valojb_sp->GetClangType(), m_valojb_sp->GetClangAST()); + return tfu; +} + +uint8_t * +ClangExpressionVariable::GetValueBytes() { - lldb::ValueObjectSP result_sp; - if (m_data_sp) + const size_t byte_size = m_valojb_sp->GetByteSize(); + if (byte_size > 0) { - Target * target = NULL; - Process *process = NULL; - if (exe_ctx) + if (m_valojb_sp->GetDataExtractor().GetByteSize() < byte_size) { - target = exe_ctx->target; - process = exe_ctx->process; - } - - Value value; - if (PointValueAtData(value, exe_ctx)) - { - lldb::ByteOrder byte_order = lldb::eByteOrderHost; - uint32_t addr_byte_size = 4; - if (process) - { - byte_order = process->GetByteOrder(); - addr_byte_size = process->GetAddressByteSize(); - } - result_sp.reset (new ValueObjectConstResult (m_user_type.GetASTContext(), - m_user_type.GetOpaqueQualType(), - m_name, - m_data_sp,// TODO: sean can you get this to be valid? - byte_order, - addr_byte_size)); + m_valojb_sp->GetValue().ResizeData(byte_size); + m_valojb_sp->GetValue().GetData (m_valojb_sp->GetDataExtractor()); } + return const_cast<uint8_t *>(m_valojb_sp->GetDataExtractor().GetDataStart()); } - return result_sp; + return NULL; +} + +void +ClangExpressionVariable::SetName (const ConstString &name) +{ + m_valojb_sp->SetName (name); +} + +void +ClangExpressionVariable::ValueUpdated () +{ + m_valojb_sp->ValueUpdated (); } diff --git a/lldb/source/Expression/ClangFunction.cpp b/lldb/source/Expression/ClangFunction.cpp index 3eac429f5c7..e55238d0904 100644 --- a/lldb/source/Expression/ClangFunction.cpp +++ b/lldb/source/Expression/ClangFunction.cpp @@ -275,7 +275,7 @@ ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, Error error; using namespace clang; - Process::ExecutionResults return_value = Process::eExecutionSetupError; + lldb::ExecutionResults return_value = lldb::eExecutionSetupError; Process *process = exe_ctx.process; @@ -441,13 +441,13 @@ ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_ exe_ctx.process->DeallocateMemory(args_addr); } -Process::ExecutionResults +lldb::ExecutionResults ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results) { return ExecuteFunction (exe_ctx, errors, 1000, true, results); } -Process::ExecutionResults +lldb::ExecutionResults ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results) { const bool try_all_threads = false; @@ -455,7 +455,7 @@ ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool s return ExecuteFunction (exe_ctx, NULL, errors, stop_others, NULL, try_all_threads, discard_on_error, results); } -Process::ExecutionResults +lldb::ExecutionResults ClangFunction::ExecuteFunction( ExecutionContext &exe_ctx, Stream &errors, @@ -470,7 +470,7 @@ ClangFunction::ExecuteFunction( } // This is the static function -Process::ExecutionResults +lldb::ExecutionResults ClangFunction::ExecuteFunction ( ExecutionContext &exe_ctx, lldb::addr_t function_address, @@ -486,7 +486,7 @@ ClangFunction::ExecuteFunction ( errors, stop_others, discard_on_error, this_arg)); if (call_plan_sp == NULL) - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; call_plan_sp->SetPrivate(true); @@ -494,7 +494,7 @@ ClangFunction::ExecuteFunction ( single_thread_timeout_usec, errors); } -Process::ExecutionResults +lldb::ExecutionResults ClangFunction::ExecuteFunction( ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, @@ -506,7 +506,7 @@ ClangFunction::ExecuteFunction( Value &results) { using namespace clang; - Process::ExecutionResults return_value = Process::eExecutionSetupError; + lldb::ExecutionResults return_value = lldb::eExecutionSetupError; lldb::addr_t args_addr; @@ -516,12 +516,12 @@ ClangFunction::ExecuteFunction( args_addr = LLDB_INVALID_ADDRESS; if (CompileFunction(errors) != 0) - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; if (args_addr == LLDB_INVALID_ADDRESS) { if (!InsertFunction(exe_ctx, args_addr, errors)) - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; } return_value = ClangFunction::ExecuteFunction(exe_ctx, m_wrapper_function_addr, args_addr, stop_others, @@ -530,7 +530,7 @@ ClangFunction::ExecuteFunction( if (args_addr_ptr != NULL) *args_addr_ptr = args_addr; - if (return_value != Process::eExecutionCompleted) + if (return_value != lldb::eExecutionCompleted) return return_value; FetchFunctionResults(exe_ctx, args_addr, results); @@ -538,7 +538,7 @@ ClangFunction::ExecuteFunction( if (args_addr_ptr == NULL) DeallocateFunctionResults(exe_ctx, args_addr); - return Process::eExecutionCompleted; + return lldb::eExecutionCompleted; } clang::ASTConsumer * diff --git a/lldb/source/Expression/ClangPersistentVariables.cpp b/lldb/source/Expression/ClangPersistentVariables.cpp index 4919922a401..5e61524f924 100644 --- a/lldb/source/Expression/ClangPersistentVariables.cpp +++ b/lldb/source/Expression/ClangPersistentVariables.cpp @@ -13,38 +13,39 @@ #include "lldb/Core/StreamString.h" #include "lldb/Core/Value.h" +using namespace lldb; using namespace lldb_private; ClangPersistentVariables::ClangPersistentVariables () : - ClangExpressionVariableStore() + ClangExpressionVariableList(), + m_next_persistent_variable_id (0) { - m_result_counter = 0; } -void -ClangPersistentVariables::GetNextResultName (ConstString &name) +ClangExpressionVariableSP +ClangPersistentVariables::CreatePersistentVariable (const lldb::ValueObjectSP &valobj_sp) { - char result_name[256]; - ::snprintf (result_name, sizeof(result_name), "$%llu", m_result_counter++); - name.SetCString(result_name); + ClangExpressionVariableSP var_sp (CreateVariable(valobj_sp)); + return var_sp; } -bool -ClangPersistentVariables::CreatePersistentVariable (const ConstString &name, - TypeFromUser user_type) +ClangExpressionVariableSP +ClangPersistentVariables::CreatePersistentVariable (const ConstString &name, const TypeFromUser& user_type, lldb::ByteOrder byte_order, uint32_t addr_byte_size) { - if (GetVariable(name)) - return false; - - ClangExpressionVariable &pvar (VariableAtIndex(CreateVariable())); - - pvar.m_name = name; - pvar.m_user_type = user_type; - // TODO: Sean, why do we need to call this?, we can just make it below - // and we aren't checking the result or anything... Is this cruft left - // over from an old code re-org? - //pvar.EnableDataVars(); - pvar.m_data_sp.reset(new DataBufferHeap(pvar.Size(), 0)); + ClangExpressionVariableSP var_sp (GetVariable(name)); - return true; -}
\ No newline at end of file + if (!var_sp) + var_sp = CreateVariable(name, user_type, byte_order, addr_byte_size); + + return var_sp; +} + + +ConstString +ClangPersistentVariables::GetNextPersistentVariableName () +{ + char name_cstr[256]; + ::snprintf (name_cstr, sizeof(name_cstr), "$%u", m_next_persistent_variable_id++); + ConstString name(name_cstr); + return name; +} diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index aa51106bce2..278cee773c1 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -271,7 +271,7 @@ ClangUserExpression::Parse (Stream &error_stream, m_dwarf_opcodes->SetByteOrder (lldb::eByteOrderHost); m_dwarf_opcodes->GetFlags ().Set (Stream::eBinary); - m_local_variables.reset(new ClangExpressionVariableStore()); + m_local_variables.reset(new ClangExpressionVariableList()); Error dwarf_error = parser.MakeDWARF (); @@ -422,7 +422,7 @@ ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream, bool ClangUserExpression::FinalizeJITExecution (Stream &error_stream, ExecutionContext &exe_ctx, - ClangExpressionVariable *&result) + lldb::ClangExpressionVariableSP &result) { Error expr_error; @@ -454,12 +454,12 @@ ClangUserExpression::FinalizeJITExecution (Stream &error_stream, return true; } -Process::ExecutionResults +lldb::ExecutionResults ClangUserExpression::Execute (Stream &error_stream, ExecutionContext &exe_ctx, bool discard_on_error, ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me, - ClangExpressionVariable *&result) + lldb::ClangExpressionVariableSP &result) { lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -469,7 +469,7 @@ ClangUserExpression::Execute (Stream &error_stream, error_stream.Printf("We don't currently support executing DWARF expressions"); - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; } else if (m_jit_addr != LLDB_INVALID_ADDRESS) { @@ -479,7 +479,7 @@ ClangUserExpression::Execute (Stream &error_stream, lldb::addr_t cmd_ptr = NULL; if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr)) - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; const bool stop_others = true; const bool try_all_threads = true; @@ -495,7 +495,7 @@ ClangUserExpression::Execute (Stream &error_stream, shared_ptr_to_me)); if (call_plan_sp == NULL || !call_plan_sp->ValidatePlan (NULL)) - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; call_plan_sp->SetPrivate(true); @@ -504,14 +504,18 @@ ClangUserExpression::Execute (Stream &error_stream, if (log) log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --"); - Process::ExecutionResults execution_result = - exe_ctx.process->RunThreadPlan (exe_ctx, call_plan_sp, stop_others, try_all_threads, discard_on_error, - single_thread_timeout_usec, error_stream); + lldb::ExecutionResults execution_result = exe_ctx.process->RunThreadPlan (exe_ctx, + call_plan_sp, + stop_others, + try_all_threads, + discard_on_error, + single_thread_timeout_usec, + error_stream); if (log) log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --"); - if (execution_result == Process::eExecutionInterrupted) + if (execution_result == lldb::eExecutionInterrupted) { if (discard_on_error) error_stream.Printf ("Expression execution was interrupted. The process has been returned to the state before execution."); @@ -520,21 +524,21 @@ ClangUserExpression::Execute (Stream &error_stream, return execution_result; } - else if (execution_result != Process::eExecutionCompleted) + else if (execution_result != lldb::eExecutionCompleted) { 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)) - return Process::eExecutionCompleted; + return lldb::eExecutionCompleted; else - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; } else { error_stream.Printf("Expression can't be run; neither DWARF nor a JIT compiled function is present"); - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; } } @@ -547,7 +551,7 @@ ClangUserExpression::DwarfOpcodeStream () return *m_dwarf_opcodes.get(); } -Process::ExecutionResults +lldb::ExecutionResults ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, bool discard_on_error, const char *expr_cstr, @@ -557,14 +561,14 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); Error error; - Process::ExecutionResults execution_results = Process::eExecutionSetupError; + lldb::ExecutionResults execution_results = lldb::eExecutionSetupError; if (exe_ctx.process == NULL) { error.SetErrorString ("Must have a process to evaluate expressions."); result_valobj_sp.reset (new ValueObjectConstResult (error)); - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; } if (!exe_ctx.process->GetDynamicCheckers()) @@ -584,7 +588,7 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, error.SetErrorString (install_errors.GetString().c_str()); result_valobj_sp.reset (new ValueObjectConstResult (error)); - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; } exe_ctx.process->SetDynamicCheckers(dynamic_checkers); @@ -609,7 +613,7 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, } else { - ClangExpressionVariable *expr_result = NULL; + lldb::ClangExpressionVariableSP expr_result; error_stream.GetString().clear(); @@ -621,7 +625,7 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, discard_on_error, user_expression_sp, expr_result); - if (execution_results != Process::eExecutionCompleted) + if (execution_results != lldb::eExecutionCompleted) { if (log) log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally =="); @@ -633,14 +637,9 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, } else { - // TODO: seems weird to get a pointer to a result object back from - // a function. Do we own it? Feels like we do, but from looking at the - // code we don't. Might be best to make this a reference and state - // explicitly that we don't own it when we get a reference back from - // the execute? if (expr_result) { - result_valobj_sp = expr_result->GetExpressionResult (&exe_ctx); + result_valobj_sp = expr_result->GetValueObject(); if (log) log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString(exe_ctx.GetBestExecutionContextScope())); diff --git a/lldb/source/Expression/IRToDWARF.cpp b/lldb/source/Expression/IRToDWARF.cpp index b7baf90d89f..96016760dc6 100644 --- a/lldb/source/Expression/IRToDWARF.cpp +++ b/lldb/source/Expression/IRToDWARF.cpp @@ -26,7 +26,7 @@ using namespace llvm; static char ID; -IRToDWARF::IRToDWARF(lldb_private::ClangExpressionVariableStore &local_vars, +IRToDWARF::IRToDWARF(lldb_private::ClangExpressionVariableList &local_vars, lldb_private::ClangExpressionDeclMap *decl_map, lldb_private::StreamString &strm, const char *func_name) : diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index d913a797288..27fda80b5cd 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -642,9 +642,6 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos() } } - if (log) - log->PutCString("Unloaded:"); - for (old_idx = 0; old_idx < old_dyld_all_image_infos.size(); ++old_idx) { if (old_dyld_all_image_infos[old_idx].address != LLDB_INVALID_ADDRESS) @@ -662,7 +659,14 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos() } if (unloaded_module_list.GetSize() > 0) + { + if (log) + { + log->PutCString("Unloaded:"); + unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload"); + } m_process->GetTarget().ModulesDidUnload (unloaded_module_list); + } } else { @@ -752,6 +756,8 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos() } } } + if (log) + loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad"); m_process->GetTarget().ModulesDidLoad (loaded_module_list); } } diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index 6c8302dbd5a..804b388e68a 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -122,9 +122,15 @@ AppleObjCRuntime::GetObjectDescription (Stream &str, Value &value, ExecutionCont bool try_all_threads = true; bool stop_others = true; - Process::ExecutionResults results - = func.ExecuteFunction(exe_ctx, &wrapper_struct_addr, error_stream, stop_others, 1000000, try_all_threads, unwind_on_error, ret); - if (results != Process::eExecutionCompleted) + ExecutionResults results = func.ExecuteFunction (exe_ctx, + &wrapper_struct_addr, + error_stream, + stop_others, + 1000000, + try_all_threads, + unwind_on_error, + ret); + if (results != lldb::eExecutionCompleted) { str.Printf("Error evaluating Print Object function: %d.\n", results); return false; diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index c8ad302a309..cd725cac8aa 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -870,16 +870,17 @@ IsOperator (const char *name, OverloadedOperatorKind &op_kind) return false; #define OPERATOR_PREFIX "operator" +#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1) const char *post_op_name = NULL; bool no_space = true; - if (!::strncmp(name, OPERATOR_PREFIX, sizeof(OPERATOR_PREFIX) - 1)) - post_op_name = name + sizeof(OPERATOR_PREFIX) - 1; - else + if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH)) return false; + post_op_name = name + OPERATOR_PREFIX_LENGTH; + if (post_op_name[0] == ' ') { post_op_name++; @@ -887,6 +888,7 @@ IsOperator (const char *name, OverloadedOperatorKind &op_kind) } #undef OPERATOR_PREFIX +#undef OPERATOR_PREFIX_LENGTH // This is an operator, set the overloaded operator kind to invalid // in case this is a conversion operator... @@ -3488,7 +3490,13 @@ ClangASTContext::AddEnumerationValueToEnumerationType clang_type_t ClangASTContext::CreatePointerType (clang_type_t clang_type) { - if (clang_type) + return CreatePointerType (getASTContext(), clang_type); +} + +clang_type_t +ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type) +{ + if (ast && clang_type) { QualType qual_type (QualType::getFromOpaquePtr(clang_type)); @@ -3497,10 +3505,10 @@ ClangASTContext::CreatePointerType (clang_type_t clang_type) { case clang::Type::ObjCObject: case clang::Type::ObjCInterface: - return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); + return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); default: - return getASTContext()->getPointerType(qual_type).getAsOpaquePtr(); + return ast->getPointerType(qual_type).getAsOpaquePtr(); } } return NULL; diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index 609ec34c709..c144ff35f99 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -161,6 +161,7 @@ ClangASTType::GetEncoding (clang_type_t clang_type, uint32_t &count) case clang::BuiltinType::Double: case clang::BuiltinType::LongDouble: return lldb::eEncodingIEEE754; + case clang::BuiltinType::ObjCClass: case clang::BuiltinType::ObjCId: case clang::BuiltinType::ObjCSel: return lldb::eEncodingUint; diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index f91c6194ea5..c949555a4cf 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -88,7 +88,6 @@ Process::Process(Target &target, Listener &listener) : m_image_tokens (), m_listener (listener), m_breakpoint_site_list (), - m_persistent_vars (), m_dynamic_checkers_ap (), m_unix_signals (), m_target_triple (), @@ -2157,12 +2156,6 @@ Process::GetSP () return GetTarget().GetProcessSP(); } -ClangPersistentVariables & -Process::GetPersistentVariables() -{ - return m_persistent_vars; -} - uint32_t Process::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids) { @@ -2334,7 +2327,7 @@ Process::UpdateInstanceName () } } -Process::ExecutionResults +ExecutionResults Process::RunThreadPlan (ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp, bool stop_others, @@ -2375,7 +2368,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, { errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString()); exe_ctx.process->RestoreProcessEvents(); - return Process::eExecutionSetupError; + return lldb::eExecutionSetupError; } // We need to call the function synchronously, so spin waiting for it to return. @@ -2440,7 +2433,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, { if (log) log->Printf ("Even though we timed out, the call plan was done. Exiting wait loop."); - return_value = Process::eExecutionCompleted; + return_value = lldb::eExecutionCompleted; break; } @@ -2458,7 +2451,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, else { exe_ctx.process->RestoreProcessEvents (); - return Process::eExecutionInterrupted; + return lldb::eExecutionInterrupted; } } } @@ -2473,12 +2466,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, if (exe_ctx.thread->IsThreadPlanDone (thread_plan_sp.get())) { - return_value = Process::eExecutionCompleted; + return_value = lldb::eExecutionCompleted; break; } else if (exe_ctx.thread->WasThreadPlanDiscarded (thread_plan_sp.get())) { - return_value = Process::eExecutionDiscarded; + return_value = lldb::eExecutionDiscarded; break; } else @@ -2557,7 +2550,7 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, { exe_ctx.thread->DiscardThreadPlansUpToPlan (thread_plan_sp); } - return_value = Process::eExecutionInterrupted; + return_value = lldb::eExecutionInterrupted; break; } } @@ -2593,19 +2586,19 @@ Process::ExecutionResultAsCString (ExecutionResults result) switch (result) { - case Process::eExecutionCompleted: + case lldb::eExecutionCompleted: result_name = "eExecutionCompleted"; break; - case Process::eExecutionDiscarded: + case lldb::eExecutionDiscarded: result_name = "eExecutionDiscarded"; break; - case Process::eExecutionInterrupted: + case lldb::eExecutionInterrupted: result_name = "eExecutionInterrupted"; break; - case Process::eExecutionSetupError: + case lldb::eExecutionSetupError: result_name = "eExecutionSetupError"; break; - case Process::eExecutionTimedOut: + case lldb::eExecutionTimedOut: result_name = "eExecutionTimedOut"; break; } diff --git a/lldb/source/Target/SectionLoadList.cpp b/lldb/source/Target/SectionLoadList.cpp index 0dcbba42fcb..f900d9697d5 100644 --- a/lldb/source/Target/SectionLoadList.cpp +++ b/lldb/source/Target/SectionLoadList.cpp @@ -68,12 +68,17 @@ SectionLoadList::SetSectionLoadAddress (const Section *section, addr_t load_addr LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE)); if (log) - log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16llx)", + { + const FileSpec &module_file_spec (section->GetModule()->GetFileSpec()); + log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s), load_addr = 0x%16.16llx)", __FUNCTION__, section, - section->GetModule()->GetFileSpec().GetFilename().AsCString(), + module_file_spec.GetDirectory().AsCString(), + module_file_spec.GetDirectory() ? "/" : "", + module_file_spec.GetFilename().AsCString(), section->GetName().AsCString(), load_addr); + } Mutex::Locker locker(m_mutex); collection::iterator pos = m_collection.find(load_addr); @@ -97,11 +102,16 @@ SectionLoadList::SetSectionUnloaded (const Section *section) LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE)); if (log) - log->Printf ("SectionLoadList::%s (section = %p (%s.%s))", + { + const FileSpec &module_file_spec (section->GetModule()->GetFileSpec()); + log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s))", __FUNCTION__, section, - section->GetModule()->GetFileSpec().GetFilename().AsCString(), + module_file_spec.GetDirectory().AsCString(), + module_file_spec.GetDirectory() ? "/" : "", + module_file_spec.GetFilename().AsCString(), section->GetName().AsCString()); + } size_t unload_count = 0; Mutex::Locker locker(m_mutex); @@ -128,12 +138,17 @@ SectionLoadList::SetSectionUnloaded (const Section *section, addr_t load_addr) LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE)); if (log) - log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16llx)", + { + const FileSpec &module_file_spec (section->GetModule()->GetFileSpec()); + log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s), load_addr = 0x%16.16llx)", __FUNCTION__, section, - section->GetModule()->GetFileSpec().GetFilename().AsCString(), + module_file_spec.GetDirectory().AsCString(), + module_file_spec.GetDirectory() ? "/" : "", + module_file_spec.GetFilename().AsCString(), section->GetName().AsCString(), load_addr); + } Mutex::Locker locker(m_mutex); return m_collection.erase (load_addr) != 0; } diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 7281ba427e4..20946532188 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -478,6 +478,159 @@ StackFrame::GetVariableList (bool get_file_globals) return m_variable_list_sp.get(); } +ValueObjectSP +StackFrame::GetValueForVariableExpressionPath (const char *var_expr) +{ + bool deref = false; + bool address_of = false; + ValueObjectSP valobj_sp; + const bool get_file_globals = true; + VariableList *variable_list = GetVariableList (get_file_globals); + + if (variable_list) + { + // If first character is a '*', then show pointer contents + if (var_expr[0] == '*') + { + deref = true; + var_expr++; // Skip the '*' + } + else if (var_expr[0] == '&') + { + address_of = true; + var_expr++; // Skip the '&' + } + + std::string var_path (var_expr); + size_t separator_idx = var_path.find_first_of(".-["); + + ConstString name_const_string; + if (separator_idx == std::string::npos) + name_const_string.SetCString (var_path.c_str()); + else + name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx); + + VariableSP var_sp (variable_list->FindVariable(name_const_string)); + if (var_sp) + { + valobj_sp = GetValueObjectForFrameVariable (var_sp); + + var_path.erase (0, name_const_string.GetLength ()); + // We are dumping at least one child + while (separator_idx != std::string::npos) + { + // Calculate the next separator index ahead of time + ValueObjectSP child_valobj_sp; + const char separator_type = var_path[0]; + switch (separator_type) + { + + case '-': + if (var_path.size() >= 2 && var_path[1] != '>') + return ValueObjectSP(); + + var_path.erase (0, 1); // Remove the '-' + // Fall through + case '.': + { + // We either have a pointer type and need to verify + // valobj_sp is a pointer, or we have a member of a + // class/union/struct being accessed with the . syntax + // and need to verify we don't have a pointer. + const bool is_ptr = var_path[0] == '>'; + + if (valobj_sp->IsPointerType () != is_ptr) + { + // Incorrect use of "." with a pointer, or "->" with + // a class/union/struct instance or reference. + return ValueObjectSP(); + } + + var_path.erase (0, 1); // Remove the '.' or '>' + separator_idx = var_path.find_first_of(".-["); + ConstString child_name; + if (separator_idx == std::string::npos) + child_name.SetCString (var_path.c_str()); + else + child_name.SetCStringWithLength(var_path.c_str(), separator_idx); + + child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true); + if (!child_valobj_sp) + { + // No child member with name "child_name" + return ValueObjectSP(); + } + // Remove the child name from the path + var_path.erase(0, child_name.GetLength()); + } + break; + + case '[': + // Array member access, or treating pointer as an array + if (var_path.size() > 2) // Need at least two brackets and a number + { + char *end = NULL; + int32_t child_index = ::strtol (&var_path[1], &end, 0); + if (end && *end == ']') + { + + if (valobj_sp->IsPointerType ()) + { + child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true); + } + else + { + child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true); + } + + if (!child_valobj_sp) + { + // Invalid array index... + return ValueObjectSP(); + } + + // Erase the array member specification '[%i]' where + // %i is the array index + var_path.erase(0, (end - var_path.c_str()) + 1); + separator_idx = var_path.find_first_of(".-["); + + // Break out early from the switch since we were + // able to find the child member + break; + } + } + return ValueObjectSP(); + + default: + // Failure... + return ValueObjectSP(); + } + + if (child_valobj_sp) + valobj_sp = child_valobj_sp; + + if (var_path.empty()) + break; + + } + if (valobj_sp) + { + if (deref) + { + ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(this, NULL)); + valobj_sp = deref_valobj_sp; + } + else if (address_of) + { + ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf()); + valobj_sp = address_of_valobj_sp; + } + } + return valobj_sp; + } + } + return ValueObjectSP(); +} bool StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr) diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index c5dd46b6b68..8546537b9a1 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -18,15 +18,17 @@ #include "lldb/Breakpoint/BreakpointResolverFileLine.h" #include "lldb/Breakpoint/BreakpointResolverName.h" #include "lldb/Core/DataBufferMemoryMap.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Event.h" #include "lldb/Core/Log.h" -#include "lldb/Core/Timer.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/Timer.h" +#include "lldb/Core/ValueObject.h" #include "lldb/Host/Host.h" #include "lldb/lldb-private-log.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Process.h" -#include "lldb/Core/Debugger.h" +#include "lldb/Target/StackFrame.h" using namespace lldb; using namespace lldb_private; @@ -46,7 +48,8 @@ Target::Target(Debugger &debugger) : m_triple(), m_search_filter_sp(), m_image_search_paths (ImageSearchPathsChanged, this), - m_scratch_ast_context_ap(NULL) + m_scratch_ast_context_ap (NULL), + m_persistent_variables () { SetEventName (eBroadcastBitBreakpointChanged, "breakpoint-changed"); SetEventName (eBroadcastBitModulesLoaded, "modules-loaded"); @@ -866,6 +869,81 @@ Target::GetExpressionPrefixContentsAsCString () return m_expr_prefix_contents.c_str(); } +ExecutionResults +Target::EvaluateExpression +( + const char *expr_cstr, + StackFrame *frame, + bool unwind_on_error, + lldb::ValueObjectSP &result_valobj_sp +) +{ + ExecutionResults execution_results = eExecutionSetupError; + + result_valobj_sp.reset(); + + ExecutionContext exe_ctx; + if (frame) + { + frame->CalculateExecutionContext(exe_ctx); + result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr); + } + else if (m_process_sp) + { + m_process_sp->CalculateExecutionContext(exe_ctx); + } + else + { + CalculateExecutionContext(exe_ctx); + } + + if (result_valobj_sp) + { + execution_results = eExecutionCompleted; + // We got a result from the frame variable expression path above... + ConstString persistent_variable_name (m_persistent_variables.GetNextPersistentVariableName()); + + lldb::ValueObjectSP const_valobj_sp; + + // Check in case our value is already a constant value + if (result_valobj_sp->GetIsConstant()) + { + const_valobj_sp = result_valobj_sp; + const_valobj_sp->SetName (persistent_variable_name); + } + else + const_valobj_sp = result_valobj_sp->CreateConstantValue (exe_ctx.GetBestExecutionContextScope(), + persistent_variable_name); + + result_valobj_sp = const_valobj_sp; + + ClangExpressionVariableSP clang_expr_variable_sp(m_persistent_variables.CreatePersistentVariable(result_valobj_sp)); + assert (clang_expr_variable_sp.get()); + } + else + { + // Make sure we aren't just trying to see the value of a persistent + // variable (something like "$0") + lldb::ClangExpressionVariableSP persistent_var_sp (m_persistent_variables.GetVariable (expr_cstr)); + if (persistent_var_sp) + { + result_valobj_sp = persistent_var_sp->GetValueObject (); + execution_results = eExecutionCompleted; + } + else + { + const char *prefix = GetExpressionPrefixContentsAsCString(); + + execution_results = ClangUserExpression::Evaluate (exe_ctx, + unwind_on_error, + expr_cstr, + prefix, + result_valobj_sp); + } + } + return execution_results; +} + //-------------------------------------------------------------- // class Target::SettingsController //-------------------------------------------------------------- diff --git a/lldb/source/Target/ThreadPlanTestCondition.cpp b/lldb/source/Target/ThreadPlanTestCondition.cpp index b5f7db87f8d..b2c90db9577 100644 --- a/lldb/source/Target/ThreadPlanTestCondition.cpp +++ b/lldb/source/Target/ThreadPlanTestCondition.cpp @@ -76,11 +76,11 @@ ThreadPlanTestCondition::ShouldStop (Event *event_ptr) LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); if (m_thread.IsThreadPlanDone(m_expression_plan_sp.get())) { - ClangExpressionVariable *expr_result = NULL; + lldb::ClangExpressionVariableSP expr_result; StreamString error_stream; m_expression->FinalizeJITExecution(error_stream, m_exe_ctx, expr_result); - ValueObjectSP result_sp (expr_result->GetExpressionResult(&m_exe_ctx)); + ValueObjectSP result_sp (expr_result->GetValueObject()); if (result_sp) { // FIXME: This is not the right answer, we should have a "GetValueAsBoolean..." |