2010-06-09 00:52:24 +08:00
//===-- ValueObject.cpp -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
2012-12-05 08:20:57 +08:00
# include "lldb/lldb-python.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Core/ValueObject.h"
// C Includes
2010-09-15 07:36:40 +08:00
# include <stdlib.h>
2010-06-09 00:52:24 +08:00
// C++ Includes
// Other libraries and framework includes
# include "llvm/Support/raw_ostream.h"
2010-09-28 09:25:32 +08:00
# include "clang/AST/Type.h"
2010-06-09 00:52:24 +08:00
// Project includes
# include "lldb/Core/DataBufferHeap.h"
2011-06-30 06:27:15 +08:00
# include "lldb/Core/Debugger.h"
2011-07-30 03:53:35 +08:00
# include "lldb/Core/Log.h"
<rdar://problem/11757916>
Make breakpoint setting by file and line much more efficient by only looking for inlined breakpoint locations if we are setting a breakpoint in anything but a source implementation file. Implementing this complex for a many reasons. Turns out that parsing compile units lazily had some issues with respect to how we need to do things with DWARF in .o files. So the fixes in the checkin for this makes these changes:
- Add a new setting called "target.inline-breakpoint-strategy" which can be set to "never", "always", or "headers". "never" will never try and set any inlined breakpoints (fastest). "always" always looks for inlined breakpoint locations (slowest, but most accurate). "headers", which is the default setting, will only look for inlined breakpoint locations if the breakpoint is set in what are consudered to be header files, which is realy defined as "not in an implementation source file".
- modify the breakpoint setting by file and line to check the current "target.inline-breakpoint-strategy" setting and act accordingly
- Modify compile units to be able to get their language and other info lazily. This allows us to create compile units from the debug map and not have to fill all of the details in, and then lazily discover this information as we go on debuggging. This is needed to avoid parsing all .o files when setting breakpoints in implementation only files (no inlines). Otherwise we would need to parse the .o file, the object file (mach-o in our case) and the symbol file (DWARF in the object file) just to see what the compile unit was.
- modify the "SymbolFileDWARFDebugMap" to subclass lldb_private::Module so that the virtual "GetObjectFile()" and "GetSymbolVendor()" functions can be intercepted when the .o file contenst are later lazilly needed. Prior to this fix, when we first instantiated the "SymbolFileDWARFDebugMap" class, we would also make modules, object files and symbol files for every .o file in the debug map because we needed to fix up the sections in the .o files with information that is in the executable debug map. Now we lazily do this in the DebugMapModule::GetObjectFile()
Cleaned up header includes a bit as well.
llvm-svn: 162860
2012-08-30 05:13:06 +08:00
# include "lldb/Core/Module.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Core/StreamString.h"
2012-10-27 10:05:48 +08:00
# include "lldb/Core/ValueObjectCast.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Core/ValueObjectChild.h"
2010-12-14 10:59:59 +08:00
# include "lldb/Core/ValueObjectConstResult.h"
2011-04-16 08:01:13 +08:00
# include "lldb/Core/ValueObjectDynamicValue.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Core/ValueObjectList.h"
2011-05-06 07:32:56 +08:00
# include "lldb/Core/ValueObjectMemory.h"
2011-07-22 08:16:08 +08:00
# include "lldb/Core/ValueObjectSyntheticFilter.h"
2010-06-09 00:52:24 +08:00
2013-01-29 07:47:25 +08:00
# include "lldb/DataFormatters/DataVisualization.h"
2014-10-31 02:27:31 +08:00
# include "lldb/DataFormatters/StringPrinter.h"
<rdar://problem/14393032>
DumpValueObject() 2.0
This checkin restores pre-Xcode5 functionality to the "po" (expr -O) command:
- expr now has a new --description-verbosity (-v) argument, which takes either compact or full as a value (-v is the same as -vfull)
When the full mode is on, "po" will show the extended output with type name, persistent variable name and value, as in
(lldb) expr -O -v -- foo
(id) $0 = 0x000000010010baf0 {
1 = 2;
2 = 3;
}
When -v is omitted, or -vcompact is passed, the Xcode5-style output will be shown, as in
(lldb) expr -O -- foo
{
1 = 2;
2 = 3;
}
- for a non-ObjectiveC object, LLDB will still try to retrieve a summary and/or value to display
(lldb) po 5
5
-v also works in this mode
(lldb) expr -O -vfull -- 5
(int) $4 = 5
On top of that, this is a major refactoring of the ValueObject printing code. The functionality is now factored into a ValueObjectPrinter class for easier maintenance in the future
DumpValueObject() was turned into an instance method ValueObject::Dump() which simply calls through to the printer code, Dump_Impl has been removed
Test case to follow
llvm-svn: 191694
2013-10-01 03:11:51 +08:00
# include "lldb/DataFormatters/ValueObjectPrinter.h"
2013-01-29 07:47:25 +08:00
2014-12-09 07:13:56 +08:00
# include "lldb/Expression/ClangExpressionVariable.h"
# include "lldb/Expression/ClangPersistentVariables.h"
2011-02-01 09:31:41 +08:00
# include "lldb/Host/Endian.h"
2011-08-13 00:42:31 +08:00
# include "lldb/Interpreter/CommandInterpreter.h"
2011-07-15 10:26:42 +08:00
# include "lldb/Interpreter/ScriptInterpreterPython.h"
2010-07-22 06:12:05 +08:00
# include "lldb/Symbol/ClangASTType.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Symbol/ClangASTContext.h"
2014-11-07 05:23:20 +08:00
# include "lldb/Symbol/CompileUnit.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Symbol/Type.h"
2010-09-11 07:12:17 +08:00
# include "lldb/Target/ExecutionContext.h"
2010-09-28 09:25:32 +08:00
# include "lldb/Target/LanguageRuntime.h"
2011-08-03 01:27:39 +08:00
# include "lldb/Target/ObjCLanguageRuntime.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Target/Process.h"
# include "lldb/Target/RegisterContext.h"
2013-12-06 09:12:00 +08:00
# include "lldb/Target/SectionLoadList.h"
2010-09-15 07:36:40 +08:00
# include "lldb/Target/Target.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Target/Thread.h"
using namespace lldb ;
using namespace lldb_private ;
2011-07-13 06:56:10 +08:00
using namespace lldb_utility ;
2010-06-09 00:52:24 +08:00
2011-09-02 09:15:17 +08:00
static user_id_t g_value_obj_uid = 0 ;
2010-06-09 00:52:24 +08:00
//----------------------------------------------------------------------
// ValueObject constructor
//----------------------------------------------------------------------
2011-03-31 08:19:25 +08:00
ValueObject : : ValueObject ( ValueObject & parent ) :
2010-06-09 00:52:24 +08:00
UserID ( + + g_value_obj_uid ) , // Unique identifier for every value object
2011-03-31 08:19:25 +08:00
m_parent ( & parent ) ,
2013-04-12 06:48:58 +08:00
m_root ( NULL ) ,
2011-04-12 03:41:40 +08:00
m_update_point ( parent . GetUpdatePoint ( ) ) ,
2010-06-09 00:52:24 +08:00
m_name ( ) ,
m_data ( ) ,
m_value ( ) ,
m_error ( ) ,
2010-09-02 10:59:18 +08:00
m_value_str ( ) ,
m_old_value_str ( ) ,
m_location_str ( ) ,
m_summary_str ( ) ,
2010-09-11 07:12:17 +08:00
m_object_desc_str ( ) ,
2014-09-06 05:46:22 +08:00
m_validation_result ( ) ,
2011-04-23 07:53:53 +08:00
m_manager ( parent . GetManager ( ) ) ,
2010-09-02 10:59:18 +08:00
m_children ( ) ,
m_synthetic_children ( ) ,
2011-04-23 07:53:53 +08:00
m_dynamic_value ( NULL ) ,
2011-07-22 08:16:08 +08:00
m_synthetic_value ( NULL ) ,
2011-04-23 07:53:53 +08:00
m_deref_valobj ( NULL ) ,
2010-10-06 11:09:11 +08:00
m_format ( eFormatDefault ) ,
2013-06-01 03:18:19 +08:00
m_last_format ( eFormatDefault ) ,
2011-07-20 04:57:44 +08:00
m_last_format_mgr_revision ( 0 ) ,
2012-03-01 12:24:26 +08:00
m_type_summary_sp ( ) ,
m_type_format_sp ( ) ,
m_synthetic_children_sp ( ) ,
2014-09-06 05:46:22 +08:00
m_type_validator_sp ( ) ,
2011-08-09 10:12:22 +08:00
m_user_id_of_forced_summary ( ) ,
2011-11-01 06:50:49 +08:00
m_address_type_of_ptr_or_ref_children ( eAddressTypeInvalid ) ,
2014-12-10 05:18:59 +08:00
m_value_checksum ( ) ,
2015-01-21 09:47:13 +08:00
m_preferred_display_language ( lldb : : eLanguageTypeUnknown ) ,
2010-09-02 10:59:18 +08:00
m_value_is_valid ( false ) ,
m_value_did_change ( false ) ,
m_children_count_valid ( false ) ,
2010-12-14 10:59:59 +08:00
m_old_value_valid ( false ) ,
2011-06-30 06:27:15 +08:00
m_is_deref_of_parent ( false ) ,
2011-07-02 08:25:22 +08:00
m_is_array_item_for_pointer ( false ) ,
2011-07-06 10:13:41 +08:00
m_is_bitfield_for_scalar ( false ) ,
2011-07-30 03:53:35 +08:00
m_is_child_at_offset ( false ) ,
2012-02-23 07:57:45 +08:00
m_is_getting_summary ( false ) ,
2014-12-10 03:51:20 +08:00
m_did_calculate_complete_objc_class_type ( false ) ,
m_is_synthetic_children_generated ( parent . m_is_synthetic_children_generated )
2010-06-09 00:52:24 +08:00
{
2011-04-23 07:53:53 +08:00
m_manager - > ManageObject ( this ) ;
2010-06-09 00:52:24 +08:00
}
//----------------------------------------------------------------------
2011-03-31 08:19:25 +08:00
// ValueObject constructor
2010-06-09 00:52:24 +08:00
//----------------------------------------------------------------------
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
ValueObject : : ValueObject ( ExecutionContextScope * exe_scope ,
AddressType child_ptr_or_ref_addr_type ) :
2011-03-31 08:19:25 +08:00
UserID ( + + g_value_obj_uid ) , // Unique identifier for every value object
m_parent ( NULL ) ,
2013-04-12 06:48:58 +08:00
m_root ( NULL ) ,
2011-04-12 03:41:40 +08:00
m_update_point ( exe_scope ) ,
2011-03-31 08:19:25 +08:00
m_name ( ) ,
m_data ( ) ,
m_value ( ) ,
m_error ( ) ,
m_value_str ( ) ,
m_old_value_str ( ) ,
m_location_str ( ) ,
m_summary_str ( ) ,
m_object_desc_str ( ) ,
2014-09-06 05:46:22 +08:00
m_validation_result ( ) ,
2011-04-23 07:53:53 +08:00
m_manager ( ) ,
2011-03-31 08:19:25 +08:00
m_children ( ) ,
m_synthetic_children ( ) ,
2011-04-23 07:53:53 +08:00
m_dynamic_value ( NULL ) ,
2011-07-22 08:16:08 +08:00
m_synthetic_value ( NULL ) ,
2011-04-23 07:53:53 +08:00
m_deref_valobj ( NULL ) ,
2011-03-31 08:19:25 +08:00
m_format ( eFormatDefault ) ,
2013-06-01 03:18:19 +08:00
m_last_format ( eFormatDefault ) ,
2011-07-20 04:57:44 +08:00
m_last_format_mgr_revision ( 0 ) ,
2012-03-01 12:24:26 +08:00
m_type_summary_sp ( ) ,
m_type_format_sp ( ) ,
m_synthetic_children_sp ( ) ,
2014-09-06 05:46:22 +08:00
m_type_validator_sp ( ) ,
2011-08-09 10:12:22 +08:00
m_user_id_of_forced_summary ( ) ,
2011-11-01 06:50:49 +08:00
m_address_type_of_ptr_or_ref_children ( child_ptr_or_ref_addr_type ) ,
2014-12-10 05:18:59 +08:00
m_value_checksum ( ) ,
2015-01-21 09:47:13 +08:00
m_preferred_display_language ( lldb : : eLanguageTypeUnknown ) ,
2011-03-31 08:19:25 +08:00
m_value_is_valid ( false ) ,
m_value_did_change ( false ) ,
m_children_count_valid ( false ) ,
m_old_value_valid ( false ) ,
2011-06-30 06:27:15 +08:00
m_is_deref_of_parent ( false ) ,
2011-07-02 08:25:22 +08:00
m_is_array_item_for_pointer ( false ) ,
2011-07-06 10:13:41 +08:00
m_is_bitfield_for_scalar ( false ) ,
2011-07-30 03:53:35 +08:00
m_is_child_at_offset ( false ) ,
2012-02-23 07:57:45 +08:00
m_is_getting_summary ( false ) ,
2014-12-10 03:51:20 +08:00
m_did_calculate_complete_objc_class_type ( false ) ,
m_is_synthetic_children_generated ( false )
2010-06-09 00:52:24 +08:00
{
2011-04-23 07:53:53 +08:00
m_manager = new ValueObjectManager ( ) ;
m_manager - > ManageObject ( this ) ;
2010-06-09 00:52:24 +08:00
}
2011-03-31 08:19:25 +08:00
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
ValueObject : : ~ ValueObject ( )
2010-06-09 00:52:24 +08:00
{
}
bool
2011-07-02 08:25:22 +08:00
ValueObject : : UpdateValueIfNeeded ( bool update_format )
2010-06-09 00:52:24 +08:00
{
2011-06-30 06:27:15 +08:00
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
bool did_change_formats = false ;
2011-07-02 08:25:22 +08:00
if ( update_format )
2013-01-29 07:47:25 +08:00
did_change_formats = UpdateFormatsIfNeeded ( ) ;
2011-06-30 06:27:15 +08:00
2010-10-05 11:13:51 +08:00
// If this is a constant value, then our success is predicated on whether
// we have an error or not
if ( GetIsConstant ( ) )
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{
2013-10-09 08:33:55 +08:00
// if you are constant, things might still have changed behind your back
// (e.g. you are a frozen object and things have changed deeper than you cared to freeze-dry yourself)
// in this case, your value has not changed, but "computed" entries might have, so you might now have
// a different summary, or a different object description. clear these so we will recompute them
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
if ( update_format & & ! did_change_formats )
2013-10-09 08:33:55 +08:00
ClearUserVisibleData ( eClearUserVisibleDataItemsSummary | eClearUserVisibleDataItemsDescription ) ;
2010-10-05 11:13:51 +08:00
return m_error . Success ( ) ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
}
2010-10-05 11:13:51 +08:00
2014-12-10 05:18:59 +08:00
bool first_update = IsChecksumEmpty ( ) ;
2011-03-31 08:19:25 +08:00
2015-05-16 09:27:00 +08:00
if ( NeedsUpdating ( ) )
2010-06-09 00:52:24 +08:00
{
2011-03-31 08:19:25 +08:00
m_update_point . SetUpdated ( ) ;
// Save the old value using swap to avoid a string copy which
// also will clear our m_value_str
if ( m_value_str . empty ( ) )
2010-06-09 00:52:24 +08:00
{
2011-03-31 08:19:25 +08:00
m_old_value_valid = false ;
}
else
{
m_old_value_valid = true ;
m_old_value_str . swap ( m_value_str ) ;
2012-03-20 06:58:49 +08:00
ClearUserVisibleData ( eClearUserVisibleDataItemsValue ) ;
2011-03-31 08:19:25 +08:00
}
2010-06-09 00:52:24 +08:00
2011-07-15 10:26:42 +08:00
ClearUserVisibleData ( ) ;
2012-03-09 12:23:44 +08:00
if ( IsInScope ( ) )
{
const bool value_was_valid = GetValueIsValid ( ) ;
2011-03-31 08:19:25 +08:00
SetValueDidChange ( false ) ;
2012-03-09 12:23:44 +08:00
m_error . Clear ( ) ;
// Call the pure virtual function to update the value
2014-12-10 05:18:59 +08:00
bool need_compare_checksums = false ;
llvm : : SmallVector < uint8_t , 16 > old_checksum ;
if ( ! first_update & & CanProvideValue ( ) )
{
need_compare_checksums = true ;
old_checksum . resize ( m_value_checksum . size ( ) ) ;
std : : copy ( m_value_checksum . begin ( ) , m_value_checksum . end ( ) , old_checksum . begin ( ) ) ;
}
2012-03-09 12:23:44 +08:00
bool success = UpdateValue ( ) ;
SetValueIsValid ( success ) ;
2014-12-10 05:18:59 +08:00
if ( success )
{
const uint64_t max_checksum_size = 128 ;
m_data . Checksum ( m_value_checksum ,
max_checksum_size ) ;
}
else
{
need_compare_checksums = false ;
m_value_checksum . clear ( ) ;
}
2015-01-09 03:11:43 +08:00
assert ( ! need_compare_checksums | | ( ! old_checksum . empty ( ) & & ! m_value_checksum . empty ( ) ) ) ;
2012-03-09 12:23:44 +08:00
if ( first_update )
SetValueDidChange ( false ) ;
else if ( ! m_value_did_change & & success = = false )
{
// The value wasn't gotten successfully, so we mark this
// as changed if the value used to be valid and now isn't
SetValueDidChange ( value_was_valid ) ;
}
2014-12-10 05:18:59 +08:00
else if ( need_compare_checksums )
{
SetValueDidChange ( memcmp ( & old_checksum [ 0 ] , & m_value_checksum [ 0 ] , m_value_checksum . size ( ) ) ) ;
}
2012-03-09 12:23:44 +08:00
}
else
2011-03-31 08:19:25 +08:00
{
2012-03-09 12:23:44 +08:00
m_error . SetErrorString ( " out of scope " ) ;
2010-06-09 00:52:24 +08:00
}
}
return m_error . Success ( ) ;
}
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
bool
2013-01-29 07:47:25 +08:00
ValueObject : : UpdateFormatsIfNeeded ( )
2011-06-30 06:27:15 +08:00
{
2013-03-28 07:08:40 +08:00
Log * log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_TYPES ) ) ;
2011-07-30 03:53:35 +08:00
if ( log )
2012-10-18 06:23:56 +08:00
log - > Printf ( " [%s %p] checking for FormatManager revisions. ValueObject rev: %d - Global rev: %d " ,
2014-04-04 12:06:10 +08:00
GetName ( ) . GetCString ( ) , static_cast < void * > ( this ) ,
m_last_format_mgr_revision ,
DataVisualization : : GetCurrentRevision ( ) ) ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
bool any_change = false ;
2014-04-04 12:06:10 +08:00
2013-01-29 07:47:25 +08:00
if ( ( m_last_format_mgr_revision ! = DataVisualization : : GetCurrentRevision ( ) ) )
2011-06-30 06:27:15 +08:00
{
2014-04-10 05:06:11 +08:00
m_last_format_mgr_revision = DataVisualization : : GetCurrentRevision ( ) ;
any_change = true ;
2013-10-09 03:03:22 +08:00
SetValueFormat ( DataVisualization : : GetFormat ( * this , eNoDynamicValues ) ) ;
2013-01-29 07:47:25 +08:00
SetSummaryFormat ( DataVisualization : : GetSummaryFormat ( * this , GetDynamicValueType ( ) ) ) ;
2012-05-16 08:38:08 +08:00
# ifndef LLDB_DISABLE_PYTHON
2013-01-29 07:47:25 +08:00
SetSyntheticChildren ( DataVisualization : : GetSyntheticChildren ( * this , GetDynamicValueType ( ) ) ) ;
2012-05-16 08:38:08 +08:00
# endif
2014-09-06 05:46:22 +08:00
SetValidator ( DataVisualization : : GetValidator ( * this , GetDynamicValueType ( ) ) ) ;
2011-06-30 06:27:15 +08:00
}
2014-04-04 12:06:10 +08:00
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
return any_change ;
2011-06-30 06:27:15 +08:00
}
2011-08-13 07:34:31 +08:00
void
ValueObject : : SetNeedsUpdate ( )
{
m_update_point . SetNeedsUpdate ( ) ;
// We have to clear the value string here so ConstResult children will notice if their values are
// changed by hand (i.e. with SetValueAsCString).
2012-03-20 06:58:49 +08:00
ClearUserVisibleData ( eClearUserVisibleDataItemsValue ) ;
2011-08-13 07:34:31 +08:00
}
2012-10-18 03:03:34 +08:00
void
2012-10-23 02:18:36 +08:00
ValueObject : : ClearDynamicTypeInformation ( )
2012-10-18 03:03:34 +08:00
{
2013-10-30 08:04:29 +08:00
m_children_count_valid = false ;
2012-10-18 03:03:34 +08:00
m_did_calculate_complete_objc_class_type = false ;
2012-10-23 02:18:36 +08:00
m_last_format_mgr_revision = 0 ;
2012-10-18 03:03:34 +08:00
m_override_type = ClangASTType ( ) ;
2012-10-23 02:18:36 +08:00
SetValueFormat ( lldb : : TypeFormatImplSP ( ) ) ;
SetSummaryFormat ( lldb : : TypeSummaryImplSP ( ) ) ;
SetSyntheticChildren ( lldb : : SyntheticChildrenSP ( ) ) ;
2012-10-18 03:03:34 +08:00
}
2012-02-23 07:57:45 +08:00
ClangASTType
ValueObject : : MaybeCalculateCompleteType ( )
{
2013-07-12 06:46:58 +08:00
ClangASTType clang_type ( GetClangTypeImpl ( ) ) ;
2012-03-30 10:04:38 +08:00
2012-02-23 07:57:45 +08:00
if ( m_did_calculate_complete_objc_class_type )
{
if ( m_override_type . IsValid ( ) )
return m_override_type ;
else
2013-07-12 06:46:58 +08:00
return clang_type ;
2012-02-23 07:57:45 +08:00
}
2013-07-12 06:46:58 +08:00
ClangASTType class_type ;
bool is_pointer_type = false ;
2012-02-23 07:57:45 +08:00
2013-07-12 06:46:58 +08:00
if ( clang_type . IsObjCObjectPointerType ( & class_type ) )
2012-02-23 07:57:45 +08:00
{
is_pointer_type = true ;
}
2013-07-12 06:46:58 +08:00
else if ( clang_type . IsObjCObjectOrInterfaceType ( ) )
2012-02-23 07:57:45 +08:00
{
2013-07-12 06:46:58 +08:00
class_type = clang_type ;
2012-02-23 07:57:45 +08:00
}
else
{
2013-07-12 06:46:58 +08:00
return clang_type ;
2012-02-23 07:57:45 +08:00
}
m_did_calculate_complete_objc_class_type = true ;
2013-07-12 06:46:58 +08:00
if ( class_type )
2012-02-23 07:57:45 +08:00
{
2013-07-12 06:46:58 +08:00
ConstString class_name ( class_type . GetConstTypeName ( ) ) ;
2012-02-23 07:57:45 +08:00
2013-07-12 06:46:58 +08:00
if ( class_name )
{
ProcessSP process_sp ( GetUpdatePoint ( ) . GetExecutionContextRef ( ) . GetProcessSP ( ) ) ;
if ( process_sp )
{
ObjCLanguageRuntime * objc_language_runtime ( process_sp - > GetObjCLanguageRuntime ( ) ) ;
if ( objc_language_runtime )
{
TypeSP complete_objc_class_type_sp = objc_language_runtime - > LookupInCompleteClassCache ( class_name ) ;
if ( complete_objc_class_type_sp )
{
ClangASTType complete_class ( complete_objc_class_type_sp - > GetClangFullType ( ) ) ;
if ( complete_class . GetCompleteType ( ) )
{
if ( is_pointer_type )
{
m_override_type = complete_class . GetPointerType ( ) ;
}
else
{
m_override_type = complete_class ;
}
if ( m_override_type . IsValid ( ) )
return m_override_type ;
}
}
}
}
}
2012-02-23 07:57:45 +08:00
}
2013-07-12 06:46:58 +08:00
return clang_type ;
2012-02-23 07:57:45 +08:00
}
2013-07-12 06:46:58 +08:00
ClangASTType
2012-02-23 07:57:45 +08:00
ValueObject : : GetClangType ( )
{
2013-07-12 06:46:58 +08:00
return MaybeCalculateCompleteType ( ) ;
2012-02-23 07:57:45 +08:00
}
2013-10-29 08:28:35 +08:00
TypeImpl
ValueObject : : GetTypeImpl ( )
{
return TypeImpl ( GetClangType ( ) ) ;
}
2010-06-09 00:52:24 +08:00
DataExtractor &
ValueObject : : GetDataExtractor ( )
{
2011-08-03 01:27:39 +08:00
UpdateValueIfNeeded ( false ) ;
2010-06-09 00:52:24 +08:00
return m_data ;
}
const Error &
2011-07-07 00:49:27 +08:00
ValueObject : : GetError ( )
2010-06-09 00:52:24 +08:00
{
2011-08-03 01:27:39 +08:00
UpdateValueIfNeeded ( false ) ;
2010-06-09 00:52:24 +08:00
return m_error ;
}
const ConstString &
ValueObject : : GetName ( ) const
{
return m_name ;
}
const char *
2011-03-31 08:19:25 +08:00
ValueObject : : GetLocationAsCString ( )
2013-05-01 04:45:04 +08:00
{
return GetLocationAsCStringImpl ( m_value ,
m_data ) ;
}
const char *
ValueObject : : GetLocationAsCStringImpl ( const Value & value ,
const DataExtractor & data )
2010-06-09 00:52:24 +08:00
{
2011-08-03 01:27:39 +08:00
if ( UpdateValueIfNeeded ( false ) )
2010-06-09 00:52:24 +08:00
{
if ( m_location_str . empty ( ) )
{
StreamString sstr ;
2013-05-01 04:45:04 +08:00
Value : : ValueType value_type = value . GetValueType ( ) ;
switch ( value_type )
2010-06-09 00:52:24 +08:00
{
case Value : : eValueTypeScalar :
2012-10-31 02:18:43 +08:00
case Value : : eValueTypeVector :
2013-05-01 04:45:04 +08:00
if ( value . GetContextType ( ) = = Value : : eContextTypeRegisterInfo )
2010-06-09 00:52:24 +08:00
{
2013-05-01 04:45:04 +08:00
RegisterInfo * reg_info = value . GetRegisterInfo ( ) ;
2010-06-09 00:52:24 +08:00
if ( reg_info )
{
if ( reg_info - > name )
m_location_str = reg_info - > name ;
else if ( reg_info - > alt_name )
m_location_str = reg_info - > alt_name ;
2013-05-01 04:45:04 +08:00
if ( m_location_str . empty ( ) )
m_location_str = ( reg_info - > encoding = = lldb : : eEncodingVector ) ? " vector " : " scalar " ;
2010-06-09 00:52:24 +08:00
}
}
2013-05-01 04:45:04 +08:00
if ( m_location_str . empty ( ) )
m_location_str = ( value_type = = Value : : eValueTypeVector ) ? " vector " : " scalar " ;
2010-06-09 00:52:24 +08:00
break ;
case Value : : eValueTypeLoadAddress :
case Value : : eValueTypeFileAddress :
case Value : : eValueTypeHostAddress :
{
2013-05-01 04:45:04 +08:00
uint32_t addr_nibble_size = data . GetAddressByteSize ( ) * 2 ;
sstr . Printf ( " 0x%*.*llx " , addr_nibble_size , addr_nibble_size , value . GetScalar ( ) . ULongLong ( LLDB_INVALID_ADDRESS ) ) ;
2010-06-09 00:52:24 +08:00
m_location_str . swap ( sstr . GetString ( ) ) ;
}
break ;
}
}
}
return m_location_str . c_str ( ) ;
}
Value &
ValueObject : : GetValue ( )
{
return m_value ;
}
const Value &
ValueObject : : GetValue ( ) const
{
return m_value ;
}
2010-11-04 09:54:29 +08:00
bool
2011-03-31 08:19:25 +08:00
ValueObject : : ResolveValue ( Scalar & scalar )
2010-11-04 09:54:29 +08:00
{
2011-08-04 09:41:02 +08:00
if ( UpdateValueIfNeeded ( false ) ) // make sure that you are up to date before returning anything
{
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
2011-08-13 07:34:31 +08:00
Value tmp_value ( m_value ) ;
2013-07-12 06:46:58 +08:00
scalar = tmp_value . ResolveValue ( & exe_ctx ) ;
2011-12-29 09:26:56 +08:00
if ( scalar . IsValid ( ) )
{
const uint32_t bitfield_bit_size = GetBitfieldBitSize ( ) ;
if ( bitfield_bit_size )
return scalar . ExtractBitfield ( bitfield_bit_size , GetBitfieldBitOffset ( ) ) ;
return true ;
}
2011-08-04 09:41:02 +08:00
}
2011-12-29 09:26:56 +08:00
return false ;
2010-11-04 09:54:29 +08:00
}
2010-06-09 00:52:24 +08:00
bool
2010-09-02 10:59:18 +08:00
ValueObject : : GetValueIsValid ( ) const
2010-06-09 00:52:24 +08:00
{
2010-09-02 10:59:18 +08:00
return m_value_is_valid ;
2010-06-09 00:52:24 +08:00
}
void
ValueObject : : SetValueIsValid ( bool b )
{
2010-09-02 10:59:18 +08:00
m_value_is_valid = b ;
2010-06-09 00:52:24 +08:00
}
bool
2011-03-31 08:19:25 +08:00
ValueObject : : GetValueDidChange ( )
2010-06-09 00:52:24 +08:00
{
2010-09-02 10:59:18 +08:00
return m_value_did_change ;
2010-06-09 00:52:24 +08:00
}
void
ValueObject : : SetValueDidChange ( bool value_changed )
{
2010-09-02 10:59:18 +08:00
m_value_did_change = value_changed ;
2010-06-09 00:52:24 +08:00
}
ValueObjectSP
2013-01-26 02:06:21 +08:00
ValueObject : : GetChildAtIndex ( size_t idx , bool can_create )
2010-06-09 00:52:24 +08:00
{
ValueObjectSP child_sp ;
2011-06-30 06:09:02 +08:00
// We may need to update our value if we are dynamic
if ( IsPossibleDynamicType ( ) )
2011-08-03 01:27:39 +08:00
UpdateValueIfNeeded ( false ) ;
2011-06-30 06:09:02 +08:00
if ( idx < GetNumChildren ( ) )
2010-06-09 00:52:24 +08:00
{
2011-06-30 06:09:02 +08:00
// Check if we have already made the child value object?
2012-03-09 11:09:58 +08:00
if ( can_create & & ! m_children . HasChildAtIndex ( idx ) )
2010-06-09 00:52:24 +08:00
{
2011-06-30 06:09:02 +08:00
// No we haven't created the child at this index, so lets have our
// subclass do it and cache the result for quick future access.
2012-03-09 11:09:58 +08:00
m_children . SetChildAtIndex ( idx , CreateChildAtIndex ( idx , false , 0 ) ) ;
2011-04-16 08:01:13 +08:00
}
2011-06-30 06:09:02 +08:00
2012-03-09 11:09:58 +08:00
ValueObject * child = m_children . GetChildAtIndex ( idx ) ;
if ( child ! = NULL )
return child - > GetSP ( ) ;
2010-06-09 00:52:24 +08:00
}
return child_sp ;
}
2013-01-12 09:00:22 +08:00
ValueObjectSP
2013-01-26 02:06:21 +08:00
ValueObject : : GetChildAtIndexPath ( const std : : initializer_list < size_t > & idxs ,
size_t * index_of_error )
2013-01-12 09:00:22 +08:00
{
if ( idxs . size ( ) = = 0 )
return GetSP ( ) ;
ValueObjectSP root ( GetSP ( ) ) ;
2013-01-26 02:06:21 +08:00
for ( size_t idx : idxs )
2013-01-12 09:00:22 +08:00
{
root = root - > GetChildAtIndex ( idx , true ) ;
if ( ! root )
{
if ( index_of_error )
* index_of_error = idx ;
return root ;
}
}
return root ;
}
ValueObjectSP
2013-01-26 02:06:21 +08:00
ValueObject : : GetChildAtIndexPath ( const std : : initializer_list < std : : pair < size_t , bool > > & idxs ,
size_t * index_of_error )
2013-01-12 09:00:22 +08:00
{
if ( idxs . size ( ) = = 0 )
return GetSP ( ) ;
ValueObjectSP root ( GetSP ( ) ) ;
2013-01-26 02:06:21 +08:00
for ( std : : pair < size_t , bool > idx : idxs )
2013-01-12 09:00:22 +08:00
{
root = root - > GetChildAtIndex ( idx . first , idx . second ) ;
if ( ! root )
{
if ( index_of_error )
* index_of_error = idx . first ;
return root ;
}
}
return root ;
}
lldb : : ValueObjectSP
2013-01-26 02:06:21 +08:00
ValueObject : : GetChildAtIndexPath ( const std : : vector < size_t > & idxs ,
size_t * index_of_error )
2013-01-12 09:00:22 +08:00
{
if ( idxs . size ( ) = = 0 )
return GetSP ( ) ;
ValueObjectSP root ( GetSP ( ) ) ;
2013-01-26 02:06:21 +08:00
for ( size_t idx : idxs )
2013-01-12 09:00:22 +08:00
{
root = root - > GetChildAtIndex ( idx , true ) ;
if ( ! root )
{
if ( index_of_error )
* index_of_error = idx ;
return root ;
}
}
return root ;
}
lldb : : ValueObjectSP
2013-01-26 02:06:21 +08:00
ValueObject : : GetChildAtIndexPath ( const std : : vector < std : : pair < size_t , bool > > & idxs ,
size_t * index_of_error )
2013-01-12 09:00:22 +08:00
{
if ( idxs . size ( ) = = 0 )
return GetSP ( ) ;
ValueObjectSP root ( GetSP ( ) ) ;
2013-01-26 02:06:21 +08:00
for ( std : : pair < size_t , bool > idx : idxs )
2013-01-12 09:00:22 +08:00
{
root = root - > GetChildAtIndex ( idx . first , idx . second ) ;
if ( ! root )
{
if ( index_of_error )
* index_of_error = idx . first ;
return root ;
}
}
return root ;
}
2013-09-12 08:48:47 +08:00
lldb : : ValueObjectSP
ValueObject : : GetChildAtNamePath ( const std : : initializer_list < ConstString > & names ,
ConstString * name_of_error )
{
if ( names . size ( ) = = 0 )
return GetSP ( ) ;
ValueObjectSP root ( GetSP ( ) ) ;
for ( ConstString name : names )
{
root = root - > GetChildMemberWithName ( name , true ) ;
if ( ! root )
{
if ( name_of_error )
* name_of_error = name ;
return root ;
}
}
return root ;
}
lldb : : ValueObjectSP
ValueObject : : GetChildAtNamePath ( const std : : vector < ConstString > & names ,
ConstString * name_of_error )
{
if ( names . size ( ) = = 0 )
return GetSP ( ) ;
ValueObjectSP root ( GetSP ( ) ) ;
for ( ConstString name : names )
{
root = root - > GetChildMemberWithName ( name , true ) ;
if ( ! root )
{
if ( name_of_error )
* name_of_error = name ;
return root ;
}
}
return root ;
}
lldb : : ValueObjectSP
ValueObject : : GetChildAtNamePath ( const std : : initializer_list < std : : pair < ConstString , bool > > & names ,
ConstString * name_of_error )
{
if ( names . size ( ) = = 0 )
return GetSP ( ) ;
ValueObjectSP root ( GetSP ( ) ) ;
for ( std : : pair < ConstString , bool > name : names )
{
root = root - > GetChildMemberWithName ( name . first , name . second ) ;
if ( ! root )
{
if ( name_of_error )
* name_of_error = name . first ;
return root ;
}
}
return root ;
}
lldb : : ValueObjectSP
ValueObject : : GetChildAtNamePath ( const std : : vector < std : : pair < ConstString , bool > > & names ,
ConstString * name_of_error )
{
if ( names . size ( ) = = 0 )
return GetSP ( ) ;
ValueObjectSP root ( GetSP ( ) ) ;
for ( std : : pair < ConstString , bool > name : names )
{
root = root - > GetChildMemberWithName ( name . first , name . second ) ;
if ( ! root )
{
if ( name_of_error )
* name_of_error = name . first ;
return root ;
}
}
return root ;
}
2013-01-26 02:06:21 +08:00
size_t
2010-06-09 00:52:24 +08:00
ValueObject : : GetIndexOfChildWithName ( const ConstString & name )
{
bool omit_empty_base_classes = true ;
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . GetIndexOfChildWithName ( name . GetCString ( ) , omit_empty_base_classes ) ;
2010-06-09 00:52:24 +08:00
}
ValueObjectSP
ValueObject : : GetChildMemberWithName ( const ConstString & name , bool can_create )
{
2011-01-09 04:28:42 +08:00
// when getting a child by name, it could be buried inside some base
2010-06-09 00:52:24 +08:00
// classes (which really aren't part of the expression path), so we
// need a vector of indexes that can get us down to the correct child
ValueObjectSP child_sp ;
2011-06-30 06:09:02 +08:00
// We may need to update our value if we are dynamic
if ( IsPossibleDynamicType ( ) )
2011-08-03 01:27:39 +08:00
UpdateValueIfNeeded ( false ) ;
2011-06-30 06:09:02 +08:00
std : : vector < uint32_t > child_indexes ;
bool omit_empty_base_classes = true ;
2013-07-12 06:46:58 +08:00
const size_t num_child_indexes = GetClangType ( ) . GetIndexOfChildMemberWithName ( name . GetCString ( ) ,
omit_empty_base_classes ,
child_indexes ) ;
2011-06-30 06:09:02 +08:00
if ( num_child_indexes > 0 )
2011-04-16 08:01:13 +08:00
{
2011-06-30 06:09:02 +08:00
std : : vector < uint32_t > : : const_iterator pos = child_indexes . begin ( ) ;
std : : vector < uint32_t > : : const_iterator end = child_indexes . end ( ) ;
2011-04-16 08:01:13 +08:00
2011-06-30 06:09:02 +08:00
child_sp = GetChildAtIndex ( * pos , can_create ) ;
for ( + + pos ; pos ! = end ; + + pos )
{
if ( child_sp )
2010-06-09 00:52:24 +08:00
{
2011-06-30 06:09:02 +08:00
ValueObjectSP new_child_sp ( child_sp - > GetChildAtIndex ( * pos , can_create ) ) ;
child_sp = new_child_sp ;
}
else
{
child_sp . reset ( ) ;
2011-04-16 08:01:13 +08:00
}
2011-06-30 06:09:02 +08:00
2010-06-09 00:52:24 +08:00
}
}
return child_sp ;
}
2013-01-26 02:06:21 +08:00
size_t
2010-06-09 00:52:24 +08:00
ValueObject : : GetNumChildren ( )
{
2012-03-27 10:35:13 +08:00
UpdateValueIfNeeded ( ) ;
2010-09-02 10:59:18 +08:00
if ( ! m_children_count_valid )
2010-06-09 00:52:24 +08:00
{
SetNumChildren ( CalculateNumChildren ( ) ) ;
}
2012-03-09 11:09:58 +08:00
return m_children . GetChildrenCount ( ) ;
2010-06-09 00:52:24 +08:00
}
2012-10-23 09:50:10 +08:00
bool
ValueObject : : MightHaveChildren ( )
{
2012-10-23 10:07:54 +08:00
bool has_children = false ;
2013-02-09 06:02:02 +08:00
const uint32_t type_info = GetTypeInfo ( ) ;
if ( type_info )
2012-10-23 09:50:10 +08:00
{
2014-10-22 04:52:14 +08:00
if ( type_info & ( eTypeHasChildren |
eTypeIsPointer |
eTypeIsReference ) )
2012-10-23 09:50:10 +08:00
has_children = true ;
}
else
{
has_children = GetNumChildren ( ) > 0 ;
}
return has_children ;
}
// Should only be called by ValueObject::GetNumChildren()
2010-06-09 00:52:24 +08:00
void
2013-01-26 02:06:21 +08:00
ValueObject : : SetNumChildren ( size_t num_children )
2010-06-09 00:52:24 +08:00
{
2010-09-02 10:59:18 +08:00
m_children_count_valid = true ;
2012-03-09 11:09:58 +08:00
m_children . SetChildrenCount ( num_children ) ;
2010-06-09 00:52:24 +08:00
}
void
ValueObject : : SetName ( const ConstString & name )
{
m_name = name ;
}
2011-04-23 07:53:53 +08:00
ValueObject *
2013-01-26 02:06:21 +08:00
ValueObject : : CreateChildAtIndex ( size_t idx , bool synthetic_array_member , int32_t synthetic_index )
2010-06-09 00:52:24 +08:00
{
2011-05-07 08:10:58 +08:00
ValueObject * valobj = NULL ;
2011-04-16 08:01:13 +08:00
2011-06-30 06:09:02 +08:00
bool omit_empty_base_classes = true ;
2011-07-10 04:12:33 +08:00
bool ignore_array_bounds = synthetic_array_member ;
2011-06-30 06:09:02 +08:00
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 ;
bool child_is_deref_of_parent = false ;
const bool transparent_pointers = synthetic_array_member = = false ;
2013-07-12 06:46:58 +08:00
ClangASTType child_clang_type ;
2011-06-30 06:09:02 +08:00
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
2011-06-30 06:09:02 +08:00
2013-07-12 06:46:58 +08:00
child_clang_type = GetClangType ( ) . GetChildClangTypeAtIndex ( & exe_ctx ,
idx ,
transparent_pointers ,
omit_empty_base_classes ,
ignore_array_bounds ,
child_name_str ,
child_byte_size ,
child_byte_offset ,
child_bitfield_bit_size ,
child_bitfield_bit_offset ,
child_is_base_class ,
2014-07-19 08:12:57 +08:00
child_is_deref_of_parent ,
this ) ;
2012-12-06 10:33:54 +08:00
if ( child_clang_type )
2010-06-09 00:52:24 +08:00
{
2011-06-30 06:09:02 +08:00
if ( synthetic_index )
child_byte_offset + = child_byte_size * synthetic_index ;
ConstString child_name ;
if ( ! child_name_str . empty ( ) )
child_name . SetCString ( child_name_str . c_str ( ) ) ;
valobj = new ValueObjectChild ( * this ,
child_clang_type ,
child_name ,
child_byte_size ,
child_byte_offset ,
child_bitfield_bit_size ,
child_bitfield_bit_offset ,
child_is_base_class ,
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
child_is_deref_of_parent ,
eAddressTypeInvalid ) ;
//if (valobj)
// valobj->SetAddressTypeOfChildren(eAddressTypeInvalid);
}
2011-04-16 08:01:13 +08:00
2011-04-23 07:53:53 +08:00
return valobj ;
2010-06-09 00:52:24 +08:00
}
2012-03-01 12:24:26 +08:00
bool
ValueObject : : GetSummaryAsCString ( TypeSummaryImpl * summary_ptr ,
std : : string & destination )
2014-11-07 05:23:20 +08:00
{
return GetSummaryAsCString ( summary_ptr , destination , TypeSummaryOptions ( ) ) ;
}
bool
ValueObject : : GetSummaryAsCString ( TypeSummaryImpl * summary_ptr ,
std : : string & destination ,
const TypeSummaryOptions & options )
2010-06-09 00:52:24 +08:00
{
2012-03-01 12:24:26 +08:00
destination . clear ( ) ;
// ideally we would like to bail out if passing NULL, but if we do so
// we end up not providing the summary for function pointers anymore
if ( /*summary_ptr == NULL ||*/ m_is_getting_summary )
return false ;
2012-01-08 04:58:07 +08:00
m_is_getting_summary = true ;
2012-04-05 01:34:10 +08:00
// this is a hot path in code and we prefer to avoid setting this string all too often also clearing out other
// information that we might care to see in a crash log. might be useful in very specific situations though.
/*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s. Summary provider's description is %s",
GetTypeName ( ) . GetCString ( ) ,
GetName ( ) . GetCString ( ) ,
summary_ptr - > GetDescription ( ) . c_str ( ) ) ; */
2014-12-10 10:00:45 +08:00
if ( UpdateValueIfNeeded ( false ) & & summary_ptr )
2012-03-01 12:24:26 +08:00
{
2014-12-10 10:00:45 +08:00
if ( HasSyntheticValue ( ) )
m_synthetic_value - > UpdateValueIfNeeded ( ) ; // the summary might depend on the synthetic children being up-to-date (e.g. ${svar%#})
summary_ptr - > FormatObject ( this , destination , options ) ;
2010-06-09 00:52:24 +08:00
}
2012-01-08 04:58:07 +08:00
m_is_getting_summary = false ;
2012-03-01 12:24:26 +08:00
return ! destination . empty ( ) ;
}
const char *
ValueObject : : GetSummaryAsCString ( )
{
if ( UpdateValueIfNeeded ( true ) & & m_summary_str . empty ( ) )
{
GetSummaryAsCString ( GetSummaryFormat ( ) . get ( ) ,
2014-11-07 05:23:20 +08:00
m_summary_str ,
2014-11-19 07:36:25 +08:00
TypeSummaryOptions ( ) ) ;
2012-03-01 12:24:26 +08:00
}
2010-06-09 00:52:24 +08:00
if ( m_summary_str . empty ( ) )
return NULL ;
return m_summary_str . c_str ( ) ;
}
2014-11-19 07:36:25 +08:00
bool
ValueObject : : GetSummaryAsCString ( std : : string & destination ,
const TypeSummaryOptions & options )
{
return GetSummaryAsCString ( GetSummaryFormat ( ) . get ( ) ,
destination ,
options ) ;
}
2011-07-12 08:18:11 +08:00
bool
ValueObject : : IsCStringContainer ( bool check_pointer )
{
2013-07-12 06:46:58 +08:00
ClangASTType pointee_or_element_clang_type ;
const Flags type_flags ( GetTypeInfo ( & pointee_or_element_clang_type ) ) ;
2014-10-22 04:52:14 +08:00
bool is_char_arr_ptr ( type_flags . AnySet ( eTypeIsArray | eTypeIsPointer ) & &
2013-07-12 06:46:58 +08:00
pointee_or_element_clang_type . IsCharType ( ) ) ;
2011-07-12 08:18:11 +08:00
if ( ! is_char_arr_ptr )
return false ;
if ( ! check_pointer )
return true ;
2014-10-22 04:52:14 +08:00
if ( type_flags . Test ( eTypeIsArray ) )
2011-07-12 08:18:11 +08:00
return true ;
2011-09-02 09:15:17 +08:00
addr_t cstr_address = LLDB_INVALID_ADDRESS ;
2011-07-12 08:18:11 +08:00
AddressType cstr_address_type = eAddressTypeInvalid ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
cstr_address = GetAddressOf ( true , & cstr_address_type ) ;
2011-07-12 08:18:11 +08:00
return ( cstr_address ! = LLDB_INVALID_ADDRESS ) ;
}
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
size_t
ValueObject : : GetPointeeData ( DataExtractor & data ,
uint32_t item_idx ,
uint32_t item_count )
{
2013-07-12 06:46:58 +08:00
ClangASTType pointee_or_element_clang_type ;
2013-02-09 06:02:02 +08:00
const uint32_t type_info = GetTypeInfo ( & pointee_or_element_clang_type ) ;
2014-10-22 04:52:14 +08:00
const bool is_pointer_type = type_info & eTypeIsPointer ;
const bool is_array_type = type_info & eTypeIsArray ;
2013-02-09 06:02:02 +08:00
if ( ! ( is_pointer_type | | is_array_type ) )
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
return 0 ;
if ( item_count = = 0 )
return 0 ;
2015-01-28 09:09:45 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
2015-02-12 08:34:25 +08:00
const uint64_t item_type_size = pointee_or_element_clang_type . GetByteSize ( exe_ctx . GetBestExecutionContextScope ( ) ) ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
const uint64_t bytes = item_count * item_type_size ;
const uint64_t offset = item_idx * item_type_size ;
if ( item_idx = = 0 & & item_count = = 1 ) // simply a deref
{
2013-02-09 06:02:02 +08:00
if ( is_pointer_type )
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{
Error error ;
ValueObjectSP pointee_sp = Dereference ( error ) ;
if ( error . Fail ( ) | | pointee_sp . get ( ) = = NULL )
return 0 ;
2014-03-01 06:27:53 +08:00
return pointee_sp - > GetData ( data , error ) ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
}
else
{
ValueObjectSP child_sp = GetChildAtIndex ( 0 , true ) ;
if ( child_sp . get ( ) = = NULL )
return 0 ;
2014-03-01 06:27:53 +08:00
Error error ;
return child_sp - > GetData ( data , error ) ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
}
return true ;
}
else /* (items > 1) */
{
Error error ;
lldb_private : : DataBufferHeap * heap_buf_ptr = NULL ;
lldb : : DataBufferSP data_sp ( heap_buf_ptr = new lldb_private : : DataBufferHeap ( ) ) ;
AddressType addr_type ;
2013-02-09 06:02:02 +08:00
lldb : : addr_t addr = is_pointer_type ? GetPointerValue ( & addr_type ) : GetAddressOf ( true , & addr_type ) ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
switch ( addr_type )
{
case eAddressTypeFile :
{
2012-02-24 09:59:29 +08:00
ModuleSP module_sp ( GetModule ( ) ) ;
if ( module_sp )
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{
2012-08-07 09:49:34 +08:00
addr = addr + offset ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
Address so_addr ;
2012-02-24 09:59:29 +08:00
module_sp - > ResolveFileAddress ( addr , so_addr ) ;
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
if ( target )
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{
2012-02-17 15:49:44 +08:00
heap_buf_ptr - > SetByteSize ( bytes ) ;
size_t bytes_read = target - > ReadMemory ( so_addr , false , heap_buf_ptr - > GetBytes ( ) , bytes , error ) ;
if ( error . Success ( ) )
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{
2012-02-17 15:49:44 +08:00
data . SetData ( data_sp ) ;
return bytes_read ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
}
}
}
}
break ;
case eAddressTypeLoad :
{
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
Process * process = exe_ctx . GetProcessPtr ( ) ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
if ( process )
{
heap_buf_ptr - > SetByteSize ( bytes ) ;
size_t bytes_read = process - > ReadMemory ( addr + offset , heap_buf_ptr - > GetBytes ( ) , bytes , error ) ;
2013-10-31 01:52:44 +08:00
if ( error . Success ( ) | | bytes_read > 0 )
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{
data . SetData ( data_sp ) ;
return bytes_read ;
}
}
}
break ;
case eAddressTypeHost :
{
2015-02-12 08:34:25 +08:00
const uint64_t max_bytes = GetClangType ( ) . GetByteSize ( exe_ctx . GetBestExecutionContextScope ( ) ) ;
2013-02-09 06:02:02 +08:00
if ( max_bytes > offset )
{
size_t bytes_read = std : : min < uint64_t > ( max_bytes - offset , bytes ) ;
2015-05-05 08:41:35 +08:00
addr = m_value . GetScalar ( ) . ULongLong ( LLDB_INVALID_ADDRESS ) ;
if ( addr = = LLDB_INVALID_ADDRESS )
break ;
2013-02-09 06:02:02 +08:00
heap_buf_ptr - > CopyData ( ( uint8_t * ) ( addr + offset ) , bytes_read ) ;
data . SetData ( data_sp ) ;
return bytes_read ;
}
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
}
break ;
case eAddressTypeInvalid :
break ;
}
}
return 0 ;
}
2013-03-15 02:31:44 +08:00
uint64_t
2014-03-01 06:27:53 +08:00
ValueObject : : GetData ( DataExtractor & data , Error & error )
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{
UpdateValueIfNeeded ( false ) ;
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
2014-03-01 06:27:53 +08:00
error = m_value . GetValueAsData ( & exe_ctx , data , 0 , GetModule ( ) . get ( ) ) ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
if ( error . Fail ( ) )
2013-04-20 03:47:32 +08:00
{
if ( m_data . GetByteSize ( ) )
{
data = m_data ;
return data . GetByteSize ( ) ;
}
else
{
return 0 ;
}
}
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
data . SetAddressByteSize ( m_data . GetAddressByteSize ( ) ) ;
data . SetByteOrder ( m_data . GetByteOrder ( ) ) ;
return data . GetByteSize ( ) ;
}
2013-04-13 09:21:23 +08:00
bool
ValueObject : : SetData ( DataExtractor & data , Error & error )
{
error . Clear ( ) ;
// Make sure our value is up to date first so that our location and location
// type is valid.
if ( ! UpdateValueIfNeeded ( false ) )
{
error . SetErrorString ( " unable to read value " ) ;
return false ;
}
uint64_t count = 0 ;
2013-07-12 06:46:58 +08:00
const Encoding encoding = GetClangType ( ) . GetEncoding ( count ) ;
2013-04-13 09:21:23 +08:00
const size_t byte_size = GetByteSize ( ) ;
Value : : ValueType value_type = m_value . GetValueType ( ) ;
switch ( value_type )
{
case Value : : eValueTypeScalar :
{
Error set_error = m_value . GetScalar ( ) . SetValueFromData ( data , encoding , byte_size ) ;
if ( ! set_error . Success ( ) )
{
error . SetErrorStringWithFormat ( " unable to set scalar value: %s " , set_error . AsCString ( ) ) ;
return false ;
}
}
break ;
case Value : : eValueTypeLoadAddress :
{
// If it is a load address, then the scalar value is the storage location
// of the data, and we have to shove this value down to that load location.
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
Process * process = exe_ctx . GetProcessPtr ( ) ;
if ( process )
{
addr_t target_addr = m_value . GetScalar ( ) . ULongLong ( LLDB_INVALID_ADDRESS ) ;
size_t bytes_written = process - > WriteMemory ( target_addr ,
data . GetDataStart ( ) ,
byte_size ,
error ) ;
if ( ! error . Success ( ) )
return false ;
if ( bytes_written ! = byte_size )
{
error . SetErrorString ( " unable to write value to memory " ) ;
return false ;
}
}
}
break ;
case Value : : eValueTypeHostAddress :
{
// If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
DataBufferSP buffer_sp ( new DataBufferHeap ( byte_size , 0 ) ) ;
m_data . SetData ( buffer_sp , 0 ) ;
data . CopyByteOrderedData ( 0 ,
byte_size ,
const_cast < uint8_t * > ( m_data . GetDataStart ( ) ) ,
byte_size ,
m_data . GetByteOrder ( ) ) ;
m_value . GetScalar ( ) = ( uintptr_t ) m_data . GetDataStart ( ) ;
}
break ;
case Value : : eValueTypeFileAddress :
case Value : : eValueTypeVector :
break ;
}
// If we have reached this point, then we have successfully changed the value.
SetNeedsUpdate ( ) ;
return true ;
}
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
// will compute strlen(str), but without consuming more than
// maxlen bytes out of str (this serves the purpose of reading
// chunks of a string without having to worry about
// missing NULL terminators in the chunk)
// of course, if strlen(str) > maxlen, the function will return
// maxlen_value (which should be != maxlen, because that allows you
// to know whether strlen(str) == maxlen or strlen(str) > maxlen)
static uint32_t
strlen_or_inf ( const char * str ,
uint32_t maxlen ,
uint32_t maxlen_value )
{
uint32_t len = 0 ;
2011-10-06 06:19:51 +08:00
if ( str )
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{
2011-10-06 06:19:51 +08:00
while ( * str )
{
len + + ; str + + ;
2013-02-09 06:02:02 +08:00
if ( len > = maxlen )
2011-10-06 06:19:51 +08:00
return maxlen_value ;
}
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
}
return len ;
}
2014-10-31 02:27:31 +08:00
static bool
CopyStringDataToBufferSP ( const StreamString & source ,
lldb : : DataBufferSP & destination )
{
destination . reset ( new DataBufferHeap ( source . GetSize ( ) + 1 , 0 ) ) ;
memcpy ( destination - > GetBytes ( ) , source . GetString ( ) . c_str ( ) , source . GetSize ( ) ) ;
return true ;
}
2013-02-22 03:57:10 +08:00
size_t
2014-10-31 02:27:31 +08:00
ValueObject : : ReadPointedString ( lldb : : DataBufferSP & buffer_sp ,
2012-02-17 15:49:44 +08:00
Error & error ,
uint32_t max_length ,
bool honor_array ,
Format item_format )
2011-07-12 08:18:11 +08:00
{
2014-10-31 02:27:31 +08:00
StreamString s ;
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
Target * target = exe_ctx . GetTargetPtr ( ) ;
2014-10-31 02:27:31 +08:00
2013-03-01 06:01:33 +08:00
if ( ! target )
{
s < < " <no target to read from> " ;
error . SetErrorString ( " no target to read from " ) ;
2014-10-31 02:27:31 +08:00
CopyStringDataToBufferSP ( s , buffer_sp ) ;
2013-03-01 06:01:33 +08:00
return 0 ;
}
if ( max_length = = 0 )
2012-02-17 15:49:44 +08:00
max_length = target - > GetMaximumSizeOfStringSummary ( ) ;
2011-07-12 08:18:11 +08:00
2013-02-22 03:57:10 +08:00
size_t bytes_read = 0 ;
size_t total_bytes_read = 0 ;
2013-07-12 06:46:58 +08:00
ClangASTType clang_type = GetClangType ( ) ;
ClangASTType elem_or_pointee_clang_type ;
2013-02-09 06:02:02 +08:00
const Flags type_flags ( GetTypeInfo ( & elem_or_pointee_clang_type ) ) ;
2014-10-22 04:52:14 +08:00
if ( type_flags . AnySet ( eTypeIsArray | eTypeIsPointer ) & &
2013-07-12 06:46:58 +08:00
elem_or_pointee_clang_type . IsCharType ( ) )
2011-07-12 08:18:11 +08:00
{
2013-03-01 06:01:33 +08:00
addr_t cstr_address = LLDB_INVALID_ADDRESS ;
AddressType cstr_address_type = eAddressTypeInvalid ;
size_t cstr_len = 0 ;
bool capped_data = false ;
2014-10-22 04:52:14 +08:00
if ( type_flags . Test ( eTypeIsArray ) )
2012-02-17 15:49:44 +08:00
{
2013-03-01 06:01:33 +08:00
// We have an array
2013-07-12 06:46:58 +08:00
uint64_t array_size = 0 ;
if ( clang_type . IsArrayType ( NULL , & array_size , NULL ) )
2013-03-01 06:01:33 +08:00
{
2013-07-12 06:46:58 +08:00
cstr_len = array_size ;
if ( cstr_len > max_length )
{
capped_data = true ;
cstr_len = max_length ;
}
2013-03-01 06:01:33 +08:00
}
cstr_address = GetAddressOf ( true , & cstr_address_type ) ;
2012-02-17 15:49:44 +08:00
}
else
{
2013-03-01 06:01:33 +08:00
// We have a pointer
cstr_address = GetPointerValue ( & cstr_address_type ) ;
}
if ( cstr_address = = 0 | | cstr_address = = LLDB_INVALID_ADDRESS )
{
s < < " <invalid address> " ;
error . SetErrorString ( " invalid address " ) ;
2014-10-31 02:27:31 +08:00
CopyStringDataToBufferSP ( s , buffer_sp ) ;
2013-03-01 06:01:33 +08:00
return 0 ;
}
2014-10-31 02:27:31 +08:00
2013-03-01 06:01:33 +08:00
Address cstr_so_addr ( cstr_address ) ;
DataExtractor data ;
if ( cstr_len > 0 & & honor_array )
{
// I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
// but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
GetPointeeData ( data , 0 , cstr_len ) ;
2014-10-31 02:27:31 +08:00
2013-03-01 06:01:33 +08:00
if ( ( bytes_read = data . GetByteSize ( ) ) > 0 )
2012-02-17 15:49:44 +08:00
{
2013-03-01 06:01:33 +08:00
total_bytes_read = bytes_read ;
2014-10-31 02:27:31 +08:00
for ( size_t offset = 0 ; offset < bytes_read ; offset + + )
s . Printf ( " %c " , * data . PeekData ( offset , 1 ) ) ;
2013-03-01 06:01:33 +08:00
if ( capped_data )
s < < " ... " ;
2012-02-17 15:49:44 +08:00
}
2013-03-01 06:01:33 +08:00
}
else
{
cstr_len = max_length ;
const size_t k_max_buf_size = 64 ;
2014-10-31 02:27:31 +08:00
2013-03-01 06:01:33 +08:00
size_t offset = 0 ;
int cstr_len_displayed = - 1 ;
bool capped_cstr = false ;
// I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
// but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
while ( ( bytes_read = GetPointeeData ( data , offset , k_max_buf_size ) ) > 0 )
2011-07-12 08:18:11 +08:00
{
2013-03-01 06:01:33 +08:00
total_bytes_read + = bytes_read ;
const char * cstr = data . PeekCStr ( 0 ) ;
size_t len = strlen_or_inf ( cstr , k_max_buf_size , k_max_buf_size + 1 ) ;
if ( len > k_max_buf_size )
len = k_max_buf_size ;
2014-10-31 02:27:31 +08:00
2013-03-01 06:01:33 +08:00
if ( cstr_len_displayed < 0 )
cstr_len_displayed = len ;
2014-10-31 02:27:31 +08:00
2013-03-01 06:01:33 +08:00
if ( len = = 0 )
break ;
cstr_len_displayed + = len ;
if ( len > bytes_read )
len = bytes_read ;
if ( len > cstr_len )
len = cstr_len ;
2014-10-31 02:27:31 +08:00
for ( size_t offset = 0 ; offset < bytes_read ; offset + + )
s . Printf ( " %c " , * data . PeekData ( offset , 1 ) ) ;
2013-03-01 06:01:33 +08:00
if ( len < k_max_buf_size )
break ;
if ( len > = cstr_len )
2011-07-30 03:53:35 +08:00
{
2013-03-01 06:01:33 +08:00
capped_cstr = true ;
break ;
2011-07-30 03:53:35 +08:00
}
2014-10-31 02:27:31 +08:00
2013-03-01 06:01:33 +08:00
cstr_len - = len ;
offset + = len ;
}
if ( cstr_len_displayed > = 0 )
{
if ( capped_cstr )
s < < " ... " ;
2011-07-12 08:18:11 +08:00
}
2012-02-17 15:49:44 +08:00
}
2011-07-12 08:18:11 +08:00
}
else
{
2013-03-01 06:01:33 +08:00
error . SetErrorString ( " not a string object " ) ;
2011-07-30 03:53:35 +08:00
s < < " <not a string object> " ;
2011-07-12 08:18:11 +08:00
}
2014-10-31 02:27:31 +08:00
CopyStringDataToBufferSP ( s , buffer_sp ) ;
2013-02-22 03:57:10 +08:00
return total_bytes_read ;
2011-07-12 08:18:11 +08:00
}
2014-09-06 05:46:22 +08:00
std : : pair < TypeValidatorResult , std : : string >
ValueObject : : GetValidationStatus ( )
{
if ( ! UpdateValueIfNeeded ( true ) )
return { TypeValidatorResult : : Success , " " } ; // not the validator's job to discuss update problems
if ( m_validation_result . hasValue ( ) )
return m_validation_result . getValue ( ) ;
if ( ! m_type_validator_sp )
return { TypeValidatorResult : : Success , " " } ; // no validator no failure
auto outcome = m_type_validator_sp - > FormatObject ( this ) ;
return ( m_validation_result = { outcome . m_result , outcome . m_message } ) . getValue ( ) ;
}
2010-09-11 07:12:17 +08:00
const char *
2011-03-31 08:19:25 +08:00
ValueObject : : GetObjectDescription ( )
2010-09-11 07:12:17 +08:00
{
2011-07-02 08:25:22 +08:00
2011-08-03 07:12:24 +08:00
if ( ! UpdateValueIfNeeded ( true ) )
2010-09-11 07:12:17 +08:00
return NULL ;
2011-07-02 08:25:22 +08:00
if ( ! m_object_desc_str . empty ( ) )
return m_object_desc_str . c_str ( ) ;
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
Process * process = exe_ctx . GetProcessPtr ( ) ;
2010-09-28 09:25:32 +08:00
if ( process = = NULL )
2010-09-11 07:12:17 +08:00
return NULL ;
2010-09-28 09:25:32 +08:00
StreamString s ;
2010-09-11 07:12:17 +08:00
2011-09-02 09:15:17 +08:00
LanguageType language = GetObjectRuntimeLanguage ( ) ;
2010-09-28 09:25:32 +08:00
LanguageRuntime * runtime = process - > GetLanguageRuntime ( language ) ;
2010-09-11 07:12:17 +08:00
2010-12-23 10:29:54 +08:00
if ( runtime = = NULL )
{
2011-03-18 08:05:18 +08:00
// Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
2013-07-12 06:46:58 +08:00
ClangASTType clang_type = GetClangType ( ) ;
if ( clang_type )
2010-12-23 10:29:54 +08:00
{
2011-03-18 08:05:18 +08:00
bool is_signed ;
2013-07-12 06:46:58 +08:00
if ( clang_type . IsIntegerType ( is_signed ) | | clang_type . IsPointerType ( ) )
2011-03-18 08:05:18 +08:00
{
2011-09-02 09:15:17 +08:00
runtime = process - > GetLanguageRuntime ( eLanguageTypeObjC ) ;
2011-03-18 08:05:18 +08:00
}
2010-12-23 10:29:54 +08:00
}
}
2011-04-01 07:01:21 +08:00
if ( runtime & & runtime - > GetObjectDescription ( s , * this ) )
2010-09-11 07:12:17 +08:00
{
m_object_desc_str . append ( s . GetData ( ) ) ;
}
2010-10-23 08:18:49 +08:00
if ( m_object_desc_str . empty ( ) )
return NULL ;
else
return m_object_desc_str . c_str ( ) ;
2010-09-11 07:12:17 +08:00
}
2010-06-09 00:52:24 +08:00
2012-03-01 12:24:26 +08:00
bool
2013-12-22 17:24:22 +08:00
ValueObject : : GetValueAsCString ( const lldb_private : : TypeFormatImpl & format ,
2012-03-01 12:24:26 +08:00
std : : string & destination )
{
2013-12-22 17:24:22 +08:00
if ( UpdateValueIfNeeded ( false ) )
return format . FormatObject ( this , destination ) ;
2012-03-01 12:24:26 +08:00
else
return false ;
}
2013-12-22 17:24:22 +08:00
bool
ValueObject : : GetValueAsCString ( lldb : : Format format ,
std : : string & destination )
{
2013-12-28 16:44:02 +08:00
return GetValueAsCString ( TypeFormatImpl_Format ( format ) , destination ) ;
2013-12-22 17:24:22 +08:00
}
2010-06-09 00:52:24 +08:00
const char *
2011-03-31 08:19:25 +08:00
ValueObject : : GetValueAsCString ( )
2010-06-09 00:52:24 +08:00
{
2013-06-01 03:18:19 +08:00
if ( UpdateValueIfNeeded ( true ) )
2010-06-09 00:52:24 +08:00
{
2013-12-22 17:24:22 +08:00
lldb : : TypeFormatImplSP format_sp ;
2012-03-01 12:24:26 +08:00
lldb : : Format my_format = GetFormat ( ) ;
2012-12-11 10:17:22 +08:00
if ( my_format = = lldb : : eFormatDefault )
2010-06-09 00:52:24 +08:00
{
2012-03-01 12:24:26 +08:00
if ( m_type_format_sp )
2013-12-22 17:24:22 +08:00
format_sp = m_type_format_sp ;
2012-03-01 12:24:26 +08:00
else
2010-06-09 00:52:24 +08:00
{
2012-03-01 12:24:26 +08:00
if ( m_is_bitfield_for_scalar )
my_format = eFormatUnsigned ;
else
2010-06-09 00:52:24 +08:00
{
2012-03-01 12:24:26 +08:00
if ( m_value . GetContextType ( ) = = Value : : eContextTypeRegisterInfo )
2010-06-09 00:52:24 +08:00
{
const RegisterInfo * reg_info = m_value . GetRegisterInfo ( ) ;
if ( reg_info )
2012-03-01 12:24:26 +08:00
my_format = reg_info - > format ;
}
else
{
Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
The way to do this is to write a synthetic child provider for your type, and have it vend the (optional) get_value function.
If get_value is defined, and it returns a valid SBValue, that SBValue's value (as in lldb_private::Value) will be used as the synthetic ValueObject's Value
The rationale for doing things this way is twofold:
- there are many possible ways to define a "value" (SBData, a Python number, ...) but SBValue seems general enough as a thing that stores a "value", so we just trade values that way and that keeps our currency trivial
- we could introduce a new level of layering (ValueObjectSyntheticValue), a new kind of formatter (synthetic value producer), but that would complicate the model (can I have a dynamic with no synthetic children but synthetic value? synthetic value with synthetic children but no dynamic?), and I really couldn't see much benefit to be reaped from this added complexity in the matrix
On the other hand, just defining a synthetic child provider with a get_value but returning no actual children is easy enough that it's not a significant road-block to adoption of this feature
Comes with a test case
llvm-svn: 219330
2014-10-09 02:27:36 +08:00
my_format = GetValue ( ) . GetClangType ( ) . GetFormat ( ) ;
2010-06-09 00:52:24 +08:00
}
}
}
}
2013-06-01 03:18:19 +08:00
if ( my_format ! = m_last_format | | m_value_str . empty ( ) )
2012-03-07 07:21:16 +08:00
{
2013-06-01 03:18:19 +08:00
m_last_format = my_format ;
2013-12-22 17:24:22 +08:00
if ( ! format_sp )
2013-12-28 16:44:02 +08:00
format_sp . reset ( new TypeFormatImpl_Format ( my_format ) ) ;
2013-12-22 17:24:22 +08:00
if ( GetValueAsCString ( * format_sp . get ( ) , m_value_str ) )
2012-03-07 07:21:16 +08:00
{
2013-06-01 03:18:19 +08:00
if ( ! m_value_did_change & & m_old_value_valid )
{
// The value was gotten successfully, so we consider the
// value as changed if the value string differs
SetValueDidChange ( m_old_value_str ! = m_value_str ) ;
}
2012-03-07 07:21:16 +08:00
}
}
2010-06-09 00:52:24 +08:00
}
if ( m_value_str . empty ( ) )
return NULL ;
return m_value_str . c_str ( ) ;
}
2011-08-03 01:27:39 +08:00
// if > 8bytes, 0 is returned. this method should mostly be used
// to read address values out of pointers
2011-08-22 10:49:39 +08:00
uint64_t
2012-06-06 03:37:43 +08:00
ValueObject : : GetValueAsUnsigned ( uint64_t fail_value , bool * success )
2011-08-03 01:27:39 +08:00
{
// If our byte size is zero this is an aggregate type that has children
Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
The way to do this is to write a synthetic child provider for your type, and have it vend the (optional) get_value function.
If get_value is defined, and it returns a valid SBValue, that SBValue's value (as in lldb_private::Value) will be used as the synthetic ValueObject's Value
The rationale for doing things this way is twofold:
- there are many possible ways to define a "value" (SBData, a Python number, ...) but SBValue seems general enough as a thing that stores a "value", so we just trade values that way and that keeps our currency trivial
- we could introduce a new level of layering (ValueObjectSyntheticValue), a new kind of formatter (synthetic value producer), but that would complicate the model (can I have a dynamic with no synthetic children but synthetic value? synthetic value with synthetic children but no dynamic?), and I really couldn't see much benefit to be reaped from this added complexity in the matrix
On the other hand, just defining a synthetic child provider with a get_value but returning no actual children is easy enough that it's not a significant road-block to adoption of this feature
Comes with a test case
llvm-svn: 219330
2014-10-09 02:27:36 +08:00
if ( CanProvideValue ( ) )
2011-08-03 01:27:39 +08:00
{
2011-08-22 10:49:39 +08:00
Scalar scalar ;
if ( ResolveValue ( scalar ) )
2012-06-06 03:37:43 +08:00
{
if ( success )
* success = true ;
2012-10-25 04:24:39 +08:00
return scalar . ULongLong ( fail_value ) ;
2012-06-06 03:37:43 +08:00
}
// fallthrough, otherwise...
2011-08-03 01:27:39 +08:00
}
2012-06-06 03:37:43 +08:00
if ( success )
* success = false ;
2011-08-22 10:49:39 +08:00
return fail_value ;
2011-08-03 01:27:39 +08:00
}
2013-11-01 02:57:50 +08:00
int64_t
ValueObject : : GetValueAsSigned ( int64_t fail_value , bool * success )
{
// If our byte size is zero this is an aggregate type that has children
Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
The way to do this is to write a synthetic child provider for your type, and have it vend the (optional) get_value function.
If get_value is defined, and it returns a valid SBValue, that SBValue's value (as in lldb_private::Value) will be used as the synthetic ValueObject's Value
The rationale for doing things this way is twofold:
- there are many possible ways to define a "value" (SBData, a Python number, ...) but SBValue seems general enough as a thing that stores a "value", so we just trade values that way and that keeps our currency trivial
- we could introduce a new level of layering (ValueObjectSyntheticValue), a new kind of formatter (synthetic value producer), but that would complicate the model (can I have a dynamic with no synthetic children but synthetic value? synthetic value with synthetic children but no dynamic?), and I really couldn't see much benefit to be reaped from this added complexity in the matrix
On the other hand, just defining a synthetic child provider with a get_value but returning no actual children is easy enough that it's not a significant road-block to adoption of this feature
Comes with a test case
llvm-svn: 219330
2014-10-09 02:27:36 +08:00
if ( CanProvideValue ( ) )
2013-11-01 02:57:50 +08:00
{
Scalar scalar ;
if ( ResolveValue ( scalar ) )
{
if ( success )
* success = true ;
2015-01-23 18:54:21 +08:00
return scalar . SLongLong ( fail_value ) ;
2013-11-01 02:57:50 +08:00
}
// fallthrough, otherwise...
}
if ( success )
* success = false ;
2015-01-23 18:54:21 +08:00
return fail_value ;
2013-11-01 02:57:50 +08:00
}
2011-08-20 05:13:46 +08:00
// if any more "special cases" are added to ValueObject::DumpPrintableRepresentation() please keep
// this call up to date by returning true for your new special cases. We will eventually move
// to checking this call result before trying to display special cases
bool
2012-03-20 06:58:49 +08:00
ValueObject : : HasSpecialPrintableRepresentation ( ValueObjectRepresentationStyle val_obj_display ,
Format custom_format )
2011-08-20 05:13:46 +08:00
{
2013-07-12 06:46:58 +08:00
Flags flags ( GetTypeInfo ( ) ) ;
2014-10-22 04:52:14 +08:00
if ( flags . AnySet ( eTypeIsArray | eTypeIsPointer )
2012-03-20 06:58:49 +08:00
& & val_obj_display = = ValueObject : : eValueObjectRepresentationStyleValue )
2011-08-20 05:13:46 +08:00
{
if ( IsCStringContainer ( true ) & &
2011-09-02 09:15:17 +08:00
( custom_format = = eFormatCString | |
custom_format = = eFormatCharArray | |
custom_format = = eFormatChar | |
custom_format = = eFormatVectorOfChar ) )
2011-08-20 05:13:46 +08:00
return true ;
2014-10-22 04:52:14 +08:00
if ( flags . Test ( eTypeIsArray ) )
2011-08-20 05:13:46 +08:00
{
2011-09-02 09:15:17 +08:00
if ( ( custom_format = = eFormatBytes ) | |
( custom_format = = eFormatBytesWithASCII ) )
2011-08-20 05:13:46 +08:00
return true ;
2011-09-02 09:15:17 +08:00
if ( ( custom_format = = eFormatVectorOfChar ) | |
( custom_format = = eFormatVectorOfFloat32 ) | |
( custom_format = = eFormatVectorOfFloat64 ) | |
( custom_format = = eFormatVectorOfSInt16 ) | |
( custom_format = = eFormatVectorOfSInt32 ) | |
( custom_format = = eFormatVectorOfSInt64 ) | |
( custom_format = = eFormatVectorOfSInt8 ) | |
( custom_format = = eFormatVectorOfUInt128 ) | |
( custom_format = = eFormatVectorOfUInt16 ) | |
( custom_format = = eFormatVectorOfUInt32 ) | |
( custom_format = = eFormatVectorOfUInt64 ) | |
( custom_format = = eFormatVectorOfUInt8 ) )
2011-08-20 05:13:46 +08:00
return true ;
}
}
return false ;
}
2011-07-06 10:13:41 +08:00
bool
ValueObject : : DumpPrintableRepresentation ( Stream & s ,
ValueObjectRepresentationStyle val_obj_display ,
2011-09-02 09:15:17 +08:00
Format custom_format ,
2014-01-08 09:36:59 +08:00
PrintableRepresentationSpecialCases special ,
bool do_dump_error )
2011-07-06 10:13:41 +08:00
{
2011-07-13 06:56:10 +08:00
2013-07-12 06:46:58 +08:00
Flags flags ( GetTypeInfo ( ) ) ;
2011-07-12 08:18:11 +08:00
2012-03-20 06:58:49 +08:00
bool allow_special = ( ( special & ePrintableRepresentationSpecialCasesAllow ) = = ePrintableRepresentationSpecialCasesAllow ) ;
bool only_special = ( ( special & ePrintableRepresentationSpecialCasesOnly ) = = ePrintableRepresentationSpecialCasesOnly ) ;
if ( allow_special )
2011-07-12 08:18:11 +08:00
{
2014-10-22 04:52:14 +08:00
if ( flags . AnySet ( eTypeIsArray | eTypeIsPointer )
2012-03-20 06:58:49 +08:00
& & val_obj_display = = ValueObject : : eValueObjectRepresentationStyleValue )
2011-07-13 06:56:10 +08:00
{
2012-03-20 06:58:49 +08:00
// when being asked to get a printable display an array or pointer type directly,
// try to "do the right thing"
if ( IsCStringContainer ( true ) & &
( custom_format = = eFormatCString | |
custom_format = = eFormatCharArray | |
custom_format = = eFormatChar | |
custom_format = = eFormatVectorOfChar ) ) // print char[] & char* directly
2011-07-13 06:56:10 +08:00
{
2012-03-20 06:58:49 +08:00
Error error ;
2014-10-31 02:27:31 +08:00
lldb : : DataBufferSP buffer_sp ;
ReadPointedString ( buffer_sp ,
2012-03-20 06:58:49 +08:00
error ,
0 ,
( custom_format = = eFormatVectorOfChar ) | |
( custom_format = = eFormatCharArray ) ) ;
2014-11-06 05:20:48 +08:00
lldb_private : : formatters : : ReadBufferAndDumpToStreamOptions options ( * this ) ;
2014-10-31 02:27:31 +08:00
options . SetData ( DataExtractor ( buffer_sp , lldb : : eByteOrderInvalid , 8 ) ) ; // none of this matters for a string - pass some defaults
options . SetStream ( & s ) ;
options . SetPrefixToken ( 0 ) ;
options . SetQuote ( ' " ' ) ;
options . SetSourceSize ( buffer_sp - > GetByteSize ( ) ) ;
lldb_private : : formatters : : ReadBufferAndDumpToStream < lldb_private : : formatters : : StringElementType : : ASCII > ( options ) ;
2012-03-20 06:58:49 +08:00
return ! error . Fail ( ) ;
}
if ( custom_format = = eFormatEnum )
return false ;
// this only works for arrays, because I have no way to know when
// the pointed memory ends, and no special \0 end of data marker
2014-10-22 04:52:14 +08:00
if ( flags . Test ( eTypeIsArray ) )
2012-03-20 06:58:49 +08:00
{
if ( ( custom_format = = eFormatBytes ) | |
( custom_format = = eFormatBytesWithASCII ) )
2011-07-13 06:56:10 +08:00
{
2013-01-26 02:06:21 +08:00
const size_t count = GetNumChildren ( ) ;
2012-03-20 06:58:49 +08:00
s < < ' [ ' ;
2013-01-26 02:06:21 +08:00
for ( size_t low = 0 ; low < count ; low + + )
2012-03-20 06:58:49 +08:00
{
if ( low )
s < < ' , ' ;
ValueObjectSP child = GetChildAtIndex ( low , true ) ;
if ( ! child . get ( ) )
{
s < < " <invalid child> " ;
continue ;
}
child - > DumpPrintableRepresentation ( s , ValueObject : : eValueObjectRepresentationStyleValue , custom_format ) ;
}
2011-07-13 06:56:10 +08:00
2012-03-20 06:58:49 +08:00
s < < ' ] ' ;
2011-07-13 06:56:10 +08:00
2012-03-20 06:58:49 +08:00
return true ;
}
2011-07-13 06:56:10 +08:00
2012-03-20 06:58:49 +08:00
if ( ( custom_format = = eFormatVectorOfChar ) | |
( custom_format = = eFormatVectorOfFloat32 ) | |
( custom_format = = eFormatVectorOfFloat64 ) | |
( custom_format = = eFormatVectorOfSInt16 ) | |
( custom_format = = eFormatVectorOfSInt32 ) | |
( custom_format = = eFormatVectorOfSInt64 ) | |
( custom_format = = eFormatVectorOfSInt8 ) | |
( custom_format = = eFormatVectorOfUInt128 ) | |
( custom_format = = eFormatVectorOfUInt16 ) | |
( custom_format = = eFormatVectorOfUInt32 ) | |
( custom_format = = eFormatVectorOfUInt64 ) | |
( custom_format = = eFormatVectorOfUInt8 ) ) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
{
2013-01-26 02:06:21 +08:00
const size_t count = GetNumChildren ( ) ;
2012-03-20 06:58:49 +08:00
Format format = FormatManager : : GetSingleItemFormat ( custom_format ) ;
s < < ' [ ' ;
2013-01-26 02:06:21 +08:00
for ( size_t low = 0 ; low < count ; low + + )
2012-03-20 06:58:49 +08:00
{
if ( low )
s < < ' , ' ;
ValueObjectSP child = GetChildAtIndex ( low , true ) ;
if ( ! child . get ( ) )
{
s < < " <invalid child> " ;
continue ;
}
child - > DumpPrintableRepresentation ( s , ValueObject : : eValueObjectRepresentationStyleValue , format ) ;
}
s < < ' ] ' ;
return true ;
}
2011-07-13 06:56:10 +08:00
}
2012-03-20 06:58:49 +08:00
if ( ( custom_format = = eFormatBoolean ) | |
( custom_format = = eFormatBinary ) | |
( custom_format = = eFormatChar ) | |
( custom_format = = eFormatCharPrintable ) | |
( custom_format = = eFormatComplexFloat ) | |
( custom_format = = eFormatDecimal ) | |
( custom_format = = eFormatHex ) | |
2012-08-10 03:33:34 +08:00
( custom_format = = eFormatHexUppercase ) | |
2012-03-20 06:58:49 +08:00
( custom_format = = eFormatFloat ) | |
( custom_format = = eFormatOctal ) | |
( custom_format = = eFormatOSType ) | |
( custom_format = = eFormatUnicode16 ) | |
( custom_format = = eFormatUnicode32 ) | |
( custom_format = = eFormatUnsigned ) | |
( custom_format = = eFormatPointer ) | |
( custom_format = = eFormatComplexInteger ) | |
( custom_format = = eFormatComplex ) | |
( custom_format = = eFormatDefault ) ) // use the [] operator
return false ;
}
}
if ( only_special )
return false ;
bool var_success = false ;
{
2013-01-26 02:06:21 +08:00
const char * cstr = NULL ;
2013-06-21 08:04:51 +08:00
// this is a local stream that we are using to ensure that the data pointed to by cstr survives
// long enough for us to copy it to its destination - it is necessary to have this temporary storage
// area for cases where our desired output is not backed by some other longer-term storage
2013-01-26 02:06:21 +08:00
StreamString strm ;
2011-07-13 06:56:10 +08:00
2014-02-15 09:24:44 +08:00
if ( custom_format ! = eFormatInvalid )
2012-03-20 06:58:49 +08:00
SetFormat ( custom_format ) ;
switch ( val_obj_display )
{
case eValueObjectRepresentationStyleValue :
2013-01-26 02:06:21 +08:00
cstr = GetValueAsCString ( ) ;
2012-03-20 06:58:49 +08:00
break ;
case eValueObjectRepresentationStyleSummary :
2013-01-26 02:06:21 +08:00
cstr = GetSummaryAsCString ( ) ;
2012-03-20 06:58:49 +08:00
break ;
2011-07-13 06:56:10 +08:00
2012-03-20 06:58:49 +08:00
case eValueObjectRepresentationStyleLanguageSpecific :
2013-01-26 02:06:21 +08:00
cstr = GetObjectDescription ( ) ;
2012-03-20 06:58:49 +08:00
break ;
case eValueObjectRepresentationStyleLocation :
2013-01-26 02:06:21 +08:00
cstr = GetLocationAsCString ( ) ;
2012-03-20 06:58:49 +08:00
break ;
case eValueObjectRepresentationStyleChildrenCount :
2014-03-03 23:39:47 +08:00
strm . Printf ( " % " PRIu64 " " , ( uint64_t ) GetNumChildren ( ) ) ;
2013-01-26 02:06:21 +08:00
cstr = strm . GetString ( ) . c_str ( ) ;
2012-03-20 06:58:49 +08:00
break ;
case eValueObjectRepresentationStyleType :
2013-01-26 02:06:21 +08:00
cstr = GetTypeName ( ) . AsCString ( ) ;
2012-03-20 06:58:49 +08:00
break ;
2013-06-21 08:04:51 +08:00
case eValueObjectRepresentationStyleName :
cstr = GetName ( ) . AsCString ( ) ;
break ;
case eValueObjectRepresentationStyleExpressionPath :
GetExpressionPath ( strm , false ) ;
cstr = strm . GetString ( ) . c_str ( ) ;
break ;
2012-03-20 06:58:49 +08:00
}
2013-01-26 02:06:21 +08:00
if ( ! cstr )
2012-03-20 06:58:49 +08:00
{
if ( val_obj_display = = eValueObjectRepresentationStyleValue )
2013-01-26 02:06:21 +08:00
cstr = GetSummaryAsCString ( ) ;
2012-03-20 06:58:49 +08:00
else if ( val_obj_display = = eValueObjectRepresentationStyleSummary )
{
Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
The way to do this is to write a synthetic child provider for your type, and have it vend the (optional) get_value function.
If get_value is defined, and it returns a valid SBValue, that SBValue's value (as in lldb_private::Value) will be used as the synthetic ValueObject's Value
The rationale for doing things this way is twofold:
- there are many possible ways to define a "value" (SBData, a Python number, ...) but SBValue seems general enough as a thing that stores a "value", so we just trade values that way and that keeps our currency trivial
- we could introduce a new level of layering (ValueObjectSyntheticValue), a new kind of formatter (synthetic value producer), but that would complicate the model (can I have a dynamic with no synthetic children but synthetic value? synthetic value with synthetic children but no dynamic?), and I really couldn't see much benefit to be reaped from this added complexity in the matrix
On the other hand, just defining a synthetic child provider with a get_value but returning no actual children is easy enough that it's not a significant road-block to adoption of this feature
Comes with a test case
llvm-svn: 219330
2014-10-09 02:27:36 +08:00
if ( ! CanProvideValue ( ) )
2011-07-13 06:56:10 +08:00
{
2013-01-26 02:06:21 +08:00
strm . Printf ( " %s @ %s " , GetTypeName ( ) . AsCString ( ) , GetLocationAsCString ( ) ) ;
cstr = strm . GetString ( ) . c_str ( ) ;
2012-03-20 06:58:49 +08:00
}
else
2013-01-26 02:06:21 +08:00
cstr = GetValueAsCString ( ) ;
2011-07-13 06:56:10 +08:00
}
}
2013-01-26 02:06:21 +08:00
if ( cstr )
s . PutCString ( cstr ) ;
2012-03-20 06:58:49 +08:00
else
{
if ( m_error . Fail ( ) )
2014-01-08 09:36:59 +08:00
{
if ( do_dump_error )
s . Printf ( " <%s> " , m_error . AsCString ( ) ) ;
else
return false ;
}
2012-03-20 06:58:49 +08:00
else if ( val_obj_display = = eValueObjectRepresentationStyleSummary )
s . PutCString ( " <no summary available> " ) ;
else if ( val_obj_display = = eValueObjectRepresentationStyleValue )
s . PutCString ( " <no value available> " ) ;
else if ( val_obj_display = = eValueObjectRepresentationStyleLanguageSpecific )
s . PutCString ( " <not a valid Objective-C object> " ) ; // edit this if we have other runtimes that support a description
else
s . PutCString ( " <no printable representation> " ) ;
}
// we should only return false here if we could not do *anything*
// even if we have an error message as output, that's a success
// from our callers' perspective, so return true
var_success = true ;
2014-02-15 09:24:44 +08:00
if ( custom_format ! = eFormatInvalid )
SetFormat ( eFormatDefault ) ;
2011-07-12 08:18:11 +08:00
}
2011-08-19 00:38:26 +08:00
2011-07-13 06:56:10 +08:00
return var_success ;
2011-07-02 08:25:22 +08:00
}
2010-10-27 11:32:59 +08:00
addr_t
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
ValueObject : : GetAddressOf ( bool scalar_is_load_address , AddressType * address_type )
2010-10-27 11:32:59 +08:00
{
2011-08-03 01:27:39 +08:00
if ( ! UpdateValueIfNeeded ( false ) )
2011-04-16 08:01:13 +08:00
return LLDB_INVALID_ADDRESS ;
2010-10-27 11:32:59 +08:00
switch ( m_value . GetValueType ( ) )
{
case Value : : eValueTypeScalar :
2012-10-31 02:18:43 +08:00
case Value : : eValueTypeVector :
2010-10-27 11:32:59 +08:00
if ( scalar_is_load_address )
{
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
if ( address_type )
* address_type = eAddressTypeLoad ;
2010-10-27 11:32:59 +08:00
return m_value . GetScalar ( ) . ULongLong ( LLDB_INVALID_ADDRESS ) ;
}
break ;
case Value : : eValueTypeLoadAddress :
case Value : : eValueTypeFileAddress :
{
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
if ( address_type )
* address_type = m_value . GetValueAddressType ( ) ;
2010-10-27 11:32:59 +08:00
return m_value . GetScalar ( ) . ULongLong ( LLDB_INVALID_ADDRESS ) ;
}
break ;
2015-05-05 03:43:34 +08:00
case Value : : eValueTypeHostAddress :
2015-05-05 08:41:35 +08:00
{
if ( address_type )
* address_type = m_value . GetValueAddressType ( ) ;
return LLDB_INVALID_ADDRESS ;
}
2015-05-05 03:43:34 +08:00
break ;
2010-10-27 11:32:59 +08:00
}
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
if ( address_type )
* address_type = eAddressTypeInvalid ;
2010-10-27 11:32:59 +08:00
return LLDB_INVALID_ADDRESS ;
}
2010-09-13 11:32:57 +08:00
addr_t
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
ValueObject : : GetPointerValue ( AddressType * address_type )
2010-09-13 11:32:57 +08:00
{
2011-09-02 09:15:17 +08:00
addr_t address = LLDB_INVALID_ADDRESS ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
if ( address_type )
* address_type = eAddressTypeInvalid ;
2011-04-16 08:01:13 +08:00
2011-08-03 01:27:39 +08:00
if ( ! UpdateValueIfNeeded ( false ) )
2011-04-16 08:01:13 +08:00
return address ;
2010-10-27 11:32:59 +08:00
switch ( m_value . GetValueType ( ) )
2010-09-13 11:32:57 +08:00
{
case Value : : eValueTypeScalar :
2012-10-31 02:18:43 +08:00
case Value : : eValueTypeVector :
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
address = m_value . GetScalar ( ) . ULongLong ( LLDB_INVALID_ADDRESS ) ;
2010-09-13 11:32:57 +08:00
break ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
case Value : : eValueTypeHostAddress :
2010-09-13 11:32:57 +08:00
case Value : : eValueTypeLoadAddress :
case Value : : eValueTypeFileAddress :
{
2013-01-26 02:06:21 +08:00
lldb : : offset_t data_offset = 0 ;
2010-09-13 11:32:57 +08:00
address = m_data . GetPointer ( & data_offset ) ;
}
break ;
}
2010-12-14 10:59:59 +08:00
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
if ( address_type )
* address_type = GetAddressTypeOfChildren ( ) ;
2010-12-14 10:59:59 +08:00
2010-09-13 11:32:57 +08:00
return address ;
}
2010-06-09 00:52:24 +08:00
bool
2012-05-09 05:25:06 +08:00
ValueObject : : SetValueFromCString ( const char * value_str , Error & error )
2010-06-09 00:52:24 +08:00
{
2012-05-09 05:25:06 +08:00
error . Clear ( ) ;
2010-06-09 00:52:24 +08:00
// Make sure our value is up to date first so that our location and location
// type is valid.
2011-08-03 01:27:39 +08:00
if ( ! UpdateValueIfNeeded ( false ) )
2012-05-09 05:25:06 +08:00
{
error . SetErrorString ( " unable to read value " ) ;
2010-06-09 00:52:24 +08:00
return false ;
2012-05-09 05:25:06 +08:00
}
2010-06-09 00:52:24 +08:00
2013-03-15 02:31:44 +08:00
uint64_t count = 0 ;
2013-07-12 06:46:58 +08:00
const Encoding encoding = GetClangType ( ) . GetEncoding ( count ) ;
2010-06-09 00:52:24 +08:00
2010-07-14 08:18:15 +08:00
const size_t byte_size = GetByteSize ( ) ;
2010-06-09 00:52:24 +08:00
2011-08-13 07:34:31 +08:00
Value : : ValueType value_type = m_value . GetValueType ( ) ;
if ( value_type = = Value : : eValueTypeScalar )
{
// If the value is already a scalar, then let the scalar change itself:
m_value . GetScalar ( ) . SetValueFromCString ( value_str , encoding , byte_size ) ;
}
else if ( byte_size < = Scalar : : GetMaxByteSize ( ) )
{
// If the value fits in a scalar, then make a new scalar and again let the
// scalar code do the conversion, then figure out where to put the new value.
Scalar new_scalar ;
error = new_scalar . SetValueFromCString ( value_str , encoding , byte_size ) ;
if ( error . Success ( ) )
2010-06-09 00:52:24 +08:00
{
2011-08-09 10:12:22 +08:00
switch ( value_type )
{
2012-02-17 15:49:44 +08:00
case Value : : eValueTypeLoadAddress :
2011-08-13 07:34:31 +08:00
{
// If it is a load address, then the scalar value is the storage location
// of the data, and we have to shove this value down to that load location.
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
Process * process = exe_ctx . GetProcessPtr ( ) ;
if ( process )
2011-08-13 07:34:31 +08:00
{
2012-10-25 04:24:39 +08:00
addr_t target_addr = m_value . GetScalar ( ) . ULongLong ( LLDB_INVALID_ADDRESS ) ;
2012-02-17 15:49:44 +08:00
size_t bytes_written = process - > WriteScalarToMemory ( target_addr ,
new_scalar ,
byte_size ,
error ) ;
2012-05-09 05:25:06 +08:00
if ( ! error . Success ( ) )
return false ;
if ( bytes_written ! = byte_size )
{
error . SetErrorString ( " unable to write value to memory " ) ;
return false ;
}
2011-08-13 07:34:31 +08:00
}
}
2011-08-09 10:12:22 +08:00
break ;
2012-02-17 15:49:44 +08:00
case Value : : eValueTypeHostAddress :
2011-08-13 07:34:31 +08:00
{
// If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
DataExtractor new_data ;
new_data . SetByteOrder ( m_data . GetByteOrder ( ) ) ;
DataBufferSP buffer_sp ( new DataBufferHeap ( byte_size , 0 ) ) ;
m_data . SetData ( buffer_sp , 0 ) ;
bool success = new_scalar . GetData ( new_data ) ;
if ( success )
{
2012-02-17 15:49:44 +08:00
new_data . CopyByteOrderedData ( 0 ,
byte_size ,
const_cast < uint8_t * > ( m_data . GetDataStart ( ) ) ,
byte_size ,
m_data . GetByteOrder ( ) ) ;
2011-08-13 07:34:31 +08:00
}
m_value . GetScalar ( ) = ( uintptr_t ) m_data . GetDataStart ( ) ;
}
2011-08-09 10:12:22 +08:00
break ;
2012-02-17 15:49:44 +08:00
case Value : : eValueTypeFileAddress :
case Value : : eValueTypeScalar :
2012-10-31 02:18:43 +08:00
case Value : : eValueTypeVector :
break ;
2011-08-09 10:12:22 +08:00
}
2010-06-09 00:52:24 +08:00
}
else
{
2011-08-13 07:34:31 +08:00
return false ;
2010-06-09 00:52:24 +08:00
}
2011-08-13 07:34:31 +08:00
}
else
{
// We don't support setting things bigger than a scalar at present.
2012-05-09 05:25:06 +08:00
error . SetErrorString ( " unable to write aggregate data type " ) ;
2010-06-09 00:52:24 +08:00
return false ;
}
2011-08-13 07:34:31 +08:00
// If we have reached this point, then we have successfully changed the value.
SetNeedsUpdate ( ) ;
return true ;
2010-06-09 00:52:24 +08:00
}
2012-02-04 10:27:34 +08:00
bool
ValueObject : : GetDeclaration ( Declaration & decl )
{
decl . Clear ( ) ;
return false ;
}
2012-03-27 07:03:23 +08:00
ConstString
ValueObject : : GetTypeName ( )
{
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . GetConstTypeName ( ) ;
2012-03-27 07:03:23 +08:00
}
Introduce the concept of a "display name" for types
Rationale:
Pretty simply, the idea is that sometimes type names are way too long and contain way too many details for the average developer to care about. For instance, a plain ol' vector of int might be shown as
std::__1::vector<int, std::__1::allocator<....
rather than the much simpler std::vector<int> form, which is what most developers would actually type in their code
Proposed solution:
Introduce a notion of "display name" and a corresponding API GetDisplayTypeName() to return such a crafted for visual representation type name
Obviously, the display name and the fully qualified (or "true") name are not necessarily the same - that's the whole point
LLDB could choose to pick the "display name" as its one true notion of a type name, and if somebody really needs the fully qualified version of it, let them deal with the problem
Or, LLDB could rename what it currently calls the "type name" to be the "display name", and add new APIs for the fully qualified name, making the display name the default choice
The choice that I am making here is that the type name will keep meaning the same, and people who want a type name suited for display will explicitly ask for one
It is the less risky/disruptive choice - and it should eventually make it fairly obvious when someone is asking for the wrong type
Caveats:
- for now, GetDisplayTypeName() == GetTypeName(), there is no logic to produce customized display type names yet.
- while the fully-qualified type name is still the main key to the kingdom of data formatters, if we start showing custom names to people, those should match formatters
llvm-svn: 209072
2014-05-18 03:14:17 +08:00
ConstString
ValueObject : : GetDisplayTypeName ( )
{
return GetTypeName ( ) ;
}
2012-03-27 07:03:23 +08:00
ConstString
ValueObject : : GetQualifiedTypeName ( )
{
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . GetConstQualifiedTypeName ( ) ;
2012-03-27 07:03:23 +08:00
}
2011-09-02 09:15:17 +08:00
LanguageType
2010-09-28 09:25:32 +08:00
ValueObject : : GetObjectRuntimeLanguage ( )
{
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . GetMinimumLanguage ( ) ;
2010-09-28 09:25:32 +08:00
}
2010-06-09 00:52:24 +08:00
void
2011-04-23 07:53:53 +08:00
ValueObject : : AddSyntheticChild ( const ConstString & key , ValueObject * valobj )
2010-06-09 00:52:24 +08:00
{
2011-04-23 07:53:53 +08:00
m_synthetic_children [ key ] = valobj ;
2010-06-09 00:52:24 +08:00
}
ValueObjectSP
ValueObject : : GetSyntheticChild ( const ConstString & key ) const
{
ValueObjectSP synthetic_child_sp ;
2011-04-23 07:53:53 +08:00
std : : map < ConstString , ValueObject * > : : const_iterator pos = m_synthetic_children . find ( key ) ;
2010-06-09 00:52:24 +08:00
if ( pos ! = m_synthetic_children . end ( ) )
2011-04-23 07:53:53 +08:00
synthetic_child_sp = pos - > second - > GetSP ( ) ;
2010-06-09 00:52:24 +08:00
return synthetic_child_sp ;
}
2013-02-09 06:02:02 +08:00
uint32_t
2013-07-12 06:46:58 +08:00
ValueObject : : GetTypeInfo ( ClangASTType * pointee_or_element_clang_type )
2013-02-09 06:02:02 +08:00
{
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . GetTypeInfo ( pointee_or_element_clang_type ) ;
2013-02-09 06:02:02 +08:00
}
2010-06-09 00:52:24 +08:00
bool
ValueObject : : IsPointerType ( )
{
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . IsPointerType ( ) ;
2010-06-09 00:52:24 +08:00
}
2011-07-10 04:12:33 +08:00
bool
ValueObject : : IsArrayType ( )
{
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . IsArrayType ( NULL , NULL , NULL ) ;
2011-07-10 04:12:33 +08:00
}
2011-07-06 10:13:41 +08:00
bool
ValueObject : : IsScalarType ( )
{
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . IsScalarType ( ) ;
2011-07-06 10:13:41 +08:00
}
2011-03-18 08:05:18 +08:00
bool
ValueObject : : IsIntegerType ( bool & is_signed )
{
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . IsIntegerType ( is_signed ) ;
2011-03-18 08:05:18 +08:00
}
2010-10-27 11:32:59 +08:00
2010-06-09 00:52:24 +08:00
bool
ValueObject : : IsPointerOrReferenceType ( )
{
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . IsPointerOrReferenceType ( ) ;
2011-05-30 08:49:24 +08:00
}
2011-06-30 06:09:02 +08:00
bool
ValueObject : : IsPossibleDynamicType ( )
{
2012-05-22 00:51:35 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
Process * process = exe_ctx . GetProcessPtr ( ) ;
if ( process )
return process - > IsPossibleDynamicValue ( * this ) ;
else
2013-07-12 06:46:58 +08:00
return GetClangType ( ) . IsPossibleDynamicType ( NULL , true , true ) ;
2011-06-30 06:09:02 +08:00
}
2015-02-11 10:35:39 +08:00
bool
ValueObject : : IsRuntimeSupportValue ( )
{
Process * process ( GetProcessSP ( ) . get ( ) ) ;
if ( process )
{
LanguageRuntime * runtime = process - > GetLanguageRuntime ( GetObjectRuntimeLanguage ( ) ) ;
if ( ! runtime )
runtime = process - > GetObjCLanguageRuntime ( ) ;
if ( runtime )
return runtime - > IsRuntimeSupportValue ( * this ) ;
}
return false ;
}
2012-12-14 07:50:33 +08:00
bool
ValueObject : : IsObjCNil ( )
{
2014-10-22 04:52:14 +08:00
const uint32_t mask = eTypeIsObjC | eTypeIsPointer ;
2013-07-12 06:46:58 +08:00
bool isObjCpointer = ( ( ( GetClangType ( ) . GetTypeInfo ( NULL ) ) & mask ) = = mask ) ;
2013-03-16 07:33:15 +08:00
if ( ! isObjCpointer )
return false ;
2012-12-14 07:50:33 +08:00
bool canReadValue = true ;
bool isZero = GetValueAsUnsigned ( 0 , & canReadValue ) = = 0 ;
2013-03-16 07:33:15 +08:00
return canReadValue & & isZero ;
2012-12-14 07:50:33 +08:00
}
2011-07-10 04:12:33 +08:00
// This allows you to create an array member using and index
// that doesn't not fall in the normal bounds of the array.
// Many times structure can be defined as:
// struct Collection
// {
// uint32_t item_count;
// Item item_array[0];
// };
// The size of the "item_array" is 1, but many times in practice
// there are more items in "item_array".
ValueObjectSP
2015-02-27 07:55:39 +08:00
ValueObject : : GetSyntheticArrayMember ( size_t index , bool can_create )
2011-07-10 04:12:33 +08:00
{
ValueObjectSP synthetic_child_sp ;
2015-02-27 07:55:39 +08:00
if ( IsPointerType ( ) | | IsArrayType ( ) )
2011-07-10 04:12:33 +08:00
{
char index_str [ 64 ] ;
2014-03-03 23:39:47 +08:00
snprintf ( index_str , sizeof ( index_str ) , " [% " PRIu64 " ] " , ( uint64_t ) index ) ;
2011-07-10 04:12:33 +08:00
ConstString index_const_str ( index_str ) ;
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
synthetic_child_sp = GetSyntheticChild ( index_const_str ) ;
if ( ! synthetic_child_sp )
{
ValueObject * synthetic_child ;
// We haven't made a synthetic array member for INDEX yet, so
// lets make one and cache it for any future reference.
synthetic_child = CreateChildAtIndex ( 0 , true , index ) ;
2015-02-27 07:55:39 +08:00
2011-07-10 04:12:33 +08:00
// Cache the value if we got one back...
if ( synthetic_child )
{
AddSyntheticChild ( index_const_str , synthetic_child ) ;
synthetic_child_sp = synthetic_child - > GetSP ( ) ;
2011-07-30 03:53:35 +08:00
synthetic_child_sp - > SetName ( ConstString ( index_str ) ) ;
2011-07-10 04:12:33 +08:00
synthetic_child_sp - > m_is_array_item_for_pointer = true ;
}
}
}
return synthetic_child_sp ;
}
2011-07-06 10:13:41 +08:00
ValueObjectSP
ValueObject : : GetSyntheticBitFieldChild ( uint32_t from , uint32_t to , bool can_create )
{
ValueObjectSP synthetic_child_sp ;
if ( IsScalarType ( ) )
{
char index_str [ 64 ] ;
snprintf ( index_str , sizeof ( index_str ) , " [%i-%i] " , from , to ) ;
ConstString index_const_str ( index_str ) ;
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
synthetic_child_sp = GetSyntheticChild ( index_const_str ) ;
if ( ! synthetic_child_sp )
{
// We haven't made a synthetic array member for INDEX yet, so
// lets make one and cache it for any future reference.
2013-07-12 06:46:58 +08:00
ValueObjectChild * synthetic_child = new ValueObjectChild ( * this ,
GetClangType ( ) ,
index_const_str ,
GetByteSize ( ) ,
0 ,
to - from + 1 ,
from ,
false ,
false ,
eAddressTypeInvalid ) ;
2011-07-06 10:13:41 +08:00
// Cache the value if we got one back...
if ( synthetic_child )
{
AddSyntheticChild ( index_const_str , synthetic_child ) ;
synthetic_child_sp = synthetic_child - > GetSP ( ) ;
2011-07-30 03:53:35 +08:00
synthetic_child_sp - > SetName ( ConstString ( index_str ) ) ;
2011-07-06 10:13:41 +08:00
synthetic_child_sp - > m_is_bitfield_for_scalar = true ;
}
}
}
return synthetic_child_sp ;
2011-08-20 05:13:46 +08:00
}
2011-09-02 09:15:17 +08:00
ValueObjectSP
2011-07-30 03:53:35 +08:00
ValueObject : : GetSyntheticChildAtOffset ( uint32_t offset , const ClangASTType & type , bool can_create )
{
ValueObjectSP synthetic_child_sp ;
char name_str [ 64 ] ;
snprintf ( name_str , sizeof ( name_str ) , " @%i " , offset ) ;
ConstString name_const_str ( name_str ) ;
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
synthetic_child_sp = GetSyntheticChild ( name_const_str ) ;
if ( synthetic_child_sp . get ( ) )
return synthetic_child_sp ;
if ( ! can_create )
2011-09-02 09:15:17 +08:00
return ValueObjectSP ( ) ;
2011-07-30 03:53:35 +08:00
2015-01-28 09:09:45 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
2011-07-30 03:53:35 +08:00
ValueObjectChild * synthetic_child = new ValueObjectChild ( * this ,
2013-07-12 06:46:58 +08:00
type ,
2011-07-30 03:53:35 +08:00
name_const_str ,
2015-02-12 08:34:25 +08:00
type . GetByteSize ( exe_ctx . GetBestExecutionContextScope ( ) ) ,
2011-07-30 03:53:35 +08:00
offset ,
0 ,
0 ,
false ,
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
false ,
eAddressTypeInvalid ) ;
2011-07-30 03:53:35 +08:00
if ( synthetic_child )
{
AddSyntheticChild ( name_const_str , synthetic_child ) ;
synthetic_child_sp = synthetic_child - > GetSP ( ) ;
synthetic_child_sp - > SetName ( name_const_str ) ;
synthetic_child_sp - > m_is_child_at_offset = true ;
}
return synthetic_child_sp ;
}
2014-08-27 04:54:04 +08:00
ValueObjectSP
2014-08-27 05:35:30 +08:00
ValueObject : : GetSyntheticBase ( uint32_t offset , const ClangASTType & type , bool can_create )
2014-08-27 04:54:04 +08:00
{
ValueObjectSP synthetic_child_sp ;
char name_str [ 64 ] ;
snprintf ( name_str , sizeof ( name_str ) , " %s " , type . GetTypeName ( ) . AsCString ( " <unknown> " ) ) ;
ConstString name_const_str ( name_str ) ;
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
synthetic_child_sp = GetSyntheticChild ( name_const_str ) ;
if ( synthetic_child_sp . get ( ) )
return synthetic_child_sp ;
if ( ! can_create )
return ValueObjectSP ( ) ;
const bool is_base_class = true ;
2015-01-28 09:09:45 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
2014-08-27 04:54:04 +08:00
ValueObjectChild * synthetic_child = new ValueObjectChild ( * this ,
type ,
name_const_str ,
2015-02-12 08:34:25 +08:00
type . GetByteSize ( exe_ctx . GetBestExecutionContextScope ( ) ) ,
2014-08-27 04:54:04 +08:00
offset ,
0 ,
0 ,
is_base_class ,
false ,
eAddressTypeInvalid ) ;
if ( synthetic_child )
{
AddSyntheticChild ( name_const_str , synthetic_child ) ;
synthetic_child_sp = synthetic_child - > GetSP ( ) ;
synthetic_child_sp - > SetName ( name_const_str ) ;
}
return synthetic_child_sp ;
}
2011-07-22 08:16:08 +08:00
// your expression path needs to have a leading . or ->
// (unless it somehow "looks like" an array, in which case it has
// a leading [ symbol). while the [ is meaningful and should be shown
// to the user, . and -> are just parser design, but by no means
// added information for the user.. strip them off
static const char *
SkipLeadingExpressionPathSeparators ( const char * expression )
{
if ( ! expression | | ! expression [ 0 ] )
return expression ;
if ( expression [ 0 ] = = ' . ' )
return expression + 1 ;
if ( expression [ 0 ] = = ' - ' & & expression [ 1 ] = = ' > ' )
return expression + 2 ;
return expression ;
}
2011-09-02 09:15:17 +08:00
ValueObjectSP
2011-07-22 08:16:08 +08:00
ValueObject : : GetSyntheticExpressionPathChild ( const char * expression , bool can_create )
{
ValueObjectSP synthetic_child_sp ;
ConstString name_const_string ( expression ) ;
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
synthetic_child_sp = GetSyntheticChild ( name_const_string ) ;
if ( ! synthetic_child_sp )
{
// We haven't made a synthetic array member for expression yet, so
// lets make one and cache it for any future reference.
2012-08-03 01:34:05 +08:00
synthetic_child_sp = GetValueForExpressionPath ( expression ,
NULL , NULL , NULL ,
2015-03-13 06:30:58 +08:00
GetValueForExpressionPathOptions ( ) . SetSyntheticChildrenTraversal ( GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : None ) ) ;
2011-07-22 08:16:08 +08:00
// Cache the value if we got one back...
if ( synthetic_child_sp . get ( ) )
{
2013-02-22 03:57:10 +08:00
// FIXME: this causes a "real" child to end up with its name changed to the contents of expression
2011-07-22 08:16:08 +08:00
AddSyntheticChild ( name_const_string , synthetic_child_sp . get ( ) ) ;
2011-07-30 03:53:35 +08:00
synthetic_child_sp - > SetName ( ConstString ( SkipLeadingExpressionPathSeparators ( expression ) ) ) ;
2011-07-22 08:16:08 +08:00
}
}
return synthetic_child_sp ;
}
void
2012-03-20 06:58:49 +08:00
ValueObject : : CalculateSyntheticValue ( bool use_synthetic )
2011-07-22 08:16:08 +08:00
{
2012-03-20 06:58:49 +08:00
if ( use_synthetic = = false )
2011-07-22 08:16:08 +08:00
return ;
2012-03-27 10:35:13 +08:00
TargetSP target_sp ( GetTargetSP ( ) ) ;
2013-09-25 06:58:37 +08:00
if ( target_sp & & target_sp - > GetEnableSyntheticValue ( ) = = false )
2012-03-27 10:35:13 +08:00
{
m_synthetic_value = NULL ;
return ;
}
2012-10-23 02:18:36 +08:00
lldb : : SyntheticChildrenSP current_synth_sp ( m_synthetic_children_sp ) ;
2013-01-29 07:47:25 +08:00
if ( ! UpdateFormatsIfNeeded ( ) & & m_synthetic_value )
2012-03-20 06:58:49 +08:00
return ;
2011-07-22 08:16:08 +08:00
2012-03-01 12:24:26 +08:00
if ( m_synthetic_children_sp . get ( ) = = NULL )
2011-07-22 08:16:08 +08:00
return ;
2012-10-23 02:18:36 +08:00
if ( current_synth_sp = = m_synthetic_children_sp & & m_synthetic_value )
return ;
2012-03-20 06:58:49 +08:00
m_synthetic_value = new ValueObjectSynthetic ( * this , m_synthetic_children_sp ) ;
2011-07-22 08:16:08 +08:00
}
2011-04-16 08:01:13 +08:00
void
2011-09-02 09:15:17 +08:00
ValueObject : : CalculateDynamicValue ( DynamicValueType use_dynamic )
2010-09-23 10:01:19 +08:00
{
2011-09-02 09:15:17 +08:00
if ( use_dynamic = = eNoDynamicValues )
2011-05-04 11:43:18 +08:00
return ;
2011-04-23 07:53:53 +08:00
if ( ! m_dynamic_value & & ! IsDynamic ( ) )
2011-04-16 08:01:13 +08:00
{
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
Process * process = exe_ctx . GetProcessPtr ( ) ;
2012-05-22 00:51:35 +08:00
if ( process & & process - > IsPossibleDynamicValue ( * this ) )
2012-10-23 02:18:36 +08:00
{
ClearDynamicTypeInformation ( ) ;
2012-05-22 00:51:35 +08:00
m_dynamic_value = new ValueObjectDynamicValue ( * this , use_dynamic ) ;
2012-10-23 02:18:36 +08:00
}
2011-04-16 08:01:13 +08:00
}
}
2011-04-23 07:53:53 +08:00
ValueObjectSP
2011-05-04 11:43:18 +08:00
ValueObject : : GetDynamicValue ( DynamicValueType use_dynamic )
2011-04-16 08:01:13 +08:00
{
2011-09-02 09:15:17 +08:00
if ( use_dynamic = = eNoDynamicValues )
2011-05-04 11:43:18 +08:00
return ValueObjectSP ( ) ;
if ( ! IsDynamic ( ) & & m_dynamic_value = = NULL )
2011-04-16 08:01:13 +08:00
{
2011-05-04 11:43:18 +08:00
CalculateDynamicValue ( use_dynamic ) ;
2011-04-16 08:01:13 +08:00
}
2011-04-23 07:53:53 +08:00
if ( m_dynamic_value )
return m_dynamic_value - > GetSP ( ) ;
else
return ValueObjectSP ( ) ;
2010-09-23 10:01:19 +08:00
}
2010-10-05 08:00:42 +08:00
2011-12-09 03:44:08 +08:00
ValueObjectSP
ValueObject : : GetStaticValue ( )
{
return GetSP ( ) ;
}
2012-05-09 02:47:08 +08:00
lldb : : ValueObjectSP
ValueObject : : GetNonSyntheticValue ( )
{
return GetSP ( ) ;
}
2011-07-22 08:16:08 +08:00
ValueObjectSP
2012-03-20 06:58:49 +08:00
ValueObject : : GetSyntheticValue ( bool use_synthetic )
2011-07-22 08:16:08 +08:00
{
2012-03-20 06:58:49 +08:00
if ( use_synthetic = = false )
return ValueObjectSP ( ) ;
2011-07-22 08:16:08 +08:00
CalculateSyntheticValue ( use_synthetic ) ;
if ( m_synthetic_value )
return m_synthetic_value - > GetSP ( ) ;
else
2012-03-20 06:58:49 +08:00
return ValueObjectSP ( ) ;
2011-07-22 08:16:08 +08:00
}
2011-08-09 09:04:56 +08:00
bool
ValueObject : : HasSyntheticValue ( )
{
2013-01-29 07:47:25 +08:00
UpdateFormatsIfNeeded ( ) ;
2011-08-09 09:04:56 +08:00
2012-03-01 12:24:26 +08:00
if ( m_synthetic_children_sp . get ( ) = = NULL )
2011-08-09 09:04:56 +08:00
return false ;
2012-03-20 06:58:49 +08:00
CalculateSyntheticValue ( true ) ;
2011-08-09 09:04:56 +08:00
if ( m_synthetic_value )
return true ;
else
return false ;
}
2011-01-21 09:59:00 +08:00
bool
ValueObject : : GetBaseClassPath ( Stream & s )
{
if ( IsBaseClass ( ) )
{
2011-04-16 08:01:13 +08:00
bool parent_had_base_class = GetParent ( ) & & GetParent ( ) - > GetBaseClassPath ( s ) ;
2013-07-12 06:46:58 +08:00
ClangASTType clang_type = GetClangType ( ) ;
2011-01-21 09:59:00 +08:00
std : : string cxx_class_name ;
2013-07-12 06:46:58 +08:00
bool this_had_base_class = clang_type . GetCXXClassName ( cxx_class_name ) ;
2011-01-21 09:59:00 +08:00
if ( this_had_base_class )
{
if ( parent_had_base_class )
s . PutCString ( " :: " ) ;
s . PutCString ( cxx_class_name . c_str ( ) ) ;
}
return parent_had_base_class | | this_had_base_class ;
}
return false ;
}
ValueObject *
ValueObject : : GetNonBaseClassParent ( )
{
2011-04-16 08:01:13 +08:00
if ( GetParent ( ) )
2011-01-21 09:59:00 +08:00
{
2011-04-16 08:01:13 +08:00
if ( GetParent ( ) - > IsBaseClass ( ) )
return GetParent ( ) - > GetNonBaseClassParent ( ) ;
2011-01-21 09:59:00 +08:00
else
2011-04-16 08:01:13 +08:00
return GetParent ( ) ;
2011-01-21 09:59:00 +08:00
}
return NULL ;
}
2010-10-05 08:00:42 +08:00
2014-08-20 06:29:08 +08:00
bool
ValueObject : : IsBaseClass ( uint32_t & depth )
{
if ( ! IsBaseClass ( ) )
{
depth = 0 ;
return false ;
}
if ( GetParent ( ) )
{
GetParent ( ) - > IsBaseClass ( depth ) ;
depth = depth + 1 ;
return true ;
}
// TODO: a base of no parent? weird..
depth = 1 ;
return true ;
}
2010-10-15 06:52:14 +08:00
void
2011-06-30 06:27:15 +08:00
ValueObject : : GetExpressionPath ( Stream & s , bool qualify_cxx_base_classes , GetExpressionPathFormat epformat )
2010-10-15 06:52:14 +08:00
{
2014-12-10 05:41:16 +08:00
// synthetic children do not actually "exist" as part of the hierarchy, and sometimes they are consed up in ways
// that don't make sense from an underlying language/API standpoint. So, use a special code path here to return
// something that can hopefully be used in expression
if ( m_is_synthetic_children_generated )
{
UpdateValueIfNeeded ( ) ;
if ( m_value . GetValueType ( ) = = Value : : eValueTypeLoadAddress )
{
if ( IsPointerOrReferenceType ( ) )
{
s . Printf ( " ((%s)0x% " PRIx64 " ) " ,
GetTypeName ( ) . AsCString ( " void " ) ,
GetValueAsUnsigned ( 0 ) ) ;
return ;
}
else
{
uint64_t load_addr = m_value . GetScalar ( ) . ULongLong ( LLDB_INVALID_ADDRESS ) ;
if ( load_addr ! = LLDB_INVALID_ADDRESS )
{
s . Printf ( " (*( (%s *)0x% " PRIx64 " )) " ,
GetTypeName ( ) . AsCString ( " void " ) ,
load_addr ) ;
return ;
}
}
}
if ( CanProvideValue ( ) )
{
s . Printf ( " ((%s)%s) " ,
GetTypeName ( ) . AsCString ( " void " ) ,
GetValueAsCString ( ) ) ;
return ;
}
return ;
}
2011-01-21 09:59:00 +08:00
const bool is_deref_of_parent = IsDereferenceOfParent ( ) ;
2012-03-20 06:58:49 +08:00
if ( is_deref_of_parent & & epformat = = eGetExpressionPathFormatDereferencePointers )
2011-08-19 00:38:26 +08:00
{
2011-06-30 06:27:15 +08:00
// this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
// fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
// the eHonorPointers mode is meant to produce strings in this latter format
s . PutCString ( " *( " ) ;
}
2011-01-21 09:59:00 +08:00
2011-06-30 06:27:15 +08:00
ValueObject * parent = GetParent ( ) ;
if ( parent )
parent - > GetExpressionPath ( s , qualify_cxx_base_classes , epformat ) ;
2011-07-02 08:25:22 +08:00
// if we are a deref_of_parent just because we are synthetic array
// members made up to allow ptr[%d] syntax to work in variable
// printing, then add our name ([%d]) to the expression path
2012-03-20 06:58:49 +08:00
if ( m_is_array_item_for_pointer & & epformat = = eGetExpressionPathFormatHonorPointers )
2011-07-02 08:25:22 +08:00
s . PutCString ( m_name . AsCString ( ) ) ;
2011-06-30 06:27:15 +08:00
2011-01-21 09:59:00 +08:00
if ( ! IsBaseClass ( ) )
{
if ( ! is_deref_of_parent )
2010-10-15 06:52:14 +08:00
{
2011-01-21 09:59:00 +08:00
ValueObject * non_base_class_parent = GetNonBaseClassParent ( ) ;
if ( non_base_class_parent )
2010-10-15 06:52:14 +08:00
{
2013-07-12 06:46:58 +08:00
ClangASTType non_base_class_parent_clang_type = non_base_class_parent - > GetClangType ( ) ;
2011-01-21 09:59:00 +08:00
if ( non_base_class_parent_clang_type )
{
2012-03-20 06:58:49 +08:00
if ( parent & & parent - > IsDereferenceOfParent ( ) & & epformat = = eGetExpressionPathFormatHonorPointers )
2011-01-21 09:59:00 +08:00
{
s . PutCString ( " -> " ) ;
}
2011-06-30 06:27:15 +08:00
else
{
2013-07-12 06:46:58 +08:00
const uint32_t non_base_class_parent_type_info = non_base_class_parent_clang_type . GetTypeInfo ( ) ;
2014-10-22 04:52:14 +08:00
if ( non_base_class_parent_type_info & eTypeIsPointer )
2011-06-30 06:27:15 +08:00
{
s . PutCString ( " -> " ) ;
}
2014-10-22 04:52:14 +08:00
else if ( ( non_base_class_parent_type_info & eTypeHasChildren ) & &
! ( non_base_class_parent_type_info & eTypeIsArray ) )
2011-06-30 06:27:15 +08:00
{
s . PutChar ( ' . ' ) ;
}
2011-01-21 09:59:00 +08:00
}
}
2010-10-15 06:52:14 +08:00
}
2011-01-21 09:59:00 +08:00
const char * name = GetName ( ) . GetCString ( ) ;
if ( name )
2010-10-15 06:52:14 +08:00
{
2011-01-21 09:59:00 +08:00
if ( qualify_cxx_base_classes )
{
if ( GetBaseClassPath ( s ) )
s . PutCString ( " :: " ) ;
}
s . PutCString ( name ) ;
2010-10-15 06:52:14 +08:00
}
}
}
2012-03-20 06:58:49 +08:00
if ( is_deref_of_parent & & epformat = = eGetExpressionPathFormatDereferencePointers )
2011-08-19 00:38:26 +08:00
{
2011-01-21 09:59:00 +08:00
s . PutChar ( ' ) ' ) ;
2011-06-30 06:27:15 +08:00
}
2010-10-15 06:52:14 +08:00
}
2011-09-02 09:15:17 +08:00
ValueObjectSP
2011-07-08 10:51:01 +08:00
ValueObject : : GetValueForExpressionPath ( const char * expression ,
const char * * first_unparsed ,
ExpressionPathScanEndReason * reason_to_stop ,
ExpressionPathEndResultType * final_value_type ,
const GetValueForExpressionPathOptions & options ,
ExpressionPathAftermath * final_task_on_target )
{
const char * dummy_first_unparsed ;
2013-02-22 03:57:10 +08:00
ExpressionPathScanEndReason dummy_reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnknown ;
ExpressionPathEndResultType dummy_final_value_type = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2012-03-20 06:58:49 +08:00
ExpressionPathAftermath dummy_final_task_on_target = ValueObject : : eExpressionPathAftermathNothing ;
2011-07-08 10:51:01 +08:00
ValueObjectSP ret_val = GetValueForExpressionPath_Impl ( expression ,
first_unparsed ? first_unparsed : & dummy_first_unparsed ,
reason_to_stop ? reason_to_stop : & dummy_reason_to_stop ,
final_value_type ? final_value_type : & dummy_final_value_type ,
options ,
final_task_on_target ? final_task_on_target : & dummy_final_task_on_target ) ;
2012-03-20 06:58:49 +08:00
if ( ! final_task_on_target | | * final_task_on_target = = ValueObject : : eExpressionPathAftermathNothing )
2011-07-08 10:51:01 +08:00
return ret_val ;
2012-03-03 08:45:57 +08:00
2012-03-20 06:58:49 +08:00
if ( ret_val . get ( ) & & ( ( final_value_type ? * final_value_type : dummy_final_value_type ) = = eExpressionPathEndResultTypePlain ) ) // I can only deref and takeaddress of plain objects
2011-07-08 10:51:01 +08:00
{
2012-03-20 06:58:49 +08:00
if ( ( final_task_on_target ? * final_task_on_target : dummy_final_task_on_target ) = = ValueObject : : eExpressionPathAftermathDereference )
2011-07-08 10:51:01 +08:00
{
Error error ;
ValueObjectSP final_value = ret_val - > Dereference ( error ) ;
if ( error . Fail ( ) | | ! final_value . get ( ) )
{
2012-03-03 08:45:57 +08:00
if ( reason_to_stop )
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonDereferencingFailed ;
2012-03-03 08:45:57 +08:00
if ( final_value_type )
2012-03-20 06:58:49 +08:00
* final_value_type = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
else
{
2012-03-03 08:45:57 +08:00
if ( final_task_on_target )
2012-03-20 06:58:49 +08:00
* final_task_on_target = ValueObject : : eExpressionPathAftermathNothing ;
2011-07-08 10:51:01 +08:00
return final_value ;
}
}
2012-03-20 06:58:49 +08:00
if ( * final_task_on_target = = ValueObject : : eExpressionPathAftermathTakeAddress )
2011-07-08 10:51:01 +08:00
{
Error error ;
ValueObjectSP final_value = ret_val - > AddressOf ( error ) ;
if ( error . Fail ( ) | | ! final_value . get ( ) )
{
2012-03-03 08:45:57 +08:00
if ( reason_to_stop )
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonTakingAddressFailed ;
2012-03-03 08:45:57 +08:00
if ( final_value_type )
2012-03-20 06:58:49 +08:00
* final_value_type = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
else
{
2012-03-03 08:45:57 +08:00
if ( final_task_on_target )
2012-03-20 06:58:49 +08:00
* final_task_on_target = ValueObject : : eExpressionPathAftermathNothing ;
2011-07-08 10:51:01 +08:00
return final_value ;
}
}
}
return ret_val ; // final_task_on_target will still have its original value, so you know I did not do it
}
2011-07-12 08:18:11 +08:00
int
ValueObject : : GetValuesForExpressionPath ( const char * expression ,
2011-09-02 09:15:17 +08:00
ValueObjectListSP & list ,
2011-07-12 08:18:11 +08:00
const char * * first_unparsed ,
ExpressionPathScanEndReason * reason_to_stop ,
ExpressionPathEndResultType * final_value_type ,
const GetValueForExpressionPathOptions & options ,
ExpressionPathAftermath * final_task_on_target )
{
const char * dummy_first_unparsed ;
ExpressionPathScanEndReason dummy_reason_to_stop ;
ExpressionPathEndResultType dummy_final_value_type ;
2012-03-20 06:58:49 +08:00
ExpressionPathAftermath dummy_final_task_on_target = ValueObject : : eExpressionPathAftermathNothing ;
2011-07-12 08:18:11 +08:00
ValueObjectSP ret_val = GetValueForExpressionPath_Impl ( expression ,
first_unparsed ? first_unparsed : & dummy_first_unparsed ,
reason_to_stop ? reason_to_stop : & dummy_reason_to_stop ,
final_value_type ? final_value_type : & dummy_final_value_type ,
options ,
final_task_on_target ? final_task_on_target : & dummy_final_task_on_target ) ;
if ( ! ret_val . get ( ) ) // if there are errors, I add nothing to the list
return 0 ;
2012-03-29 09:34:34 +08:00
if ( ( reason_to_stop ? * reason_to_stop : dummy_reason_to_stop ) ! = eExpressionPathScanEndReasonArrayRangeOperatorMet )
2011-07-12 08:18:11 +08:00
{
// I need not expand a range, just post-process the final value and return
2012-03-20 06:58:49 +08:00
if ( ! final_task_on_target | | * final_task_on_target = = ValueObject : : eExpressionPathAftermathNothing )
2011-07-12 08:18:11 +08:00
{
list - > Append ( ret_val ) ;
return 1 ;
}
2012-03-29 09:34:34 +08:00
if ( ret_val . get ( ) & & ( final_value_type ? * final_value_type : dummy_final_value_type ) = = eExpressionPathEndResultTypePlain ) // I can only deref and takeaddress of plain objects
2011-07-12 08:18:11 +08:00
{
2012-03-20 06:58:49 +08:00
if ( * final_task_on_target = = ValueObject : : eExpressionPathAftermathDereference )
2011-07-12 08:18:11 +08:00
{
Error error ;
ValueObjectSP final_value = ret_val - > Dereference ( error ) ;
if ( error . Fail ( ) | | ! final_value . get ( ) )
{
2012-07-17 11:23:13 +08:00
if ( reason_to_stop )
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonDereferencingFailed ;
if ( final_value_type )
* final_value_type = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
else
{
2012-03-20 06:58:49 +08:00
* final_task_on_target = ValueObject : : eExpressionPathAftermathNothing ;
2011-07-12 08:18:11 +08:00
list - > Append ( final_value ) ;
return 1 ;
}
}
2012-03-20 06:58:49 +08:00
if ( * final_task_on_target = = ValueObject : : eExpressionPathAftermathTakeAddress )
2011-07-12 08:18:11 +08:00
{
Error error ;
ValueObjectSP final_value = ret_val - > AddressOf ( error ) ;
if ( error . Fail ( ) | | ! final_value . get ( ) )
{
2012-07-17 11:23:13 +08:00
if ( reason_to_stop )
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonTakingAddressFailed ;
if ( final_value_type )
* final_value_type = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
else
{
2012-03-20 06:58:49 +08:00
* final_task_on_target = ValueObject : : eExpressionPathAftermathNothing ;
2011-07-12 08:18:11 +08:00
list - > Append ( final_value ) ;
return 1 ;
}
}
}
}
else
{
return ExpandArraySliceExpression ( first_unparsed ? * first_unparsed : dummy_first_unparsed ,
first_unparsed ? first_unparsed : & dummy_first_unparsed ,
ret_val ,
list ,
reason_to_stop ? reason_to_stop : & dummy_reason_to_stop ,
final_value_type ? final_value_type : & dummy_final_value_type ,
options ,
final_task_on_target ? final_task_on_target : & dummy_final_task_on_target ) ;
}
// in any non-covered case, just do the obviously right thing
list - > Append ( ret_val ) ;
return 1 ;
}
2011-09-02 09:15:17 +08:00
ValueObjectSP
2011-07-08 10:51:01 +08:00
ValueObject : : GetValueForExpressionPath_Impl ( const char * expression_cstr ,
const char * * first_unparsed ,
ExpressionPathScanEndReason * reason_to_stop ,
ExpressionPathEndResultType * final_result ,
const GetValueForExpressionPathOptions & options ,
ExpressionPathAftermath * what_next )
{
ValueObjectSP root = GetSP ( ) ;
if ( ! root . get ( ) )
return ValueObjectSP ( ) ;
* first_unparsed = expression_cstr ;
while ( true )
{
const char * expression_cstr = * first_unparsed ; // hide the top level expression_cstr
2013-07-12 06:46:58 +08:00
ClangASTType root_clang_type = root - > GetClangType ( ) ;
ClangASTType pointee_clang_type ;
Flags pointee_clang_type_info ;
2011-07-12 08:18:11 +08:00
2013-07-12 06:46:58 +08:00
Flags root_clang_type_info ( root_clang_type . GetTypeInfo ( & pointee_clang_type ) ) ;
2011-07-12 08:18:11 +08:00
if ( pointee_clang_type )
2013-07-12 06:46:58 +08:00
pointee_clang_type_info . Reset ( pointee_clang_type . GetTypeInfo ( ) ) ;
2011-07-08 10:51:01 +08:00
if ( ! expression_cstr | | * expression_cstr = = ' \0 ' )
{
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonEndOfString ;
2011-07-08 10:51:01 +08:00
return root ;
}
switch ( * expression_cstr )
{
case ' - ' :
{
if ( options . m_check_dot_vs_arrow_syntax & &
2014-10-22 04:52:14 +08:00
root_clang_type_info . Test ( eTypeIsPointer ) ) // if you are trying to use -> on a non-pointer and I must catch the error
2011-07-08 10:51:01 +08:00
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonArrowInsteadOfDot ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
2014-10-22 04:52:14 +08:00
if ( root_clang_type_info . Test ( eTypeIsObjC ) & & // if yo are trying to extract an ObjC IVar when this is forbidden
root_clang_type_info . Test ( eTypeIsPointer ) & &
2011-07-08 10:51:01 +08:00
options . m_no_fragile_ivar )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonFragileIVarNotAllowed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
if ( expression_cstr [ 1 ] ! = ' > ' )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
expression_cstr + + ; // skip the -
}
case ' . ' : // or fallthrough from ->
{
if ( options . m_check_dot_vs_arrow_syntax & & * expression_cstr = = ' . ' & &
2014-10-22 04:52:14 +08:00
root_clang_type_info . Test ( eTypeIsPointer ) ) // if you are trying to use . on a pointer and I must catch the error
2011-07-08 10:51:01 +08:00
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonDotInsteadOfArrow ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
expression_cstr + + ; // skip .
const char * next_separator = strpbrk ( expression_cstr + 1 , " -.[ " ) ;
ConstString child_name ;
if ( ! next_separator ) // if no other separator just expand this last layer
{
child_name . SetCString ( expression_cstr ) ;
2011-08-12 01:08:01 +08:00
ValueObjectSP child_valobj_sp = root - > GetChildMemberWithName ( child_name , true ) ;
if ( child_valobj_sp . get ( ) ) // we know we are done, so just return
2011-07-08 10:51:01 +08:00
{
2012-12-08 06:21:08 +08:00
* first_unparsed = " " ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonEndOfString ;
* final_result = ValueObject : : eExpressionPathEndResultTypePlain ;
2011-08-12 01:08:01 +08:00
return child_valobj_sp ;
}
2015-03-13 06:30:58 +08:00
else
2011-08-12 01:08:01 +08:00
{
2015-03-13 06:30:58 +08:00
switch ( options . m_synthetic_children_traversal )
2012-08-03 01:34:05 +08:00
{
2015-03-13 06:30:58 +08:00
case GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : None :
break ;
case GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : FromSynthetic :
if ( root - > IsSynthetic ( ) )
{
child_valobj_sp = root - > GetNonSyntheticValue ( ) ;
if ( child_valobj_sp . get ( ) )
child_valobj_sp = child_valobj_sp - > GetChildMemberWithName ( child_name , true ) ;
}
break ;
case GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : ToSynthetic :
if ( ! root - > IsSynthetic ( ) )
{
child_valobj_sp = root - > GetSyntheticValue ( ) ;
if ( child_valobj_sp . get ( ) )
child_valobj_sp = child_valobj_sp - > GetChildMemberWithName ( child_name , true ) ;
}
break ;
case GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : Both :
if ( root - > IsSynthetic ( ) )
{
child_valobj_sp = root - > GetNonSyntheticValue ( ) ;
if ( child_valobj_sp . get ( ) )
child_valobj_sp = child_valobj_sp - > GetChildMemberWithName ( child_name , true ) ;
}
else
{
child_valobj_sp = root - > GetSyntheticValue ( ) ;
if ( child_valobj_sp . get ( ) )
child_valobj_sp = child_valobj_sp - > GetChildMemberWithName ( child_name , true ) ;
}
break ;
2012-08-03 01:34:05 +08:00
}
2011-08-12 01:08:01 +08:00
}
// if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
// so we hit the "else" branch, and return an error
if ( child_valobj_sp . get ( ) ) // if it worked, just return
{
2012-12-08 06:21:08 +08:00
* first_unparsed = " " ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonEndOfString ;
* final_result = ValueObject : : eExpressionPathEndResultTypePlain ;
2011-08-12 01:08:01 +08:00
return child_valobj_sp ;
2011-07-08 10:51:01 +08:00
}
else
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
}
else // other layers do expand
{
child_name . SetCStringWithLength ( expression_cstr , next_separator - expression_cstr ) ;
2011-08-12 01:08:01 +08:00
ValueObjectSP child_valobj_sp = root - > GetChildMemberWithName ( child_name , true ) ;
if ( child_valobj_sp . get ( ) ) // store the new root and move on
{
root = child_valobj_sp ;
* first_unparsed = next_separator ;
2012-03-20 06:58:49 +08:00
* final_result = ValueObject : : eExpressionPathEndResultTypePlain ;
2011-08-12 01:08:01 +08:00
continue ;
}
2015-03-13 06:30:58 +08:00
else
2011-08-12 01:08:01 +08:00
{
2015-03-13 06:30:58 +08:00
switch ( options . m_synthetic_children_traversal )
2012-08-03 01:34:05 +08:00
{
2015-03-13 06:30:58 +08:00
case GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : None :
break ;
case GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : FromSynthetic :
if ( root - > IsSynthetic ( ) )
{
child_valobj_sp = root - > GetNonSyntheticValue ( ) ;
if ( child_valobj_sp . get ( ) )
child_valobj_sp = child_valobj_sp - > GetChildMemberWithName ( child_name , true ) ;
}
break ;
case GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : ToSynthetic :
if ( ! root - > IsSynthetic ( ) )
{
child_valobj_sp = root - > GetSyntheticValue ( ) ;
if ( child_valobj_sp . get ( ) )
child_valobj_sp = child_valobj_sp - > GetChildMemberWithName ( child_name , true ) ;
}
break ;
case GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : Both :
if ( root - > IsSynthetic ( ) )
{
child_valobj_sp = root - > GetNonSyntheticValue ( ) ;
if ( child_valobj_sp . get ( ) )
child_valobj_sp = child_valobj_sp - > GetChildMemberWithName ( child_name , true ) ;
}
else
{
child_valobj_sp = root - > GetSyntheticValue ( ) ;
if ( child_valobj_sp . get ( ) )
child_valobj_sp = child_valobj_sp - > GetChildMemberWithName ( child_name , true ) ;
}
break ;
2012-08-03 01:34:05 +08:00
}
2011-08-12 01:08:01 +08:00
}
// if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
// so we hit the "else" branch, and return an error
if ( child_valobj_sp . get ( ) ) // if it worked, move on
2011-07-08 10:51:01 +08:00
{
2011-08-12 01:08:01 +08:00
root = child_valobj_sp ;
2011-07-08 10:51:01 +08:00
* first_unparsed = next_separator ;
2012-03-20 06:58:49 +08:00
* final_result = ValueObject : : eExpressionPathEndResultTypePlain ;
2011-07-08 10:51:01 +08:00
continue ;
}
else
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
}
break ;
}
case ' [ ' :
{
2014-10-22 04:52:14 +08:00
if ( ! root_clang_type_info . Test ( eTypeIsArray ) & & ! root_clang_type_info . Test ( eTypeIsPointer ) & & ! root_clang_type_info . Test ( eTypeIsVector ) ) // if this is not a T[] nor a T*
2011-07-08 10:51:01 +08:00
{
2014-10-22 04:52:14 +08:00
if ( ! root_clang_type_info . Test ( eTypeIsScalar ) ) // if this is not even a scalar...
2011-07-08 10:51:01 +08:00
{
2015-03-13 06:30:58 +08:00
if ( options . m_synthetic_children_traversal = = GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : None ) // ...only chance left is synthetic
2011-08-09 09:04:56 +08:00
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorInvalid ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-08-09 09:04:56 +08:00
return ValueObjectSP ( ) ;
}
2011-07-08 10:51:01 +08:00
}
else if ( ! options . m_allow_bitfields_syntax ) // if this is a scalar, check that we can expand bitfields
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorNotAllowed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
}
if ( * ( expression_cstr + 1 ) = = ' ] ' ) // if this is an unbounded range it only works for arrays
{
2014-10-22 04:52:14 +08:00
if ( ! root_clang_type_info . Test ( eTypeIsArray ) )
2011-07-08 10:51:01 +08:00
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonEmptyRangeNotAllowed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
{
* first_unparsed = expression_cstr + 2 ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonArrayRangeOperatorMet ;
* final_result = ValueObject : : eExpressionPathEndResultTypeUnboundedRange ;
2011-07-08 10:51:01 +08:00
return root ;
}
}
const char * separator_position = : : strchr ( expression_cstr + 1 , ' - ' ) ;
const char * close_bracket_position = : : strchr ( expression_cstr + 1 , ' ] ' ) ;
if ( ! close_bracket_position ) // if there is no ], this is a syntax error
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
if ( ! separator_position | | separator_position > close_bracket_position ) // if no separator, this is either [] or [N]
{
char * end = NULL ;
unsigned long index = : : strtoul ( expression_cstr + 1 , & end , 0 ) ;
if ( ! end | | end ! = close_bracket_position ) // if something weird is in our way return an error
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
if ( end - expression_cstr = = 1 ) // if this is [], only return a valid value for arrays
{
2014-10-22 04:52:14 +08:00
if ( root_clang_type_info . Test ( eTypeIsArray ) )
2011-07-08 10:51:01 +08:00
{
* first_unparsed = expression_cstr + 2 ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonArrayRangeOperatorMet ;
* final_result = ValueObject : : eExpressionPathEndResultTypeUnboundedRange ;
2011-07-08 10:51:01 +08:00
return root ;
}
else
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonEmptyRangeNotAllowed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
}
// from here on we do have a valid index
2014-10-22 04:52:14 +08:00
if ( root_clang_type_info . Test ( eTypeIsArray ) )
2011-07-08 10:51:01 +08:00
{
2011-07-10 04:12:33 +08:00
ValueObjectSP child_valobj_sp = root - > GetChildAtIndex ( index , true ) ;
if ( ! child_valobj_sp )
2015-02-27 07:55:39 +08:00
child_valobj_sp = root - > GetSyntheticArrayMember ( index , true ) ;
2011-08-09 09:04:56 +08:00
if ( ! child_valobj_sp )
2012-03-20 06:58:49 +08:00
if ( root - > HasSyntheticValue ( ) & & root - > GetSyntheticValue ( ) - > GetNumChildren ( ) > index )
child_valobj_sp = root - > GetSyntheticValue ( ) - > GetChildAtIndex ( index , true ) ;
2011-07-10 04:12:33 +08:00
if ( child_valobj_sp )
{
root = child_valobj_sp ;
* first_unparsed = end + 1 ; // skip ]
2012-03-20 06:58:49 +08:00
* final_result = ValueObject : : eExpressionPathEndResultTypePlain ;
2011-07-10 04:12:33 +08:00
continue ;
}
else
2011-07-08 10:51:01 +08:00
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
}
2014-10-22 04:52:14 +08:00
else if ( root_clang_type_info . Test ( eTypeIsPointer ) )
2011-07-08 10:51:01 +08:00
{
2012-03-20 06:58:49 +08:00
if ( * what_next = = ValueObject : : eExpressionPathAftermathDereference & & // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
2014-10-22 04:52:14 +08:00
pointee_clang_type_info . Test ( eTypeIsScalar ) )
2011-07-08 10:51:01 +08:00
{
Error error ;
root = root - > Dereference ( error ) ;
if ( error . Fail ( ) | | ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonDereferencingFailed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
else
{
2012-03-20 06:58:49 +08:00
* what_next = eExpressionPathAftermathNothing ;
2011-07-08 10:51:01 +08:00
continue ;
}
}
else
{
2013-07-12 06:46:58 +08:00
if ( root - > GetClangType ( ) . GetMinimumLanguage ( ) = = eLanguageTypeObjC
2014-10-22 04:52:14 +08:00
& & pointee_clang_type_info . AllClear ( eTypeIsPointer )
2012-03-27 07:03:23 +08:00
& & root - > HasSyntheticValue ( )
2015-03-13 06:30:58 +08:00
& & ( options . m_synthetic_children_traversal = = GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : ToSynthetic | |
options . m_synthetic_children_traversal = = GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : Both ) )
2011-08-09 09:04:56 +08:00
{
2012-03-20 06:58:49 +08:00
root = root - > GetSyntheticValue ( ) - > GetChildAtIndex ( index , true ) ;
2011-08-09 09:04:56 +08:00
}
else
2015-02-27 07:55:39 +08:00
root = root - > GetSyntheticArrayMember ( index , true ) ;
2011-07-08 10:51:01 +08:00
if ( ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
else
{
* first_unparsed = end + 1 ; // skip ]
2012-03-20 06:58:49 +08:00
* final_result = ValueObject : : eExpressionPathEndResultTypePlain ;
2011-07-08 10:51:01 +08:00
continue ;
}
}
}
2014-10-22 04:52:14 +08:00
else if ( root_clang_type_info . Test ( eTypeIsScalar ) )
2011-07-08 10:51:01 +08:00
{
root = root - > GetSyntheticBitFieldChild ( index , index , true ) ;
if ( ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
{
* first_unparsed = end + 1 ; // skip ]
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonBitfieldRangeOperatorMet ;
* final_result = ValueObject : : eExpressionPathEndResultTypeBitfield ;
2011-07-08 10:51:01 +08:00
return root ;
}
}
2014-10-22 04:52:14 +08:00
else if ( root_clang_type_info . Test ( eTypeIsVector ) )
2013-06-19 08:00:45 +08:00
{
root = root - > GetChildAtIndex ( index , true ) ;
if ( ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
return ValueObjectSP ( ) ;
}
else
{
* first_unparsed = end + 1 ; // skip ]
* final_result = ValueObject : : eExpressionPathEndResultTypePlain ;
continue ;
}
}
2015-03-13 06:30:58 +08:00
else if ( options . m_synthetic_children_traversal = = GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : ToSynthetic | |
options . m_synthetic_children_traversal = = GetValueForExpressionPathOptions : : SyntheticChildrenTraversal : : Both )
2011-08-09 09:04:56 +08:00
{
2012-03-20 06:58:49 +08:00
if ( root - > HasSyntheticValue ( ) )
root = root - > GetSyntheticValue ( ) ;
else if ( ! root - > IsSynthetic ( ) )
{
* first_unparsed = expression_cstr ;
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonSyntheticValueMissing ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
return ValueObjectSP ( ) ;
}
// if we are here, then root itself is a synthetic VO.. should be good to go
if ( ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonSyntheticValueMissing ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
return ValueObjectSP ( ) ;
}
root = root - > GetChildAtIndex ( index , true ) ;
2011-08-09 09:04:56 +08:00
if ( ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-08-09 09:04:56 +08:00
return ValueObjectSP ( ) ;
}
2011-08-12 01:08:01 +08:00
else
{
* first_unparsed = end + 1 ; // skip ]
2012-03-20 06:58:49 +08:00
* final_result = ValueObject : : eExpressionPathEndResultTypePlain ;
2011-08-12 01:08:01 +08:00
continue ;
}
2011-08-09 09:04:56 +08:00
}
else
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-08-09 09:04:56 +08:00
return ValueObjectSP ( ) ;
}
2011-07-08 10:51:01 +08:00
}
else // we have a low and a high index
{
char * end = NULL ;
unsigned long index_lower = : : strtoul ( expression_cstr + 1 , & end , 0 ) ;
if ( ! end | | end ! = separator_position ) // if something weird is in our way return an error
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
unsigned long index_higher = : : strtoul ( separator_position + 1 , & end , 0 ) ;
if ( ! end | | end ! = close_bracket_position ) // if something weird is in our way return an error
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
if ( index_lower > index_higher ) // swap indices if required
{
unsigned long temp = index_lower ;
index_lower = index_higher ;
index_higher = temp ;
}
2014-10-22 04:52:14 +08:00
if ( root_clang_type_info . Test ( eTypeIsScalar ) ) // expansion only works for scalars
2011-07-08 10:51:01 +08:00
{
root = root - > GetSyntheticBitFieldChild ( index_lower , index_higher , true ) ;
if ( ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
else
{
* first_unparsed = end + 1 ; // skip ]
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonBitfieldRangeOperatorMet ;
* final_result = ValueObject : : eExpressionPathEndResultTypeBitfield ;
2011-07-08 10:51:01 +08:00
return root ;
}
}
2014-10-22 04:52:14 +08:00
else if ( root_clang_type_info . Test ( eTypeIsPointer ) & & // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
2012-03-20 06:58:49 +08:00
* what_next = = ValueObject : : eExpressionPathAftermathDereference & &
2014-10-22 04:52:14 +08:00
pointee_clang_type_info . Test ( eTypeIsScalar ) )
2011-07-08 10:51:01 +08:00
{
Error error ;
root = root - > Dereference ( error ) ;
if ( error . Fail ( ) | | ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonDereferencingFailed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
}
else
{
2012-03-20 06:58:49 +08:00
* what_next = ValueObject : : eExpressionPathAftermathNothing ;
2011-07-08 10:51:01 +08:00
continue ;
}
}
else
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonArrayRangeOperatorMet ;
* final_result = ValueObject : : eExpressionPathEndResultTypeBoundedRange ;
2011-07-08 10:51:01 +08:00
return root ;
}
}
break ;
}
default : // some non-separator is in the way
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-08 10:51:01 +08:00
return ValueObjectSP ( ) ;
break ;
}
}
}
}
2011-07-12 08:18:11 +08:00
int
ValueObject : : ExpandArraySliceExpression ( const char * expression_cstr ,
const char * * first_unparsed ,
2011-09-02 09:15:17 +08:00
ValueObjectSP root ,
ValueObjectListSP & list ,
2011-07-12 08:18:11 +08:00
ExpressionPathScanEndReason * reason_to_stop ,
ExpressionPathEndResultType * final_result ,
const GetValueForExpressionPathOptions & options ,
ExpressionPathAftermath * what_next )
{
if ( ! root . get ( ) )
return 0 ;
* first_unparsed = expression_cstr ;
while ( true )
{
const char * expression_cstr = * first_unparsed ; // hide the top level expression_cstr
2013-07-12 06:46:58 +08:00
ClangASTType root_clang_type = root - > GetClangType ( ) ;
ClangASTType pointee_clang_type ;
Flags pointee_clang_type_info ;
Flags root_clang_type_info ( root_clang_type . GetTypeInfo ( & pointee_clang_type ) ) ;
2011-07-12 08:18:11 +08:00
if ( pointee_clang_type )
2013-07-12 06:46:58 +08:00
pointee_clang_type_info . Reset ( pointee_clang_type . GetTypeInfo ( ) ) ;
2011-07-12 08:18:11 +08:00
if ( ! expression_cstr | | * expression_cstr = = ' \0 ' )
{
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonEndOfString ;
2011-07-12 08:18:11 +08:00
list - > Append ( root ) ;
return 1 ;
}
switch ( * expression_cstr )
{
case ' [ ' :
{
2014-10-22 04:52:14 +08:00
if ( ! root_clang_type_info . Test ( eTypeIsArray ) & & ! root_clang_type_info . Test ( eTypeIsPointer ) ) // if this is not a T[] nor a T*
2011-07-12 08:18:11 +08:00
{
2014-10-22 04:52:14 +08:00
if ( ! root_clang_type_info . Test ( eTypeIsScalar ) ) // if this is not even a scalar, this syntax is just plain wrong!
2011-07-12 08:18:11 +08:00
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorInvalid ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
else if ( ! options . m_allow_bitfields_syntax ) // if this is a scalar, check that we can expand bitfields
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorNotAllowed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
}
if ( * ( expression_cstr + 1 ) = = ' ] ' ) // if this is an unbounded range it only works for arrays
{
2014-10-22 04:52:14 +08:00
if ( ! root_clang_type_info . Test ( eTypeIsArray ) )
2011-07-12 08:18:11 +08:00
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonEmptyRangeNotAllowed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
else // expand this into list
{
2013-01-26 02:06:21 +08:00
const size_t max_index = root - > GetNumChildren ( ) - 1 ;
for ( size_t index = 0 ; index < max_index ; index + + )
2011-07-12 08:18:11 +08:00
{
ValueObjectSP child =
root - > GetChildAtIndex ( index , true ) ;
list - > Append ( child ) ;
}
* first_unparsed = expression_cstr + 2 ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorExpanded ;
* final_result = ValueObject : : eExpressionPathEndResultTypeValueObjectList ;
2011-07-12 08:18:11 +08:00
return max_index ; // tell me number of items I added to the VOList
}
}
const char * separator_position = : : strchr ( expression_cstr + 1 , ' - ' ) ;
const char * close_bracket_position = : : strchr ( expression_cstr + 1 , ' ] ' ) ;
if ( ! close_bracket_position ) // if there is no ], this is a syntax error
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
if ( ! separator_position | | separator_position > close_bracket_position ) // if no separator, this is either [] or [N]
{
char * end = NULL ;
unsigned long index = : : strtoul ( expression_cstr + 1 , & end , 0 ) ;
if ( ! end | | end ! = close_bracket_position ) // if something weird is in our way return an error
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
if ( end - expression_cstr = = 1 ) // if this is [], only return a valid value for arrays
{
2014-10-22 04:52:14 +08:00
if ( root_clang_type_info . Test ( eTypeIsArray ) )
2011-07-12 08:18:11 +08:00
{
2013-01-26 02:06:21 +08:00
const size_t max_index = root - > GetNumChildren ( ) - 1 ;
for ( size_t index = 0 ; index < max_index ; index + + )
2011-07-12 08:18:11 +08:00
{
ValueObjectSP child =
root - > GetChildAtIndex ( index , true ) ;
list - > Append ( child ) ;
}
* first_unparsed = expression_cstr + 2 ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorExpanded ;
* final_result = ValueObject : : eExpressionPathEndResultTypeValueObjectList ;
2011-07-12 08:18:11 +08:00
return max_index ; // tell me number of items I added to the VOList
}
else
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonEmptyRangeNotAllowed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
}
// from here on we do have a valid index
2014-10-22 04:52:14 +08:00
if ( root_clang_type_info . Test ( eTypeIsArray ) )
2011-07-12 08:18:11 +08:00
{
root = root - > GetChildAtIndex ( index , true ) ;
if ( ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
else
{
list - > Append ( root ) ;
* first_unparsed = end + 1 ; // skip ]
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorExpanded ;
* final_result = ValueObject : : eExpressionPathEndResultTypeValueObjectList ;
2011-07-12 08:18:11 +08:00
return 1 ;
}
}
2014-10-22 04:52:14 +08:00
else if ( root_clang_type_info . Test ( eTypeIsPointer ) )
2011-07-12 08:18:11 +08:00
{
2012-03-20 06:58:49 +08:00
if ( * what_next = = ValueObject : : eExpressionPathAftermathDereference & & // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
2014-10-22 04:52:14 +08:00
pointee_clang_type_info . Test ( eTypeIsScalar ) )
2011-07-12 08:18:11 +08:00
{
Error error ;
root = root - > Dereference ( error ) ;
if ( error . Fail ( ) | | ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonDereferencingFailed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
else
{
2012-03-20 06:58:49 +08:00
* what_next = eExpressionPathAftermathNothing ;
2011-07-12 08:18:11 +08:00
continue ;
}
}
else
{
2015-02-27 07:55:39 +08:00
root = root - > GetSyntheticArrayMember ( index , true ) ;
2011-07-12 08:18:11 +08:00
if ( ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
else
{
list - > Append ( root ) ;
* first_unparsed = end + 1 ; // skip ]
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorExpanded ;
* final_result = ValueObject : : eExpressionPathEndResultTypeValueObjectList ;
2011-07-12 08:18:11 +08:00
return 1 ;
}
}
}
else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
{
root = root - > GetSyntheticBitFieldChild ( index , index , true ) ;
if ( ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
{
list - > Append ( root ) ;
* first_unparsed = end + 1 ; // skip ]
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorExpanded ;
* final_result = ValueObject : : eExpressionPathEndResultTypeValueObjectList ;
2011-07-12 08:18:11 +08:00
return 1 ;
}
}
}
else // we have a low and a high index
{
char * end = NULL ;
unsigned long index_lower = : : strtoul ( expression_cstr + 1 , & end , 0 ) ;
if ( ! end | | end ! = separator_position ) // if something weird is in our way return an error
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
unsigned long index_higher = : : strtoul ( separator_position + 1 , & end , 0 ) ;
if ( ! end | | end ! = close_bracket_position ) // if something weird is in our way return an error
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
if ( index_lower > index_higher ) // swap indices if required
{
unsigned long temp = index_lower ;
index_lower = index_higher ;
index_higher = temp ;
}
2014-10-22 04:52:14 +08:00
if ( root_clang_type_info . Test ( eTypeIsScalar ) ) // expansion only works for scalars
2011-07-12 08:18:11 +08:00
{
root = root - > GetSyntheticBitFieldChild ( index_lower , index_higher , true ) ;
if ( ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonNoSuchChild ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
else
{
list - > Append ( root ) ;
* first_unparsed = end + 1 ; // skip ]
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorExpanded ;
* final_result = ValueObject : : eExpressionPathEndResultTypeValueObjectList ;
2011-07-12 08:18:11 +08:00
return 1 ;
}
}
2014-10-22 04:52:14 +08:00
else if ( root_clang_type_info . Test ( eTypeIsPointer ) & & // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
2012-03-20 06:58:49 +08:00
* what_next = = ValueObject : : eExpressionPathAftermathDereference & &
2014-10-22 04:52:14 +08:00
pointee_clang_type_info . Test ( eTypeIsScalar ) )
2011-07-12 08:18:11 +08:00
{
Error error ;
root = root - > Dereference ( error ) ;
if ( error . Fail ( ) | | ! root . get ( ) )
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonDereferencingFailed ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
}
else
{
2012-03-20 06:58:49 +08:00
* what_next = ValueObject : : eExpressionPathAftermathNothing ;
2011-07-12 08:18:11 +08:00
continue ;
}
}
else
{
2011-07-20 03:48:13 +08:00
for ( unsigned long index = index_lower ;
2011-07-12 08:18:11 +08:00
index < = index_higher ; index + + )
{
ValueObjectSP child =
root - > GetChildAtIndex ( index , true ) ;
list - > Append ( child ) ;
}
* first_unparsed = end + 1 ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonRangeOperatorExpanded ;
* final_result = ValueObject : : eExpressionPathEndResultTypeValueObjectList ;
2011-07-12 08:18:11 +08:00
return index_higher - index_lower + 1 ; // tell me number of items I added to the VOList
}
}
break ;
}
default : // some non-[ separator, or something entirely wrong, is in the way
{
* first_unparsed = expression_cstr ;
2012-03-20 06:58:49 +08:00
* reason_to_stop = ValueObject : : eExpressionPathScanEndReasonUnexpectedSymbol ;
* final_result = ValueObject : : eExpressionPathEndResultTypeInvalid ;
2011-07-12 08:18:11 +08:00
return 0 ;
break ;
}
}
}
}
2012-03-23 02:15:37 +08:00
void
<rdar://problem/14393032>
DumpValueObject() 2.0
This checkin restores pre-Xcode5 functionality to the "po" (expr -O) command:
- expr now has a new --description-verbosity (-v) argument, which takes either compact or full as a value (-v is the same as -vfull)
When the full mode is on, "po" will show the extended output with type name, persistent variable name and value, as in
(lldb) expr -O -v -- foo
(id) $0 = 0x000000010010baf0 {
1 = 2;
2 = 3;
}
When -v is omitted, or -vcompact is passed, the Xcode5-style output will be shown, as in
(lldb) expr -O -- foo
{
1 = 2;
2 = 3;
}
- for a non-ObjectiveC object, LLDB will still try to retrieve a summary and/or value to display
(lldb) po 5
5
-v also works in this mode
(lldb) expr -O -vfull -- 5
(int) $4 = 5
On top of that, this is a major refactoring of the ValueObject printing code. The functionality is now factored into a ValueObjectPrinter class for easier maintenance in the future
DumpValueObject() was turned into an instance method ValueObject::Dump() which simply calls through to the printer code, Dump_Impl has been removed
Test case to follow
llvm-svn: 191694
2013-10-01 03:11:51 +08:00
ValueObject : : LogValueObject ( Log * log )
2012-03-23 02:15:37 +08:00
{
<rdar://problem/14393032>
DumpValueObject() 2.0
This checkin restores pre-Xcode5 functionality to the "po" (expr -O) command:
- expr now has a new --description-verbosity (-v) argument, which takes either compact or full as a value (-v is the same as -vfull)
When the full mode is on, "po" will show the extended output with type name, persistent variable name and value, as in
(lldb) expr -O -v -- foo
(id) $0 = 0x000000010010baf0 {
1 = 2;
2 = 3;
}
When -v is omitted, or -vcompact is passed, the Xcode5-style output will be shown, as in
(lldb) expr -O -- foo
{
1 = 2;
2 = 3;
}
- for a non-ObjectiveC object, LLDB will still try to retrieve a summary and/or value to display
(lldb) po 5
5
-v also works in this mode
(lldb) expr -O -vfull -- 5
(int) $4 = 5
On top of that, this is a major refactoring of the ValueObject printing code. The functionality is now factored into a ValueObjectPrinter class for easier maintenance in the future
DumpValueObject() was turned into an instance method ValueObject::Dump() which simply calls through to the printer code, Dump_Impl has been removed
Test case to follow
llvm-svn: 191694
2013-10-01 03:11:51 +08:00
if ( log )
return LogValueObject ( log , DumpValueObjectOptions : : DefaultOptions ( ) ) ;
2012-03-23 02:15:37 +08:00
}
void
<rdar://problem/14393032>
DumpValueObject() 2.0
This checkin restores pre-Xcode5 functionality to the "po" (expr -O) command:
- expr now has a new --description-verbosity (-v) argument, which takes either compact or full as a value (-v is the same as -vfull)
When the full mode is on, "po" will show the extended output with type name, persistent variable name and value, as in
(lldb) expr -O -v -- foo
(id) $0 = 0x000000010010baf0 {
1 = 2;
2 = 3;
}
When -v is omitted, or -vcompact is passed, the Xcode5-style output will be shown, as in
(lldb) expr -O -- foo
{
1 = 2;
2 = 3;
}
- for a non-ObjectiveC object, LLDB will still try to retrieve a summary and/or value to display
(lldb) po 5
5
-v also works in this mode
(lldb) expr -O -vfull -- 5
(int) $4 = 5
On top of that, this is a major refactoring of the ValueObject printing code. The functionality is now factored into a ValueObjectPrinter class for easier maintenance in the future
DumpValueObject() was turned into an instance method ValueObject::Dump() which simply calls through to the printer code, Dump_Impl has been removed
Test case to follow
llvm-svn: 191694
2013-10-01 03:11:51 +08:00
ValueObject : : LogValueObject ( Log * log , const DumpValueObjectOptions & options )
2012-03-23 02:15:37 +08:00
{
<rdar://problem/14393032>
DumpValueObject() 2.0
This checkin restores pre-Xcode5 functionality to the "po" (expr -O) command:
- expr now has a new --description-verbosity (-v) argument, which takes either compact or full as a value (-v is the same as -vfull)
When the full mode is on, "po" will show the extended output with type name, persistent variable name and value, as in
(lldb) expr -O -v -- foo
(id) $0 = 0x000000010010baf0 {
1 = 2;
2 = 3;
}
When -v is omitted, or -vcompact is passed, the Xcode5-style output will be shown, as in
(lldb) expr -O -- foo
{
1 = 2;
2 = 3;
}
- for a non-ObjectiveC object, LLDB will still try to retrieve a summary and/or value to display
(lldb) po 5
5
-v also works in this mode
(lldb) expr -O -vfull -- 5
(int) $4 = 5
On top of that, this is a major refactoring of the ValueObject printing code. The functionality is now factored into a ValueObjectPrinter class for easier maintenance in the future
DumpValueObject() was turned into an instance method ValueObject::Dump() which simply calls through to the printer code, Dump_Impl has been removed
Test case to follow
llvm-svn: 191694
2013-10-01 03:11:51 +08:00
if ( log )
2012-03-23 02:15:37 +08:00
{
StreamString s ;
<rdar://problem/14393032>
DumpValueObject() 2.0
This checkin restores pre-Xcode5 functionality to the "po" (expr -O) command:
- expr now has a new --description-verbosity (-v) argument, which takes either compact or full as a value (-v is the same as -vfull)
When the full mode is on, "po" will show the extended output with type name, persistent variable name and value, as in
(lldb) expr -O -v -- foo
(id) $0 = 0x000000010010baf0 {
1 = 2;
2 = 3;
}
When -v is omitted, or -vcompact is passed, the Xcode5-style output will be shown, as in
(lldb) expr -O -- foo
{
1 = 2;
2 = 3;
}
- for a non-ObjectiveC object, LLDB will still try to retrieve a summary and/or value to display
(lldb) po 5
5
-v also works in this mode
(lldb) expr -O -vfull -- 5
(int) $4 = 5
On top of that, this is a major refactoring of the ValueObject printing code. The functionality is now factored into a ValueObjectPrinter class for easier maintenance in the future
DumpValueObject() was turned into an instance method ValueObject::Dump() which simply calls through to the printer code, Dump_Impl has been removed
Test case to follow
llvm-svn: 191694
2013-10-01 03:11:51 +08:00
Dump ( s , options ) ;
2012-03-23 02:15:37 +08:00
if ( s . GetSize ( ) )
log - > PutCString ( s . GetData ( ) ) ;
}
}
2012-03-01 12:24:26 +08:00
void
<rdar://problem/14393032>
DumpValueObject() 2.0
This checkin restores pre-Xcode5 functionality to the "po" (expr -O) command:
- expr now has a new --description-verbosity (-v) argument, which takes either compact or full as a value (-v is the same as -vfull)
When the full mode is on, "po" will show the extended output with type name, persistent variable name and value, as in
(lldb) expr -O -v -- foo
(id) $0 = 0x000000010010baf0 {
1 = 2;
2 = 3;
}
When -v is omitted, or -vcompact is passed, the Xcode5-style output will be shown, as in
(lldb) expr -O -- foo
{
1 = 2;
2 = 3;
}
- for a non-ObjectiveC object, LLDB will still try to retrieve a summary and/or value to display
(lldb) po 5
5
-v also works in this mode
(lldb) expr -O -vfull -- 5
(int) $4 = 5
On top of that, this is a major refactoring of the ValueObject printing code. The functionality is now factored into a ValueObjectPrinter class for easier maintenance in the future
DumpValueObject() was turned into an instance method ValueObject::Dump() which simply calls through to the printer code, Dump_Impl has been removed
Test case to follow
llvm-svn: 191694
2013-10-01 03:11:51 +08:00
ValueObject : : Dump ( Stream & s )
2012-03-01 12:24:26 +08:00
{
2014-12-20 09:41:27 +08:00
Dump ( s , DumpValueObjectOptions : : DefaultOptions ( ) ) ;
2012-03-01 12:24:26 +08:00
}
void
<rdar://problem/14393032>
DumpValueObject() 2.0
This checkin restores pre-Xcode5 functionality to the "po" (expr -O) command:
- expr now has a new --description-verbosity (-v) argument, which takes either compact or full as a value (-v is the same as -vfull)
When the full mode is on, "po" will show the extended output with type name, persistent variable name and value, as in
(lldb) expr -O -v -- foo
(id) $0 = 0x000000010010baf0 {
1 = 2;
2 = 3;
}
When -v is omitted, or -vcompact is passed, the Xcode5-style output will be shown, as in
(lldb) expr -O -- foo
{
1 = 2;
2 = 3;
}
- for a non-ObjectiveC object, LLDB will still try to retrieve a summary and/or value to display
(lldb) po 5
5
-v also works in this mode
(lldb) expr -O -vfull -- 5
(int) $4 = 5
On top of that, this is a major refactoring of the ValueObject printing code. The functionality is now factored into a ValueObjectPrinter class for easier maintenance in the future
DumpValueObject() was turned into an instance method ValueObject::Dump() which simply calls through to the printer code, Dump_Impl has been removed
Test case to follow
llvm-svn: 191694
2013-10-01 03:11:51 +08:00
ValueObject : : Dump ( Stream & s ,
const DumpValueObjectOptions & options )
{
ValueObjectPrinter printer ( this , & s , options ) ;
printer . PrintValueObject ( ) ;
2012-03-01 12:24:26 +08:00
}
2010-12-14 10:59:59 +08:00
ValueObjectSP
2011-03-31 08:19:25 +08:00
ValueObject : : CreateConstantValue ( const ConstString & name )
2010-12-14 10:59:59 +08:00
{
ValueObjectSP valobj_sp ;
2011-08-03 01:27:39 +08:00
if ( UpdateValueIfNeeded ( false ) & & m_error . Success ( ) )
2010-12-14 10:59:59 +08:00
{
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
DataExtractor data ;
data . SetByteOrder ( m_data . GetByteOrder ( ) ) ;
data . SetAddressByteSize ( m_data . GetAddressByteSize ( ) ) ;
2012-04-25 06:15:37 +08:00
if ( IsBitfield ( ) )
{
Value v ( Scalar ( GetValueAsUnsigned ( UINT64_MAX ) ) ) ;
2013-07-12 06:46:58 +08:00
m_error = v . GetValueAsData ( & exe_ctx , data , 0 , GetModule ( ) . get ( ) ) ;
2012-04-25 06:15:37 +08:00
}
else
2013-07-12 06:46:58 +08:00
m_error = m_value . GetValueAsData ( & exe_ctx , data , 0 , GetModule ( ) . get ( ) ) ;
2012-02-17 15:49:44 +08:00
valobj_sp = ValueObjectConstResult : : Create ( exe_ctx . GetBestExecutionContextScope ( ) ,
GetClangType ( ) ,
name ,
data ,
GetAddressOf ( ) ) ;
2010-12-14 10:59:59 +08:00
}
2011-03-31 08:19:25 +08:00
if ( ! valobj_sp )
2010-12-14 10:59:59 +08:00
{
2013-12-11 07:16:40 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
valobj_sp = ValueObjectConstResult : : Create ( exe_ctx . GetBestExecutionContextScope ( ) , m_error ) ;
2010-12-14 10:59:59 +08:00
}
return valobj_sp ;
}
2014-10-10 02:24:30 +08:00
ValueObjectSP
ValueObject : : GetQualifiedRepresentationIfAvailable ( lldb : : DynamicValueType dynValue ,
bool synthValue )
{
ValueObjectSP result_sp ( GetSP ( ) ) ;
switch ( dynValue )
{
case lldb : : eDynamicCanRunTarget :
case lldb : : eDynamicDontRunTarget :
{
if ( ! result_sp - > IsDynamic ( ) )
{
if ( result_sp - > GetDynamicValue ( dynValue ) )
result_sp = result_sp - > GetDynamicValue ( dynValue ) ;
}
}
break ;
case lldb : : eNoDynamicValues :
{
if ( result_sp - > IsDynamic ( ) )
{
if ( result_sp - > GetStaticValue ( ) )
result_sp = result_sp - > GetStaticValue ( ) ;
}
}
break ;
}
if ( synthValue )
{
if ( ! result_sp - > IsSynthetic ( ) )
{
if ( result_sp - > GetSyntheticValue ( ) )
result_sp = result_sp - > GetSyntheticValue ( ) ;
}
}
else
{
if ( result_sp - > IsSynthetic ( ) )
{
if ( result_sp - > GetNonSyntheticValue ( ) )
result_sp = result_sp - > GetNonSyntheticValue ( ) ;
}
}
return result_sp ;
}
2014-07-19 08:12:57 +08:00
lldb : : addr_t
ValueObject : : GetCPPVTableAddress ( AddressType & address_type )
{
ClangASTType pointee_type ;
ClangASTType this_type ( GetClangType ( ) ) ;
uint32_t type_info = this_type . GetTypeInfo ( & pointee_type ) ;
if ( type_info )
{
bool ptr_or_ref = false ;
2014-10-22 04:52:14 +08:00
if ( type_info & ( eTypeIsPointer | eTypeIsReference ) )
2014-07-19 08:12:57 +08:00
{
ptr_or_ref = true ;
type_info = pointee_type . GetTypeInfo ( ) ;
}
2014-10-22 04:52:14 +08:00
const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus ;
2014-07-19 08:12:57 +08:00
if ( ( type_info & cpp_class ) = = cpp_class )
{
if ( ptr_or_ref )
{
address_type = GetAddressTypeOfChildren ( ) ;
return GetValueAsUnsigned ( LLDB_INVALID_ADDRESS ) ;
}
else
return GetAddressOf ( false , & address_type ) ;
}
}
address_type = eAddressTypeInvalid ;
return LLDB_INVALID_ADDRESS ;
}
2011-09-02 09:15:17 +08:00
ValueObjectSP
2010-12-21 04:49:23 +08:00
ValueObject : : Dereference ( Error & error )
2010-12-14 10:59:59 +08:00
{
2011-04-23 07:53:53 +08:00
if ( m_deref_valobj )
return m_deref_valobj - > GetSP ( ) ;
2011-04-16 08:01:13 +08:00
2010-12-15 13:08:08 +08:00
const bool is_pointer_type = IsPointerType ( ) ;
if ( is_pointer_type )
2010-12-14 10:59:59 +08:00
{
bool omit_empty_base_classes = true ;
2011-07-10 04:12:33 +08:00
bool ignore_array_bounds = false ;
2010-12-14 10:59:59 +08:00
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 ;
2011-01-21 09:59:00 +08:00
bool child_is_deref_of_parent = false ;
2010-12-14 10:59:59 +08:00
const bool transparent_pointers = false ;
2013-07-12 06:46:58 +08:00
ClangASTType clang_type = GetClangType ( ) ;
ClangASTType child_clang_type ;
2011-06-25 06:03:24 +08:00
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
2011-06-25 06:03:24 +08:00
2013-07-12 06:46:58 +08:00
child_clang_type = clang_type . GetChildClangTypeAtIndex ( & exe_ctx ,
0 ,
transparent_pointers ,
omit_empty_base_classes ,
ignore_array_bounds ,
child_name_str ,
child_byte_size ,
child_byte_offset ,
child_bitfield_bit_size ,
child_bitfield_bit_offset ,
child_is_base_class ,
2014-07-19 08:12:57 +08:00
child_is_deref_of_parent ,
this ) ;
2011-01-10 05:07:35 +08:00
if ( child_clang_type & & child_byte_size )
2010-12-14 10:59:59 +08:00
{
ConstString child_name ;
if ( ! child_name_str . empty ( ) )
child_name . SetCString ( child_name_str . c_str ( ) ) ;
2011-04-23 07:53:53 +08:00
m_deref_valobj = new ValueObjectChild ( * this ,
child_clang_type ,
child_name ,
child_byte_size ,
child_byte_offset ,
child_bitfield_bit_size ,
child_bitfield_bit_offset ,
child_is_base_class ,
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
child_is_deref_of_parent ,
eAddressTypeInvalid ) ;
2010-12-14 10:59:59 +08:00
}
}
2010-12-15 13:08:08 +08:00
2011-04-23 07:53:53 +08:00
if ( m_deref_valobj )
2010-12-15 13:08:08 +08:00
{
error . Clear ( ) ;
2011-04-23 07:53:53 +08:00
return m_deref_valobj - > GetSP ( ) ;
2010-12-15 13:08:08 +08:00
}
2010-12-14 10:59:59 +08:00
else
{
2010-12-15 13:08:08 +08:00
StreamString strm ;
A few of the issue I have been trying to track down and fix have been due to
the way LLDB lazily gets complete definitions for types within the debug info.
When we run across a class/struct/union definition in the DWARF, we will only
parse the full definition if we need to. This works fine for top level types
that are assigned directly to variables and arguments, but when we have a
variable with a class, lets say "A" for this example, that has a member:
"B *m_b". Initially we don't need to hunt down a definition for this class
unless we are ever asked to do something with it ("expr m_b->getDecl()" for
example). With my previous approach to lazy type completion, we would be able
to take a "A *a" and get a complete type for it, but we wouldn't be able to
then do an "a->m_b->getDecl()" unless we always expanded all types within a
class prior to handing out the type. Expanding everything is very costly and
it would be great if there were a better way.
A few months ago I worked with the llvm/clang folks to have the
ExternalASTSource class be able to complete classes if there weren't completed
yet:
class ExternalASTSource {
....
virtual void
CompleteType (clang::TagDecl *Tag);
virtual void
CompleteType (clang::ObjCInterfaceDecl *Class);
};
This was great, because we can now have the class that is producing the AST
(SymbolFileDWARF and SymbolFileDWARFDebugMap) sign up as external AST sources
and the object that creates the forward declaration types can now also
complete them anywhere within the clang type system.
This patch makes a few major changes:
- lldb_private::Module classes now own the AST context. Previously the TypeList
objects did.
- The DWARF parsers now sign up as an external AST sources so they can complete
types.
- All of the pure clang type system wrapper code we have in LLDB (ClangASTContext,
ClangASTType, and more) can now be iterating through children of any type,
and if a class/union/struct type (clang::RecordType or ObjC interface)
is found that is incomplete, we can ask the AST to get the definition.
- The SymbolFileDWARFDebugMap class now will create and use a single AST that
all child SymbolFileDWARF classes will share (much like what happens when
we have a complete linked DWARF for an executable).
We will need to modify some of the ClangUserExpression code to take more
advantage of this completion ability in the near future. Meanwhile we should
be better off now that we can be accessing any children of variables through
pointers and always be able to resolve the clang type if needed.
llvm-svn: 123613
2011-01-17 11:46:26 +08:00
GetExpressionPath ( strm , true ) ;
2010-12-15 13:08:08 +08:00
if ( is_pointer_type )
error . SetErrorStringWithFormat ( " dereference failed: (%s) %s " , GetTypeName ( ) . AsCString ( " <invalid type> " ) , strm . GetString ( ) . c_str ( ) ) ;
else
error . SetErrorStringWithFormat ( " not a pointer type: (%s) %s " , GetTypeName ( ) . AsCString ( " <invalid type> " ) , strm . GetString ( ) . c_str ( ) ) ;
2011-04-23 07:53:53 +08:00
return ValueObjectSP ( ) ;
2010-12-14 10:59:59 +08:00
}
}
2011-09-02 09:15:17 +08:00
ValueObjectSP
2010-12-15 13:08:08 +08:00
ValueObject : : AddressOf ( Error & error )
2010-12-14 10:59:59 +08:00
{
2011-04-16 08:01:13 +08:00
if ( m_addr_of_valobj_sp )
return m_addr_of_valobj_sp ;
2011-03-25 05:19:54 +08:00
AddressType address_type = eAddressTypeInvalid ;
2010-12-14 10:59:59 +08:00
const bool scalar_is_load_address = false ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
addr_t addr = GetAddressOf ( scalar_is_load_address , & address_type ) ;
2010-12-15 13:08:08 +08:00
error . Clear ( ) ;
2015-05-05 03:43:34 +08:00
if ( addr ! = LLDB_INVALID_ADDRESS & & address_type ! = eAddressTypeHost )
2010-12-14 10:59:59 +08:00
{
switch ( address_type )
{
case eAddressTypeInvalid :
2010-12-15 13:08:08 +08:00
{
StreamString expr_path_strm ;
A few of the issue I have been trying to track down and fix have been due to
the way LLDB lazily gets complete definitions for types within the debug info.
When we run across a class/struct/union definition in the DWARF, we will only
parse the full definition if we need to. This works fine for top level types
that are assigned directly to variables and arguments, but when we have a
variable with a class, lets say "A" for this example, that has a member:
"B *m_b". Initially we don't need to hunt down a definition for this class
unless we are ever asked to do something with it ("expr m_b->getDecl()" for
example). With my previous approach to lazy type completion, we would be able
to take a "A *a" and get a complete type for it, but we wouldn't be able to
then do an "a->m_b->getDecl()" unless we always expanded all types within a
class prior to handing out the type. Expanding everything is very costly and
it would be great if there were a better way.
A few months ago I worked with the llvm/clang folks to have the
ExternalASTSource class be able to complete classes if there weren't completed
yet:
class ExternalASTSource {
....
virtual void
CompleteType (clang::TagDecl *Tag);
virtual void
CompleteType (clang::ObjCInterfaceDecl *Class);
};
This was great, because we can now have the class that is producing the AST
(SymbolFileDWARF and SymbolFileDWARFDebugMap) sign up as external AST sources
and the object that creates the forward declaration types can now also
complete them anywhere within the clang type system.
This patch makes a few major changes:
- lldb_private::Module classes now own the AST context. Previously the TypeList
objects did.
- The DWARF parsers now sign up as an external AST sources so they can complete
types.
- All of the pure clang type system wrapper code we have in LLDB (ClangASTContext,
ClangASTType, and more) can now be iterating through children of any type,
and if a class/union/struct type (clang::RecordType or ObjC interface)
is found that is incomplete, we can ask the AST to get the definition.
- The SymbolFileDWARFDebugMap class now will create and use a single AST that
all child SymbolFileDWARF classes will share (much like what happens when
we have a complete linked DWARF for an executable).
We will need to modify some of the ClangUserExpression code to take more
advantage of this completion ability in the near future. Meanwhile we should
be better off now that we can be accessing any children of variables through
pointers and always be able to resolve the clang type if needed.
llvm-svn: 123613
2011-01-17 11:46:26 +08:00
GetExpressionPath ( expr_path_strm , true ) ;
2010-12-15 13:08:08 +08:00
error . SetErrorStringWithFormat ( " '%s' is not in memory " , expr_path_strm . GetString ( ) . c_str ( ) ) ;
}
2010-12-14 10:59:59 +08:00
break ;
2010-12-15 13:08:08 +08:00
2010-12-14 10:59:59 +08:00
case eAddressTypeFile :
case eAddressTypeLoad :
{
2013-07-12 06:46:58 +08:00
ClangASTType clang_type = GetClangType ( ) ;
if ( clang_type )
2010-12-14 10:59:59 +08:00
{
std : : string name ( 1 , ' & ' ) ;
name . append ( m_name . AsCString ( " " ) ) ;
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
m_addr_of_valobj_sp = ValueObjectConstResult : : Create ( exe_ctx . GetBestExecutionContextScope ( ) ,
2013-07-12 06:46:58 +08:00
clang_type . GetPointerType ( ) ,
2011-04-23 07:53:53 +08:00
ConstString ( name . c_str ( ) ) ,
addr ,
eAddressTypeInvalid ,
m_data . GetAddressByteSize ( ) ) ;
2010-12-14 10:59:59 +08:00
}
}
break ;
2015-05-05 03:43:34 +08:00
default :
break ;
2010-12-14 10:59:59 +08:00
}
}
2013-04-20 03:47:32 +08:00
else
{
StreamString expr_path_strm ;
GetExpressionPath ( expr_path_strm , true ) ;
error . SetErrorStringWithFormat ( " '%s' doesn't have a valid address " , expr_path_strm . GetString ( ) . c_str ( ) ) ;
}
2011-04-16 08:01:13 +08:00
return m_addr_of_valobj_sp ;
2010-12-14 10:59:59 +08:00
}
2012-02-03 13:34:10 +08:00
ValueObjectSP
ValueObject : : Cast ( const ClangASTType & clang_ast_type )
{
2012-02-04 10:27:34 +08:00
return ValueObjectCast : : Create ( * this , GetName ( ) , clang_ast_type ) ;
2012-02-03 13:34:10 +08:00
}
2011-05-06 07:32:56 +08:00
2011-09-02 09:15:17 +08:00
ValueObjectSP
2011-05-06 07:32:56 +08:00
ValueObject : : CastPointerType ( const char * name , ClangASTType & clang_ast_type )
{
2011-09-02 09:15:17 +08:00
ValueObjectSP valobj_sp ;
2011-05-06 07:32:56 +08:00
AddressType address_type ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
addr_t ptr_value = GetPointerValue ( & address_type ) ;
2011-05-06 07:32:56 +08:00
if ( ptr_value ! = LLDB_INVALID_ADDRESS )
{
2012-02-24 09:59:29 +08:00
Address ptr_addr ( ptr_value ) ;
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
valobj_sp = ValueObjectMemory : : Create ( exe_ctx . GetBestExecutionContextScope ( ) ,
2011-05-06 07:32:56 +08:00
name ,
ptr_addr ,
clang_ast_type ) ;
}
return valobj_sp ;
}
2011-09-02 09:15:17 +08:00
ValueObjectSP
2011-05-06 07:32:56 +08:00
ValueObject : : CastPointerType ( const char * name , TypeSP & type_sp )
{
2011-09-02 09:15:17 +08:00
ValueObjectSP valobj_sp ;
2011-05-06 07:32:56 +08:00
AddressType address_type ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
addr_t ptr_value = GetPointerValue ( & address_type ) ;
2011-05-06 07:32:56 +08:00
if ( ptr_value ! = LLDB_INVALID_ADDRESS )
{
2012-02-24 09:59:29 +08:00
Address ptr_addr ( ptr_value ) ;
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( GetExecutionContextRef ( ) ) ;
valobj_sp = ValueObjectMemory : : Create ( exe_ctx . GetBestExecutionContextScope ( ) ,
2011-05-06 07:32:56 +08:00
name ,
ptr_addr ,
type_sp ) ;
}
return valobj_sp ;
}
2011-03-31 08:19:25 +08:00
ValueObject : : EvaluationPoint : : EvaluationPoint ( ) :
2012-02-17 15:49:44 +08:00
m_mod_id ( ) ,
m_exe_ctx_ref ( ) ,
2014-12-10 05:18:59 +08:00
m_needs_update ( true )
2011-03-31 08:19:25 +08:00
{
}
ValueObject : : EvaluationPoint : : EvaluationPoint ( ExecutionContextScope * exe_scope , bool use_selected ) :
2012-02-17 15:49:44 +08:00
m_mod_id ( ) ,
m_exe_ctx_ref ( ) ,
2014-12-10 05:18:59 +08:00
m_needs_update ( true )
2011-03-31 08:19:25 +08:00
{
2012-02-17 15:49:44 +08:00
ExecutionContext exe_ctx ( exe_scope ) ;
TargetSP target_sp ( exe_ctx . GetTargetSP ( ) ) ;
if ( target_sp )
2011-03-31 08:19:25 +08:00
{
2012-02-17 15:49:44 +08:00
m_exe_ctx_ref . SetTargetSP ( target_sp ) ;
ProcessSP process_sp ( exe_ctx . GetProcessSP ( ) ) ;
if ( ! process_sp )
process_sp = target_sp - > GetProcessSP ( ) ;
2011-03-31 08:19:25 +08:00
2012-02-17 15:49:44 +08:00
if ( process_sp )
2011-03-31 08:19:25 +08:00
{
2012-02-17 15:49:44 +08:00
m_mod_id = process_sp - > GetModID ( ) ;
m_exe_ctx_ref . SetProcessSP ( process_sp ) ;
2011-08-09 10:12:22 +08:00
2012-02-17 15:49:44 +08:00
ThreadSP thread_sp ( exe_ctx . GetThreadSP ( ) ) ;
2011-03-31 08:19:25 +08:00
2012-02-17 15:49:44 +08:00
if ( ! thread_sp )
2011-03-31 08:19:25 +08:00
{
if ( use_selected )
2012-02-17 15:49:44 +08:00
thread_sp = process_sp - > GetThreadList ( ) . GetSelectedThread ( ) ;
2011-03-31 08:19:25 +08:00
}
2012-02-17 15:49:44 +08:00
if ( thread_sp )
2011-03-31 08:19:25 +08:00
{
2012-02-17 15:49:44 +08:00
m_exe_ctx_ref . SetThreadSP ( thread_sp ) ;
2011-09-22 12:58:26 +08:00
2013-11-04 17:33:30 +08:00
StackFrameSP frame_sp ( exe_ctx . GetFrameSP ( ) ) ;
2012-02-17 15:49:44 +08:00
if ( ! frame_sp )
2011-03-31 08:19:25 +08:00
{
if ( use_selected )
2012-02-17 15:49:44 +08:00
frame_sp = thread_sp - > GetSelectedFrame ( ) ;
2011-03-31 08:19:25 +08:00
}
2012-02-17 15:49:44 +08:00
if ( frame_sp )
m_exe_ctx_ref . SetFrameSP ( frame_sp ) ;
2011-03-31 08:19:25 +08:00
}
}
}
}
ValueObject : : EvaluationPoint : : EvaluationPoint ( const ValueObject : : EvaluationPoint & rhs ) :
2012-02-17 15:49:44 +08:00
m_mod_id ( ) ,
m_exe_ctx_ref ( rhs . m_exe_ctx_ref ) ,
2014-12-10 05:18:59 +08:00
m_needs_update ( true )
2011-03-31 08:19:25 +08:00
{
}
ValueObject : : EvaluationPoint : : ~ EvaluationPoint ( )
{
}
// This function checks the EvaluationPoint against the current process state. If the current
// state matches the evaluation point, or the evaluation point is already invalid, then we return
// false, meaning "no change". If the current state is different, we update our state, and return
// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
// future calls to NeedsUpdate will return true.
2011-12-10 09:49:43 +08:00
// exe_scope will be set to the current execution context scope.
2011-03-31 08:19:25 +08:00
bool
2015-05-16 09:27:00 +08:00
ValueObject : : EvaluationPoint : : SyncWithProcessState ( bool accept_invalid_exe_ctx )
2011-03-31 08:19:25 +08:00
{
2011-12-17 09:35:57 +08:00
// Start with the target, if it is NULL, then we're obviously not going to get any further:
2014-01-28 07:43:24 +08:00
const bool thread_and_frame_only_if_stopped = true ;
ExecutionContext exe_ctx ( m_exe_ctx_ref . Lock ( thread_and_frame_only_if_stopped ) ) ;
2011-12-17 09:35:57 +08:00
2012-02-17 15:49:44 +08:00
if ( exe_ctx . GetTargetPtr ( ) = = NULL )
2011-12-17 09:35:57 +08:00
return false ;
2011-03-31 08:19:25 +08:00
// If we don't have a process nothing can change.
2012-02-17 15:49:44 +08:00
Process * process = exe_ctx . GetProcessPtr ( ) ;
if ( process = = NULL )
2011-03-31 08:19:25 +08:00
return false ;
2011-12-17 09:35:57 +08:00
2011-03-31 08:19:25 +08:00
// If our stop id is the current stop ID, nothing has changed:
2012-02-17 15:49:44 +08:00
ProcessModID current_mod_id = process - > GetModID ( ) ;
2011-08-09 10:12:22 +08:00
2011-04-16 08:01:13 +08:00
// If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
// In either case, we aren't going to be able to sync with the process state.
2011-08-09 10:12:22 +08:00
if ( current_mod_id . GetStopID ( ) = = 0 )
2011-04-16 08:01:13 +08:00
return false ;
2011-12-10 09:49:43 +08:00
2012-07-17 11:23:13 +08:00
bool changed = false ;
const bool was_valid = m_mod_id . IsValid ( ) ;
if ( was_valid )
2011-08-13 05:40:01 +08:00
{
if ( m_mod_id = = current_mod_id )
{
2012-01-13 06:42:34 +08:00
// Everything is already up to date in this object, no need to
2011-08-13 05:40:01 +08:00
// update the execution context scope.
2011-12-10 09:49:43 +08:00
changed = false ;
2011-08-13 05:40:01 +08:00
}
2011-12-10 09:49:43 +08:00
else
{
m_mod_id = current_mod_id ;
m_needs_update = true ;
changed = true ;
}
2011-08-13 05:40:01 +08:00
}
2011-03-31 08:19:25 +08:00
2011-12-17 09:35:57 +08:00
// Now re-look up the thread and frame in case the underlying objects have gone away & been recreated.
// That way we'll be sure to return a valid exe_scope.
// If we used to have a thread or a frame but can't find it anymore, then mark ourselves as invalid.
2011-03-31 08:19:25 +08:00
2015-05-16 09:27:00 +08:00
if ( ! accept_invalid_exe_ctx )
2011-03-31 08:19:25 +08:00
{
2015-05-16 09:27:00 +08:00
if ( m_exe_ctx_ref . HasThreadRef ( ) )
2011-03-31 08:19:25 +08:00
{
2015-05-16 09:27:00 +08:00
ThreadSP thread_sp ( m_exe_ctx_ref . GetThreadSP ( ) ) ;
if ( thread_sp )
2011-03-31 08:19:25 +08:00
{
2015-05-16 09:27:00 +08:00
if ( m_exe_ctx_ref . HasFrameRef ( ) )
2012-02-17 15:49:44 +08:00
{
2015-05-16 09:27:00 +08:00
StackFrameSP frame_sp ( m_exe_ctx_ref . GetFrameSP ( ) ) ;
if ( ! frame_sp )
{
// We used to have a frame, but now it is gone
SetInvalid ( ) ;
changed = was_valid ;
}
2012-02-17 15:49:44 +08:00
}
2011-03-31 08:19:25 +08:00
}
2015-05-16 09:27:00 +08:00
else
{
// We used to have a thread, but now it is gone
SetInvalid ( ) ;
changed = was_valid ;
}
2011-03-31 08:19:25 +08:00
}
}
2015-05-16 09:27:00 +08:00
2011-12-10 09:49:43 +08:00
return changed ;
2011-03-31 08:19:25 +08:00
}
2011-05-03 02:13:59 +08:00
void
ValueObject : : EvaluationPoint : : SetUpdated ( )
{
2012-02-17 15:49:44 +08:00
ProcessSP process_sp ( m_exe_ctx_ref . GetProcessSP ( ) ) ;
if ( process_sp )
m_mod_id = process_sp - > GetModID ( ) ;
2011-05-03 02:13:59 +08:00
m_needs_update = false ;
}
2011-07-15 10:26:42 +08:00
void
2012-03-20 06:58:49 +08:00
ValueObject : : ClearUserVisibleData ( uint32_t clear_mask )
2011-07-15 10:26:42 +08:00
{
2012-03-20 06:58:49 +08:00
if ( ( clear_mask & eClearUserVisibleDataItemsValue ) = = eClearUserVisibleDataItemsValue )
m_value_str . clear ( ) ;
if ( ( clear_mask & eClearUserVisibleDataItemsLocation ) = = eClearUserVisibleDataItemsLocation )
m_location_str . clear ( ) ;
if ( ( clear_mask & eClearUserVisibleDataItemsSummary ) = = eClearUserVisibleDataItemsSummary )
m_summary_str . clear ( ) ;
if ( ( clear_mask & eClearUserVisibleDataItemsDescription ) = = eClearUserVisibleDataItemsDescription )
m_object_desc_str . clear ( ) ;
if ( ( clear_mask & eClearUserVisibleDataItemsSyntheticChildren ) = = eClearUserVisibleDataItemsSyntheticChildren )
{
if ( m_synthetic_value )
m_synthetic_value = NULL ;
}
2014-09-06 05:46:22 +08:00
if ( ( clear_mask & eClearUserVisibleDataItemsValidator ) = = eClearUserVisibleDataItemsValidator )
m_validation_result . reset ( ) ;
2011-07-20 03:48:13 +08:00
}
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
SymbolContextScope *
ValueObject : : GetSymbolContextScope ( )
{
if ( m_parent )
{
if ( ! m_parent - > IsPointerOrReferenceType ( ) )
return m_parent - > GetSymbolContextScope ( ) ;
}
return NULL ;
}
2012-09-14 02:27:09 +08:00
lldb : : ValueObjectSP
ValueObject : : CreateValueObjectFromExpression ( const char * name ,
const char * expression ,
const ExecutionContext & exe_ctx )
2014-12-18 05:18:43 +08:00
{
return CreateValueObjectFromExpression ( name , expression , exe_ctx , EvaluateExpressionOptions ( ) ) ;
}
lldb : : ValueObjectSP
ValueObject : : CreateValueObjectFromExpression ( const char * name ,
const char * expression ,
const ExecutionContext & exe_ctx ,
const EvaluateExpressionOptions & options )
2012-09-14 02:27:09 +08:00
{
lldb : : ValueObjectSP retval_sp ;
lldb : : TargetSP target_sp ( exe_ctx . GetTargetSP ( ) ) ;
if ( ! target_sp )
return retval_sp ;
if ( ! expression | | ! * expression )
return retval_sp ;
target_sp - > EvaluateExpression ( expression ,
exe_ctx . GetFrameSP ( ) . get ( ) ,
2014-12-18 05:18:43 +08:00
retval_sp ,
options ) ;
2012-09-14 02:27:09 +08:00
if ( retval_sp & & name & & * name )
retval_sp - > SetName ( ConstString ( name ) ) ;
return retval_sp ;
}
lldb : : ValueObjectSP
ValueObject : : CreateValueObjectFromAddress ( const char * name ,
uint64_t address ,
const ExecutionContext & exe_ctx ,
ClangASTType type )
{
2013-07-12 06:46:58 +08:00
if ( type )
2012-09-14 02:27:09 +08:00
{
2013-07-12 06:46:58 +08:00
ClangASTType pointer_type ( type . GetPointerType ( ) ) ;
if ( pointer_type )
{
lldb : : DataBufferSP buffer ( new lldb_private : : DataBufferHeap ( & address , sizeof ( lldb : : addr_t ) ) ) ;
lldb : : ValueObjectSP ptr_result_valobj_sp ( ValueObjectConstResult : : Create ( exe_ctx . GetBestExecutionContextScope ( ) ,
pointer_type ,
ConstString ( name ) ,
buffer ,
2014-12-18 05:18:43 +08:00
exe_ctx . GetByteOrder ( ) ,
2013-07-12 06:46:58 +08:00
exe_ctx . GetAddressByteSize ( ) ) ) ;
if ( ptr_result_valobj_sp )
{
ptr_result_valobj_sp - > GetValue ( ) . SetValueType ( Value : : eValueTypeLoadAddress ) ;
Error err ;
ptr_result_valobj_sp = ptr_result_valobj_sp - > Dereference ( err ) ;
if ( ptr_result_valobj_sp & & name & & * name )
ptr_result_valobj_sp - > SetName ( ConstString ( name ) ) ;
}
return ptr_result_valobj_sp ;
}
2012-09-14 02:27:09 +08:00
}
2013-07-12 06:46:58 +08:00
return lldb : : ValueObjectSP ( ) ;
2012-09-14 02:27:09 +08:00
}
lldb : : ValueObjectSP
ValueObject : : CreateValueObjectFromData ( const char * name ,
2014-04-01 07:02:25 +08:00
const DataExtractor & data ,
2012-09-14 02:27:09 +08:00
const ExecutionContext & exe_ctx ,
ClangASTType type )
{
lldb : : ValueObjectSP new_value_sp ;
new_value_sp = ValueObjectConstResult : : Create ( exe_ctx . GetBestExecutionContextScope ( ) ,
2013-07-12 06:46:58 +08:00
type ,
2012-09-14 02:27:09 +08:00
ConstString ( name ) ,
data ,
LLDB_INVALID_ADDRESS ) ;
new_value_sp - > SetAddressTypeOfChildren ( eAddressTypeLoad ) ;
if ( new_value_sp & & name & & * name )
new_value_sp - > SetName ( ConstString ( name ) ) ;
return new_value_sp ;
}
2013-04-12 06:48:58 +08:00
ModuleSP
ValueObject : : GetModule ( )
{
ValueObject * root ( GetRoot ( ) ) ;
if ( root ! = this )
return root - > GetModule ( ) ;
return lldb : : ModuleSP ( ) ;
}
ValueObject *
ValueObject : : GetRoot ( )
{
if ( m_root )
return m_root ;
2015-01-22 11:07:34 +08:00
return ( m_root = FollowParentChain ( [ ] ( ValueObject * vo ) - > bool {
return ( vo - > m_parent ! = nullptr ) ;
} ) ) ;
}
ValueObject *
ValueObject : : FollowParentChain ( std : : function < bool ( ValueObject * ) > f )
{
ValueObject * vo = this ;
while ( vo )
2013-04-12 06:48:58 +08:00
{
2015-01-22 11:07:34 +08:00
if ( f ( vo ) = = false )
break ;
vo = vo - > m_parent ;
2013-04-12 06:48:58 +08:00
}
2015-01-22 11:07:34 +08:00
return vo ;
2013-04-12 06:48:58 +08:00
}
AddressType
ValueObject : : GetAddressTypeOfChildren ( )
{
if ( m_address_type_of_ptr_or_ref_children = = eAddressTypeInvalid )
{
ValueObject * root ( GetRoot ( ) ) ;
if ( root ! = this )
return root - > GetAddressTypeOfChildren ( ) ;
}
return m_address_type_of_ptr_or_ref_children ;
}
lldb : : DynamicValueType
ValueObject : : GetDynamicValueType ( )
{
ValueObject * with_dv_info = this ;
while ( with_dv_info )
{
if ( with_dv_info - > HasDynamicValueTypeInfo ( ) )
return with_dv_info - > GetDynamicValueTypeImpl ( ) ;
with_dv_info = with_dv_info - > m_parent ;
}
return lldb : : eNoDynamicValues ;
}
2013-06-01 01:43:40 +08:00
2013-04-12 06:48:58 +08:00
lldb : : Format
ValueObject : : GetFormat ( ) const
{
const ValueObject * with_fmt_info = this ;
while ( with_fmt_info )
{
if ( with_fmt_info - > m_format ! = lldb : : eFormatDefault )
return with_fmt_info - > m_format ;
with_fmt_info = with_fmt_info - > m_parent ;
}
return m_format ;
}
Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
The way to do this is to write a synthetic child provider for your type, and have it vend the (optional) get_value function.
If get_value is defined, and it returns a valid SBValue, that SBValue's value (as in lldb_private::Value) will be used as the synthetic ValueObject's Value
The rationale for doing things this way is twofold:
- there are many possible ways to define a "value" (SBData, a Python number, ...) but SBValue seems general enough as a thing that stores a "value", so we just trade values that way and that keeps our currency trivial
- we could introduce a new level of layering (ValueObjectSyntheticValue), a new kind of formatter (synthetic value producer), but that would complicate the model (can I have a dynamic with no synthetic children but synthetic value? synthetic value with synthetic children but no dynamic?), and I really couldn't see much benefit to be reaped from this added complexity in the matrix
On the other hand, just defining a synthetic child provider with a get_value but returning no actual children is easy enough that it's not a significant road-block to adoption of this feature
Comes with a test case
llvm-svn: 219330
2014-10-09 02:27:36 +08:00
2014-11-07 05:23:20 +08:00
lldb : : LanguageType
ValueObject : : GetPreferredDisplayLanguage ( )
{
2015-01-21 09:47:13 +08:00
lldb : : LanguageType type = m_preferred_display_language ;
if ( m_preferred_display_language = = lldb : : eLanguageTypeUnknown )
2014-11-07 05:23:20 +08:00
{
2015-01-21 09:47:13 +08:00
if ( GetRoot ( ) )
2014-11-07 05:23:20 +08:00
{
2015-01-21 09:47:13 +08:00
if ( GetRoot ( ) = = this )
2014-11-07 05:23:20 +08:00
{
2015-01-21 09:47:13 +08:00
if ( StackFrameSP frame_sp = GetFrameSP ( ) )
{
const SymbolContext & sc ( frame_sp - > GetSymbolContext ( eSymbolContextCompUnit ) ) ;
if ( CompileUnit * cu = sc . comp_unit )
type = cu - > GetLanguage ( ) ;
}
}
else
{
type = GetRoot ( ) - > GetPreferredDisplayLanguage ( ) ;
2014-11-07 05:23:20 +08:00
}
}
}
2015-01-21 09:47:13 +08:00
return ( m_preferred_display_language = type ) ; // only compute it once
}
void
ValueObject : : SetPreferredDisplayLanguage ( lldb : : LanguageType lt )
{
m_preferred_display_language = lt ;
2014-11-07 05:23:20 +08:00
}
Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
The way to do this is to write a synthetic child provider for your type, and have it vend the (optional) get_value function.
If get_value is defined, and it returns a valid SBValue, that SBValue's value (as in lldb_private::Value) will be used as the synthetic ValueObject's Value
The rationale for doing things this way is twofold:
- there are many possible ways to define a "value" (SBData, a Python number, ...) but SBValue seems general enough as a thing that stores a "value", so we just trade values that way and that keeps our currency trivial
- we could introduce a new level of layering (ValueObjectSyntheticValue), a new kind of formatter (synthetic value producer), but that would complicate the model (can I have a dynamic with no synthetic children but synthetic value? synthetic value with synthetic children but no dynamic?), and I really couldn't see much benefit to be reaped from this added complexity in the matrix
On the other hand, just defining a synthetic child provider with a get_value but returning no actual children is easy enough that it's not a significant road-block to adoption of this feature
Comes with a test case
llvm-svn: 219330
2014-10-09 02:27:36 +08:00
bool
ValueObject : : CanProvideValue ( )
{
2014-12-10 05:18:59 +08:00
// we need to support invalid types as providers of values because some bare-board
// debugging scenarios have no notion of types, but still manage to have raw numeric
// values for things like registers. sigh.
const ClangASTType & type ( GetClangType ( ) ) ;
return ( false = = type . IsValid ( ) ) | | ( 0 ! = ( type . GetTypeInfo ( ) & eTypeHasValue ) ) ;
}
bool
ValueObject : : IsChecksumEmpty ( )
{
return m_value_checksum . empty ( ) ;
Extend synthetic children to produce synthetic values (as in, those that GetValueAsUnsigned(), GetValueAsCString() would return)
The way to do this is to write a synthetic child provider for your type, and have it vend the (optional) get_value function.
If get_value is defined, and it returns a valid SBValue, that SBValue's value (as in lldb_private::Value) will be used as the synthetic ValueObject's Value
The rationale for doing things this way is twofold:
- there are many possible ways to define a "value" (SBData, a Python number, ...) but SBValue seems general enough as a thing that stores a "value", so we just trade values that way and that keeps our currency trivial
- we could introduce a new level of layering (ValueObjectSyntheticValue), a new kind of formatter (synthetic value producer), but that would complicate the model (can I have a dynamic with no synthetic children but synthetic value? synthetic value with synthetic children but no dynamic?), and I really couldn't see much benefit to be reaped from this added complexity in the matrix
On the other hand, just defining a synthetic child provider with a get_value but returning no actual children is easy enough that it's not a significant road-block to adoption of this feature
Comes with a test case
llvm-svn: 219330
2014-10-09 02:27:36 +08:00
}
2014-12-09 07:13:56 +08:00
ValueObjectSP
ValueObject : : Persist ( )
{
if ( ! UpdateValueIfNeeded ( ) )
return nullptr ;
TargetSP target_sp ( GetTargetSP ( ) ) ;
if ( ! target_sp )
return nullptr ;
ConstString name ( target_sp - > GetPersistentVariables ( ) . GetNextPersistentVariableName ( ) ) ;
ClangExpressionVariableSP clang_var_sp ( new ClangExpressionVariable ( target_sp . get ( ) , GetValue ( ) , name ) ) ;
if ( clang_var_sp )
{
clang_var_sp - > m_live_sp = clang_var_sp - > m_frozen_sp ;
clang_var_sp - > m_flags | = ClangExpressionVariable : : EVIsProgramReference ;
target_sp - > GetPersistentVariables ( ) . AddVariable ( clang_var_sp ) ;
}
return clang_var_sp - > GetValueObject ( ) ;
}
2014-12-10 03:51:20 +08:00
bool
ValueObject : : IsSyntheticChildrenGenerated ( )
{
return m_is_synthetic_children_generated ;
}
void
ValueObject : : SetSyntheticChildrenGenerated ( bool b )
{
m_is_synthetic_children_generated = b ;
}