ValueObject.cpp revision 263363
131606Syokota//===-- ValueObject.cpp -----------------------------------------*- C++ -*-===// 231606Syokota// 331606Syokota// The LLVM Compiler Infrastructure 431606Syokota// 531606Syokota// This file is distributed under the University of Illinois Open Source 631606Syokota// License. See LICENSE.TXT for details. 731606Syokota// 831606Syokota//===----------------------------------------------------------------------===// 931606Syokota 1031606Syokota#include "lldb/lldb-python.h" 1131606Syokota 1231606Syokota#include "lldb/Core/ValueObject.h" 1331606Syokota 1431606Syokota// C Includes 1531606Syokota#include <stdlib.h> 1631606Syokota 1731606Syokota// C++ Includes 1831606Syokota// Other libraries and framework includes 1931606Syokota#include "llvm/Support/raw_ostream.h" 2031606Syokota#include "clang/AST/Type.h" 2131606Syokota 2231606Syokota// Project includes 2331606Syokota#include "lldb/Core/DataBufferHeap.h" 2431606Syokota#include "lldb/Core/Debugger.h" 2531606Syokota#include "lldb/Core/Log.h" 2631606Syokota#include "lldb/Core/Module.h" 2750476Speter#include "lldb/Core/StreamString.h" 2831606Syokota#include "lldb/Core/ValueObjectCast.h" 2931606Syokota#include "lldb/Core/ValueObjectChild.h" 3053200Sphantom#include "lldb/Core/ValueObjectConstResult.h" 3179538Sru#include "lldb/Core/ValueObjectDynamicValue.h" 3231606Syokota#include "lldb/Core/ValueObjectList.h" 3331606Syokota#include "lldb/Core/ValueObjectMemory.h" 3431606Syokota#include "lldb/Core/ValueObjectSyntheticFilter.h" 3531606Syokota 3684306Sru#include "lldb/DataFormatters/DataVisualization.h" 3731606Syokota#include "lldb/DataFormatters/ValueObjectPrinter.h" 3831606Syokota 3931606Syokota#include "lldb/Host/Endian.h" 4054142Syokota 4154142Syokota#include "lldb/Interpreter/CommandInterpreter.h" 4231606Syokota#include "lldb/Interpreter/ScriptInterpreterPython.h" 4331606Syokota 4431606Syokota#include "lldb/Symbol/ClangASTType.h" 4554142Syokota#include "lldb/Symbol/ClangASTContext.h" 4631606Syokota#include "lldb/Symbol/Type.h" 4731606Syokota 4879727Sschweikh#include "lldb/Target/ExecutionContext.h" 4931606Syokota#include "lldb/Target/LanguageRuntime.h" 5031606Syokota#include "lldb/Target/ObjCLanguageRuntime.h" 5131606Syokota#include "lldb/Target/Process.h" 5231606Syokota#include "lldb/Target/RegisterContext.h" 5331606Syokota#include "lldb/Target/Target.h" 5431606Syokota#include "lldb/Target/Thread.h" 5531606Syokota 5631606Syokotausing namespace lldb; 5731606Syokotausing namespace lldb_private; 5831606Syokotausing namespace lldb_utility; 5979727Sschweikh 6031606Syokotastatic user_id_t g_value_obj_uid = 0; 6131606Syokota 6231606Syokota//---------------------------------------------------------------------- 6331606Syokota// ValueObject constructor 6431606Syokota//---------------------------------------------------------------------- 6531606SyokotaValueObject::ValueObject (ValueObject &parent) : 6631606Syokota UserID (++g_value_obj_uid), // Unique identifier for every value object 6731606Syokota m_parent (&parent), 6831606Syokota m_root (NULL), 6979727Sschweikh m_update_point (parent.GetUpdatePoint ()), 7031606Syokota m_name (), 7131606Syokota m_data (), 7231606Syokota m_value (), 7379727Sschweikh m_error (), 7479727Sschweikh m_value_str (), 7531606Syokota m_old_value_str (), 7631606Syokota m_location_str (), 7731606Syokota m_summary_str (), 7879727Sschweikh m_object_desc_str (), 7931606Syokota m_manager(parent.GetManager()), 8031606Syokota m_children (), 8131606Syokota m_synthetic_children (), 8231606Syokota m_dynamic_value (NULL), 8331606Syokota m_synthetic_value(NULL), 8431606Syokota m_deref_valobj(NULL), 8531606Syokota m_format (eFormatDefault), 8631606Syokota m_last_format (eFormatDefault), 8757676Ssheldonh m_last_format_mgr_revision(0), 8857676Ssheldonh m_type_summary_sp(), 8931606Syokota m_type_format_sp(), 9031606Syokota m_synthetic_children_sp(), 9131606Syokota m_user_id_of_forced_summary(), 9231606Syokota m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid), 9331606Syokota m_value_is_valid (false), 9479727Sschweikh m_value_did_change (false), 9531606Syokota m_children_count_valid (false), 9631606Syokota m_old_value_valid (false), 9779727Sschweikh m_is_deref_of_parent (false), 9831606Syokota m_is_array_item_for_pointer(false), 9931606Syokota m_is_bitfield_for_scalar(false), 10079727Sschweikh m_is_child_at_offset(false), 101131530Sru m_is_getting_summary(false), 102131530Sru m_did_calculate_complete_objc_class_type(false) 10331606Syokota{ 10431606Syokota m_manager->ManageObject(this); 10579727Sschweikh} 106131530Sru 107131530Sru//---------------------------------------------------------------------- 10831606Syokota// ValueObject constructor 10931606Syokota//---------------------------------------------------------------------- 11057676SsheldonhValueObject::ValueObject (ExecutionContextScope *exe_scope, 11179727Sschweikh AddressType child_ptr_or_ref_addr_type) : 11250103Schris UserID (++g_value_obj_uid), // Unique identifier for every value object 11331606Syokota m_parent (NULL), 11457676Ssheldonh m_root (NULL), 11579727Sschweikh m_update_point (exe_scope), 11650103Schris m_name (), 11731606Syokota m_data (), 11831606Syokota m_value (), 11957676Ssheldonh m_error (), 12057676Ssheldonh m_value_str (), 12131606Syokota m_old_value_str (), 12257676Ssheldonh m_location_str (), 12357676Ssheldonh m_summary_str (), 12431606Syokota m_object_desc_str (), 12531606Syokota m_manager(), 12631606Syokota m_children (), 12731606Syokota m_synthetic_children (), 12857676Ssheldonh m_dynamic_value (NULL), 12979727Sschweikh m_synthetic_value(NULL), 13031606Syokota m_deref_valobj(NULL), 13131606Syokota m_format (eFormatDefault), 13279727Sschweikh m_last_format (eFormatDefault), 13379727Sschweikh m_last_format_mgr_revision(0), 13431606Syokota m_type_summary_sp(), 13531606Syokota m_type_format_sp(), 13631606Syokota m_synthetic_children_sp(), 13731606Syokota m_user_id_of_forced_summary(), 13831606Syokota m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type), 13931606Syokota m_value_is_valid (false), 14031606Syokota m_value_did_change (false), 14157676Ssheldonh m_children_count_valid (false), 14257676Ssheldonh m_old_value_valid (false), 14357676Ssheldonh m_is_deref_of_parent (false), 14479727Sschweikh m_is_array_item_for_pointer(false), 14531606Syokota m_is_bitfield_for_scalar(false), 14631606Syokota m_is_child_at_offset(false), 14731606Syokota m_is_getting_summary(false), 14831606Syokota m_did_calculate_complete_objc_class_type(false) 14931606Syokota{ 15031606Syokota m_manager = new ValueObjectManager(); 15131606Syokota m_manager->ManageObject (this); 15231606Syokota} 15331606Syokota 15479727Sschweikh//---------------------------------------------------------------------- 15531606Syokota// Destructor 15631606Syokota//---------------------------------------------------------------------- 15731606SyokotaValueObject::~ValueObject () 15831606Syokota{ 15931606Syokota} 16031606Syokota 16131606Syokotabool 16231606SyokotaValueObject::UpdateValueIfNeeded (bool update_format) 16331606Syokota{ 16431606Syokota 16531606Syokota bool did_change_formats = false; 16631606Syokota 16731606Syokota if (update_format) 16831606Syokota did_change_formats = UpdateFormatsIfNeeded(); 16931606Syokota 17031606Syokota // If this is a constant value, then our success is predicated on whether 17131606Syokota // we have an error or not 17257676Ssheldonh if (GetIsConstant()) 17357676Ssheldonh { 17431606Syokota // if you are constant, things might still have changed behind your back 17531606Syokota // (e.g. you are a frozen object and things have changed deeper than you cared to freeze-dry yourself) 17631606Syokota // in this case, your value has not changed, but "computed" entries might have, so you might now have 17731606Syokota // a different summary, or a different object description. clear these so we will recompute them 17831606Syokota if (update_format && !did_change_formats) 17931606Syokota ClearUserVisibleData(eClearUserVisibleDataItemsSummary | eClearUserVisibleDataItemsDescription); 18031606Syokota return m_error.Success(); 18131606Syokota } 18231606Syokota 18331606Syokota bool first_update = m_update_point.IsFirstEvaluation(); 18454142Syokota 18531606Syokota if (m_update_point.NeedsUpdating()) 18631606Syokota { 18731606Syokota m_update_point.SetUpdated(); 18831606Syokota 18931606Syokota // Save the old value using swap to avoid a string copy which 19031606Syokota // also will clear our m_value_str 19131606Syokota if (m_value_str.empty()) 19231606Syokota { 19331606Syokota m_old_value_valid = false; 19431606Syokota } 19531606Syokota else 19631606Syokota { 19731606Syokota m_old_value_valid = true; 19831606Syokota m_old_value_str.swap (m_value_str); 19931606Syokota ClearUserVisibleData(eClearUserVisibleDataItemsValue); 20031606Syokota } 20179727Sschweikh 20231606Syokota ClearUserVisibleData(); 20379727Sschweikh 20431606Syokota if (IsInScope()) 20531606Syokota { 20631606Syokota const bool value_was_valid = GetValueIsValid(); 20731606Syokota SetValueDidChange (false); 20831606Syokota 20957676Ssheldonh m_error.Clear(); 21057676Ssheldonh 21179727Sschweikh // Call the pure virtual function to update the value 21231606Syokota bool success = UpdateValue (); 21331606Syokota 21431606Syokota SetValueIsValid (success); 21531606Syokota 21631606Syokota if (first_update) 21731606Syokota SetValueDidChange (false); 21831606Syokota else if (!m_value_did_change && success == false) 21931606Syokota { 22031606Syokota // The value wasn't gotten successfully, so we mark this 22131606Syokota // as changed if the value used to be valid and now isn't 22231606Syokota SetValueDidChange (value_was_valid); 22331606Syokota } 22431606Syokota } 22531606Syokota else 22631606Syokota { 22731606Syokota m_error.SetErrorString("out of scope"); 22831606Syokota } 22931606Syokota } 23079727Sschweikh return m_error.Success(); 23131606Syokota} 23279727Sschweikh 23331606Syokotabool 23431606SyokotaValueObject::UpdateFormatsIfNeeded() 23531606Syokota{ 23631606Syokota Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 23731606Syokota if (log) 23879727Sschweikh log->Printf("[%s %p] checking for FormatManager revisions. ValueObject rev: %d - Global rev: %d", 239131530Sru GetName().GetCString(), 240131530Sru this, 24131606Syokota m_last_format_mgr_revision, 24231606Syokota DataVisualization::GetCurrentRevision()); 24331606Syokota 24431606Syokota bool any_change = false; 24579727Sschweikh 24631606Syokota if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision())) 24731606Syokota { 24831606Syokota SetValueFormat(DataVisualization::GetFormat (*this, eNoDynamicValues)); 24931606Syokota SetSummaryFormat(DataVisualization::GetSummaryFormat (*this, GetDynamicValueType())); 25031606Syokota#ifndef LLDB_DISABLE_PYTHON 25131606Syokota SetSyntheticChildren(DataVisualization::GetSyntheticChildren (*this, GetDynamicValueType())); 25231606Syokota#endif 25331606Syokota 25431606Syokota m_last_format_mgr_revision = DataVisualization::GetCurrentRevision(); 25531606Syokota 25631606Syokota any_change = true; 25731606Syokota } 25831606Syokota 25931606Syokota return any_change; 26031606Syokota 26131606Syokota} 26231606Syokota 26331606Syokotavoid 26431606SyokotaValueObject::SetNeedsUpdate () 26531606Syokota{ 26631606Syokota m_update_point.SetNeedsUpdate(); 26757676Ssheldonh // We have to clear the value string here so ConstResult children will notice if their values are 26857676Ssheldonh // changed by hand (i.e. with SetValueAsCString). 26931606Syokota ClearUserVisibleData(eClearUserVisibleDataItemsValue); 27031606Syokota} 27131606Syokota 27231606Syokotavoid 27331606SyokotaValueObject::ClearDynamicTypeInformation () 27431606Syokota{ 27531606Syokota m_children_count_valid = false; 27631606Syokota m_did_calculate_complete_objc_class_type = false; 27731606Syokota m_last_format_mgr_revision = 0; 27831606Syokota m_override_type = ClangASTType(); 27931606Syokota SetValueFormat(lldb::TypeFormatImplSP()); 28031606Syokota SetSummaryFormat(lldb::TypeSummaryImplSP()); 28179727Sschweikh SetSyntheticChildren(lldb::SyntheticChildrenSP()); 28279727Sschweikh} 28331606Syokota 28457676SsheldonhClangASTType 28557676SsheldonhValueObject::MaybeCalculateCompleteType () 28631606Syokota{ 28731606Syokota ClangASTType clang_type(GetClangTypeImpl()); 28831606Syokota 28931606Syokota if (m_did_calculate_complete_objc_class_type) 29079727Sschweikh { 29131606Syokota if (m_override_type.IsValid()) 29231606Syokota return m_override_type; 29331606Syokota else 29431606Syokota return clang_type; 29531606Syokota } 29631606Syokota 29779727Sschweikh ClangASTType class_type; 29831606Syokota bool is_pointer_type = false; 29979727Sschweikh 30031606Syokota if (clang_type.IsObjCObjectPointerType(&class_type)) 30131606Syokota { 30231606Syokota is_pointer_type = true; 30331606Syokota } 30431606Syokota else if (clang_type.IsObjCObjectOrInterfaceType()) 30531606Syokota { 30631606Syokota class_type = clang_type; 30731606Syokota } 30879727Sschweikh else 30979727Sschweikh { 31031606Syokota return clang_type; 31131606Syokota } 31231606Syokota 31379727Sschweikh m_did_calculate_complete_objc_class_type = true; 31431606Syokota 31531606Syokota if (class_type) 31631606Syokota { 31731606Syokota ConstString class_name (class_type.GetConstTypeName()); 31831606Syokota 31931606Syokota if (class_name) 32031606Syokota { 32131606Syokota ProcessSP process_sp(GetUpdatePoint().GetExecutionContextRef().GetProcessSP()); 32231606Syokota 32331606Syokota if (process_sp) 32431606Syokota { 32531606Syokota ObjCLanguageRuntime *objc_language_runtime(process_sp->GetObjCLanguageRuntime()); 32631606Syokota 32731606Syokota if (objc_language_runtime) 32831606Syokota { 32931606Syokota TypeSP complete_objc_class_type_sp = objc_language_runtime->LookupInCompleteClassCache(class_name); 33031606Syokota 33131606Syokota if (complete_objc_class_type_sp) 33231606Syokota { 33331606Syokota ClangASTType complete_class(complete_objc_class_type_sp->GetClangFullType()); 33431606Syokota 33531606Syokota if (complete_class.GetCompleteType()) 33653054Syokota { 33779727Sschweikh if (is_pointer_type) 33831606Syokota { 33931606Syokota m_override_type = complete_class.GetPointerType(); 34031606Syokota } 34131606Syokota else 34231606Syokota { 34331606Syokota m_override_type = complete_class; 34431606Syokota } 34531606Syokota 34631606Syokota if (m_override_type.IsValid()) 34731606Syokota return m_override_type; 34831606Syokota } 34931606Syokota } 35031606Syokota } 35131606Syokota } 35231606Syokota } 35331606Syokota } 35431606Syokota return clang_type; 35531606Syokota} 35631606Syokota 35779727SschweikhClangASTType 35831606SyokotaValueObject::GetClangType () 35979727Sschweikh{ 36031606Syokota return MaybeCalculateCompleteType(); 36131606Syokota} 36231606Syokota 36379727SschweikhTypeImpl 36453054SyokotaValueObject::GetTypeImpl () 36531606Syokota{ 36631606Syokota return TypeImpl(GetClangType()); 36779727Sschweikh} 36831606Syokota 36931606SyokotaDataExtractor & 37031606SyokotaValueObject::GetDataExtractor () 37131606Syokota{ 37231606Syokota UpdateValueIfNeeded(false); 37331606Syokota return m_data; 37479727Sschweikh} 37553054Syokota 37657676Ssheldonhconst Error & 37757676SsheldonhValueObject::GetError() 37831606Syokota{ 37931606Syokota UpdateValueIfNeeded(false); 38031606Syokota return m_error; 38131606Syokota} 382244040Seadler 38331606Syokotaconst ConstString & 38431606SyokotaValueObject::GetName() const 38531606Syokota{ 38631606Syokota return m_name; 38731606Syokota} 38831606Syokota 38931606Syokotaconst char * 39054142SyokotaValueObject::GetLocationAsCString () 39154142Syokota{ 39231606Syokota return GetLocationAsCStringImpl(m_value, 39331606Syokota m_data); 39431606Syokota} 39531606Syokota 39631606Syokotaconst char * 39731606SyokotaValueObject::GetLocationAsCStringImpl (const Value& value, 39854142Syokota const DataExtractor& data) 39931606Syokota{ 40031606Syokota if (UpdateValueIfNeeded(false)) 40134504Scharnier { 40231606Syokota if (m_location_str.empty()) 403267938Sbapt { 404 StreamString sstr; 405 406 Value::ValueType value_type = value.GetValueType(); 407 408 switch (value_type) 409 { 410 case Value::eValueTypeScalar: 411 case Value::eValueTypeVector: 412 if (value.GetContextType() == Value::eContextTypeRegisterInfo) 413 { 414 RegisterInfo *reg_info = value.GetRegisterInfo(); 415 if (reg_info) 416 { 417 if (reg_info->name) 418 m_location_str = reg_info->name; 419 else if (reg_info->alt_name) 420 m_location_str = reg_info->alt_name; 421 if (m_location_str.empty()) 422 m_location_str = (reg_info->encoding == lldb::eEncodingVector) ? "vector" : "scalar"; 423 } 424 } 425 if (m_location_str.empty()) 426 m_location_str = (value_type == Value::eValueTypeVector) ? "vector" : "scalar"; 427 break; 428 429 case Value::eValueTypeLoadAddress: 430 case Value::eValueTypeFileAddress: 431 case Value::eValueTypeHostAddress: 432 { 433 uint32_t addr_nibble_size = data.GetAddressByteSize() * 2; 434 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS)); 435 m_location_str.swap(sstr.GetString()); 436 } 437 break; 438 } 439 } 440 } 441 return m_location_str.c_str(); 442} 443 444Value & 445ValueObject::GetValue() 446{ 447 return m_value; 448} 449 450const Value & 451ValueObject::GetValue() const 452{ 453 return m_value; 454} 455 456bool 457ValueObject::ResolveValue (Scalar &scalar) 458{ 459 if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything 460 { 461 ExecutionContext exe_ctx (GetExecutionContextRef()); 462 Value tmp_value(m_value); 463 scalar = tmp_value.ResolveValue(&exe_ctx); 464 if (scalar.IsValid()) 465 { 466 const uint32_t bitfield_bit_size = GetBitfieldBitSize(); 467 if (bitfield_bit_size) 468 return scalar.ExtractBitfield (bitfield_bit_size, GetBitfieldBitOffset()); 469 return true; 470 } 471 } 472 return false; 473} 474 475bool 476ValueObject::GetValueIsValid () const 477{ 478 return m_value_is_valid; 479} 480 481 482void 483ValueObject::SetValueIsValid (bool b) 484{ 485 m_value_is_valid = b; 486} 487 488bool 489ValueObject::GetValueDidChange () 490{ 491 GetValueAsCString (); 492 return m_value_did_change; 493} 494 495void 496ValueObject::SetValueDidChange (bool value_changed) 497{ 498 m_value_did_change = value_changed; 499} 500 501ValueObjectSP 502ValueObject::GetChildAtIndex (size_t idx, bool can_create) 503{ 504 ValueObjectSP child_sp; 505 // We may need to update our value if we are dynamic 506 if (IsPossibleDynamicType ()) 507 UpdateValueIfNeeded(false); 508 if (idx < GetNumChildren()) 509 { 510 // Check if we have already made the child value object? 511 if (can_create && !m_children.HasChildAtIndex(idx)) 512 { 513 // No we haven't created the child at this index, so lets have our 514 // subclass do it and cache the result for quick future access. 515 m_children.SetChildAtIndex(idx,CreateChildAtIndex (idx, false, 0)); 516 } 517 518 ValueObject* child = m_children.GetChildAtIndex(idx); 519 if (child != NULL) 520 return child->GetSP(); 521 } 522 return child_sp; 523} 524 525ValueObjectSP 526ValueObject::GetChildAtIndexPath (const std::initializer_list<size_t>& idxs, 527 size_t* index_of_error) 528{ 529 if (idxs.size() == 0) 530 return GetSP(); 531 ValueObjectSP root(GetSP()); 532 for (size_t idx : idxs) 533 { 534 root = root->GetChildAtIndex(idx, true); 535 if (!root) 536 { 537 if (index_of_error) 538 *index_of_error = idx; 539 return root; 540 } 541 } 542 return root; 543} 544 545ValueObjectSP 546ValueObject::GetChildAtIndexPath (const std::initializer_list< std::pair<size_t, bool> >& idxs, 547 size_t* index_of_error) 548{ 549 if (idxs.size() == 0) 550 return GetSP(); 551 ValueObjectSP root(GetSP()); 552 for (std::pair<size_t, bool> idx : idxs) 553 { 554 root = root->GetChildAtIndex(idx.first, idx.second); 555 if (!root) 556 { 557 if (index_of_error) 558 *index_of_error = idx.first; 559 return root; 560 } 561 } 562 return root; 563} 564 565lldb::ValueObjectSP 566ValueObject::GetChildAtIndexPath (const std::vector<size_t> &idxs, 567 size_t* index_of_error) 568{ 569 if (idxs.size() == 0) 570 return GetSP(); 571 ValueObjectSP root(GetSP()); 572 for (size_t idx : idxs) 573 { 574 root = root->GetChildAtIndex(idx, true); 575 if (!root) 576 { 577 if (index_of_error) 578 *index_of_error = idx; 579 return root; 580 } 581 } 582 return root; 583} 584 585lldb::ValueObjectSP 586ValueObject::GetChildAtIndexPath (const std::vector< std::pair<size_t, bool> > &idxs, 587 size_t* index_of_error) 588{ 589 if (idxs.size() == 0) 590 return GetSP(); 591 ValueObjectSP root(GetSP()); 592 for (std::pair<size_t, bool> idx : idxs) 593 { 594 root = root->GetChildAtIndex(idx.first, idx.second); 595 if (!root) 596 { 597 if (index_of_error) 598 *index_of_error = idx.first; 599 return root; 600 } 601 } 602 return root; 603} 604 605lldb::ValueObjectSP 606ValueObject::GetChildAtNamePath (const std::initializer_list<ConstString> &names, 607 ConstString* name_of_error) 608{ 609 if (names.size() == 0) 610 return GetSP(); 611 ValueObjectSP root(GetSP()); 612 for (ConstString name : names) 613 { 614 root = root->GetChildMemberWithName(name, true); 615 if (!root) 616 { 617 if (name_of_error) 618 *name_of_error = name; 619 return root; 620 } 621 } 622 return root; 623} 624 625lldb::ValueObjectSP 626ValueObject::GetChildAtNamePath (const std::vector<ConstString> &names, 627 ConstString* name_of_error) 628{ 629 if (names.size() == 0) 630 return GetSP(); 631 ValueObjectSP root(GetSP()); 632 for (ConstString name : names) 633 { 634 root = root->GetChildMemberWithName(name, true); 635 if (!root) 636 { 637 if (name_of_error) 638 *name_of_error = name; 639 return root; 640 } 641 } 642 return root; 643} 644 645lldb::ValueObjectSP 646ValueObject::GetChildAtNamePath (const std::initializer_list< std::pair<ConstString, bool> > &names, 647 ConstString* name_of_error) 648{ 649 if (names.size() == 0) 650 return GetSP(); 651 ValueObjectSP root(GetSP()); 652 for (std::pair<ConstString, bool> name : names) 653 { 654 root = root->GetChildMemberWithName(name.first, name.second); 655 if (!root) 656 { 657 if (name_of_error) 658 *name_of_error = name.first; 659 return root; 660 } 661 } 662 return root; 663} 664 665lldb::ValueObjectSP 666ValueObject::GetChildAtNamePath (const std::vector< std::pair<ConstString, bool> > &names, 667 ConstString* name_of_error) 668{ 669 if (names.size() == 0) 670 return GetSP(); 671 ValueObjectSP root(GetSP()); 672 for (std::pair<ConstString, bool> name : names) 673 { 674 root = root->GetChildMemberWithName(name.first, name.second); 675 if (!root) 676 { 677 if (name_of_error) 678 *name_of_error = name.first; 679 return root; 680 } 681 } 682 return root; 683} 684 685size_t 686ValueObject::GetIndexOfChildWithName (const ConstString &name) 687{ 688 bool omit_empty_base_classes = true; 689 return GetClangType().GetIndexOfChildWithName (name.GetCString(), omit_empty_base_classes); 690} 691 692ValueObjectSP 693ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create) 694{ 695 // when getting a child by name, it could be buried inside some base 696 // classes (which really aren't part of the expression path), so we 697 // need a vector of indexes that can get us down to the correct child 698 ValueObjectSP child_sp; 699 700 // We may need to update our value if we are dynamic 701 if (IsPossibleDynamicType ()) 702 UpdateValueIfNeeded(false); 703 704 std::vector<uint32_t> child_indexes; 705 bool omit_empty_base_classes = true; 706 const size_t num_child_indexes = GetClangType().GetIndexOfChildMemberWithName (name.GetCString(), 707 omit_empty_base_classes, 708 child_indexes); 709 if (num_child_indexes > 0) 710 { 711 std::vector<uint32_t>::const_iterator pos = child_indexes.begin (); 712 std::vector<uint32_t>::const_iterator end = child_indexes.end (); 713 714 child_sp = GetChildAtIndex(*pos, can_create); 715 for (++pos; pos != end; ++pos) 716 { 717 if (child_sp) 718 { 719 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create)); 720 child_sp = new_child_sp; 721 } 722 else 723 { 724 child_sp.reset(); 725 } 726 727 } 728 } 729 return child_sp; 730} 731 732 733size_t 734ValueObject::GetNumChildren () 735{ 736 UpdateValueIfNeeded(); 737 if (!m_children_count_valid) 738 { 739 SetNumChildren (CalculateNumChildren()); 740 } 741 return m_children.GetChildrenCount(); 742} 743 744bool 745ValueObject::MightHaveChildren() 746{ 747 bool has_children = false; 748 const uint32_t type_info = GetTypeInfo(); 749 if (type_info) 750 { 751 if (type_info & (ClangASTType::eTypeHasChildren | 752 ClangASTType::eTypeIsPointer | 753 ClangASTType::eTypeIsReference)) 754 has_children = true; 755 } 756 else 757 { 758 has_children = GetNumChildren () > 0; 759 } 760 return has_children; 761} 762 763// Should only be called by ValueObject::GetNumChildren() 764void 765ValueObject::SetNumChildren (size_t num_children) 766{ 767 m_children_count_valid = true; 768 m_children.SetChildrenCount(num_children); 769} 770 771void 772ValueObject::SetName (const ConstString &name) 773{ 774 m_name = name; 775} 776 777ValueObject * 778ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index) 779{ 780 ValueObject *valobj = NULL; 781 782 bool omit_empty_base_classes = true; 783 bool ignore_array_bounds = synthetic_array_member; 784 std::string child_name_str; 785 uint32_t child_byte_size = 0; 786 int32_t child_byte_offset = 0; 787 uint32_t child_bitfield_bit_size = 0; 788 uint32_t child_bitfield_bit_offset = 0; 789 bool child_is_base_class = false; 790 bool child_is_deref_of_parent = false; 791 792 const bool transparent_pointers = synthetic_array_member == false; 793 ClangASTType child_clang_type; 794 795 ExecutionContext exe_ctx (GetExecutionContextRef()); 796 797 child_clang_type = GetClangType().GetChildClangTypeAtIndex (&exe_ctx, 798 GetName().GetCString(), 799 idx, 800 transparent_pointers, 801 omit_empty_base_classes, 802 ignore_array_bounds, 803 child_name_str, 804 child_byte_size, 805 child_byte_offset, 806 child_bitfield_bit_size, 807 child_bitfield_bit_offset, 808 child_is_base_class, 809 child_is_deref_of_parent); 810 if (child_clang_type) 811 { 812 if (synthetic_index) 813 child_byte_offset += child_byte_size * synthetic_index; 814 815 ConstString child_name; 816 if (!child_name_str.empty()) 817 child_name.SetCString (child_name_str.c_str()); 818 819 valobj = new ValueObjectChild (*this, 820 child_clang_type, 821 child_name, 822 child_byte_size, 823 child_byte_offset, 824 child_bitfield_bit_size, 825 child_bitfield_bit_offset, 826 child_is_base_class, 827 child_is_deref_of_parent, 828 eAddressTypeInvalid); 829 //if (valobj) 830 // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid); 831 } 832 833 return valobj; 834} 835 836bool 837ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr, 838 std::string& destination) 839{ 840 destination.clear(); 841 842 // ideally we would like to bail out if passing NULL, but if we do so 843 // we end up not providing the summary for function pointers anymore 844 if (/*summary_ptr == NULL ||*/ m_is_getting_summary) 845 return false; 846 847 m_is_getting_summary = true; 848 849 // this is a hot path in code and we prefer to avoid setting this string all too often also clearing out other 850 // information that we might care to see in a crash log. might be useful in very specific situations though. 851 /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s. Summary provider's description is %s", 852 GetTypeName().GetCString(), 853 GetName().GetCString(), 854 summary_ptr->GetDescription().c_str());*/ 855 856 if (UpdateValueIfNeeded (false)) 857 { 858 if (summary_ptr) 859 { 860 if (HasSyntheticValue()) 861 m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on the synthetic children being up-to-date (e.g. ${svar%#}) 862 summary_ptr->FormatObject(this, destination); 863 } 864 else 865 { 866 ClangASTType clang_type = GetClangType(); 867 868 // Do some default printout for function pointers 869 if (clang_type) 870 { 871 if (clang_type.IsFunctionPointerType ()) 872 { 873 StreamString sstr; 874 AddressType func_ptr_address_type = eAddressTypeInvalid; 875 addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type); 876 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS) 877 { 878 switch (func_ptr_address_type) 879 { 880 case eAddressTypeInvalid: 881 case eAddressTypeFile: 882 break; 883 884 case eAddressTypeLoad: 885 { 886 ExecutionContext exe_ctx (GetExecutionContextRef()); 887 888 Address so_addr; 889 Target *target = exe_ctx.GetTargetPtr(); 890 if (target && target->GetSectionLoadList().IsEmpty() == false) 891 { 892 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr)) 893 { 894 so_addr.Dump (&sstr, 895 exe_ctx.GetBestExecutionContextScope(), 896 Address::DumpStyleResolvedDescription, 897 Address::DumpStyleSectionNameOffset); 898 } 899 } 900 } 901 break; 902 903 case eAddressTypeHost: 904 break; 905 } 906 } 907 if (sstr.GetSize() > 0) 908 { 909 destination.assign (1, '('); 910 destination.append (sstr.GetData(), sstr.GetSize()); 911 destination.append (1, ')'); 912 } 913 } 914 } 915 } 916 } 917 m_is_getting_summary = false; 918 return !destination.empty(); 919} 920 921const char * 922ValueObject::GetSummaryAsCString () 923{ 924 if (UpdateValueIfNeeded(true) && m_summary_str.empty()) 925 { 926 GetSummaryAsCString(GetSummaryFormat().get(), 927 m_summary_str); 928 } 929 if (m_summary_str.empty()) 930 return NULL; 931 return m_summary_str.c_str(); 932} 933 934bool 935ValueObject::IsCStringContainer(bool check_pointer) 936{ 937 ClangASTType pointee_or_element_clang_type; 938 const Flags type_flags (GetTypeInfo (&pointee_or_element_clang_type)); 939 bool is_char_arr_ptr (type_flags.AnySet (ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) && 940 pointee_or_element_clang_type.IsCharType ()); 941 if (!is_char_arr_ptr) 942 return false; 943 if (!check_pointer) 944 return true; 945 if (type_flags.Test(ClangASTType::eTypeIsArray)) 946 return true; 947 addr_t cstr_address = LLDB_INVALID_ADDRESS; 948 AddressType cstr_address_type = eAddressTypeInvalid; 949 cstr_address = GetAddressOf (true, &cstr_address_type); 950 return (cstr_address != LLDB_INVALID_ADDRESS); 951} 952 953size_t 954ValueObject::GetPointeeData (DataExtractor& data, 955 uint32_t item_idx, 956 uint32_t item_count) 957{ 958 ClangASTType pointee_or_element_clang_type; 959 const uint32_t type_info = GetTypeInfo (&pointee_or_element_clang_type); 960 const bool is_pointer_type = type_info & ClangASTType::eTypeIsPointer; 961 const bool is_array_type = type_info & ClangASTType::eTypeIsArray; 962 if (!(is_pointer_type || is_array_type)) 963 return 0; 964 965 if (item_count == 0) 966 return 0; 967 968 const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize(); 969 const uint64_t bytes = item_count * item_type_size; 970 const uint64_t offset = item_idx * item_type_size; 971 972 if (item_idx == 0 && item_count == 1) // simply a deref 973 { 974 if (is_pointer_type) 975 { 976 Error error; 977 ValueObjectSP pointee_sp = Dereference(error); 978 if (error.Fail() || pointee_sp.get() == NULL) 979 return 0; 980 return pointee_sp->GetDataExtractor().Copy(data); 981 } 982 else 983 { 984 ValueObjectSP child_sp = GetChildAtIndex(0, true); 985 if (child_sp.get() == NULL) 986 return 0; 987 return child_sp->GetDataExtractor().Copy(data); 988 } 989 return true; 990 } 991 else /* (items > 1) */ 992 { 993 Error error; 994 lldb_private::DataBufferHeap* heap_buf_ptr = NULL; 995 lldb::DataBufferSP data_sp(heap_buf_ptr = new lldb_private::DataBufferHeap()); 996 997 AddressType addr_type; 998 lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type); 999 1000 switch (addr_type) 1001 { 1002 case eAddressTypeFile: 1003 { 1004 ModuleSP module_sp (GetModule()); 1005 if (module_sp) 1006 { 1007 addr = addr + offset; 1008 Address so_addr; 1009 module_sp->ResolveFileAddress(addr, so_addr); 1010 ExecutionContext exe_ctx (GetExecutionContextRef()); 1011 Target* target = exe_ctx.GetTargetPtr(); 1012 if (target) 1013 { 1014 heap_buf_ptr->SetByteSize(bytes); 1015 size_t bytes_read = target->ReadMemory(so_addr, false, heap_buf_ptr->GetBytes(), bytes, error); 1016 if (error.Success()) 1017 { 1018 data.SetData(data_sp); 1019 return bytes_read; 1020 } 1021 } 1022 } 1023 } 1024 break; 1025 case eAddressTypeLoad: 1026 { 1027 ExecutionContext exe_ctx (GetExecutionContextRef()); 1028 Process *process = exe_ctx.GetProcessPtr(); 1029 if (process) 1030 { 1031 heap_buf_ptr->SetByteSize(bytes); 1032 size_t bytes_read = process->ReadMemory(addr + offset, heap_buf_ptr->GetBytes(), bytes, error); 1033 if (error.Success() || bytes_read > 0) 1034 { 1035 data.SetData(data_sp); 1036 return bytes_read; 1037 } 1038 } 1039 } 1040 break; 1041 case eAddressTypeHost: 1042 { 1043 const uint64_t max_bytes = GetClangType().GetByteSize(); 1044 if (max_bytes > offset) 1045 { 1046 size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes); 1047 heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes_read); 1048 data.SetData(data_sp); 1049 return bytes_read; 1050 } 1051 } 1052 break; 1053 case eAddressTypeInvalid: 1054 break; 1055 } 1056 } 1057 return 0; 1058} 1059 1060uint64_t 1061ValueObject::GetData (DataExtractor& data) 1062{ 1063 UpdateValueIfNeeded(false); 1064 ExecutionContext exe_ctx (GetExecutionContextRef()); 1065 Error error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get()); 1066 if (error.Fail()) 1067 { 1068 if (m_data.GetByteSize()) 1069 { 1070 data = m_data; 1071 return data.GetByteSize(); 1072 } 1073 else 1074 { 1075 return 0; 1076 } 1077 } 1078 data.SetAddressByteSize(m_data.GetAddressByteSize()); 1079 data.SetByteOrder(m_data.GetByteOrder()); 1080 return data.GetByteSize(); 1081} 1082 1083bool 1084ValueObject::SetData (DataExtractor &data, Error &error) 1085{ 1086 error.Clear(); 1087 // Make sure our value is up to date first so that our location and location 1088 // type is valid. 1089 if (!UpdateValueIfNeeded(false)) 1090 { 1091 error.SetErrorString("unable to read value"); 1092 return false; 1093 } 1094 1095 uint64_t count = 0; 1096 const Encoding encoding = GetClangType().GetEncoding(count); 1097 1098 const size_t byte_size = GetByteSize(); 1099 1100 Value::ValueType value_type = m_value.GetValueType(); 1101 1102 switch (value_type) 1103 { 1104 case Value::eValueTypeScalar: 1105 { 1106 Error set_error = m_value.GetScalar().SetValueFromData(data, encoding, byte_size); 1107 1108 if (!set_error.Success()) 1109 { 1110 error.SetErrorStringWithFormat("unable to set scalar value: %s", set_error.AsCString()); 1111 return false; 1112 } 1113 } 1114 break; 1115 case Value::eValueTypeLoadAddress: 1116 { 1117 // If it is a load address, then the scalar value is the storage location 1118 // of the data, and we have to shove this value down to that load location. 1119 ExecutionContext exe_ctx (GetExecutionContextRef()); 1120 Process *process = exe_ctx.GetProcessPtr(); 1121 if (process) 1122 { 1123 addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1124 size_t bytes_written = process->WriteMemory(target_addr, 1125 data.GetDataStart(), 1126 byte_size, 1127 error); 1128 if (!error.Success()) 1129 return false; 1130 if (bytes_written != byte_size) 1131 { 1132 error.SetErrorString("unable to write value to memory"); 1133 return false; 1134 } 1135 } 1136 } 1137 break; 1138 case Value::eValueTypeHostAddress: 1139 { 1140 // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data. 1141 DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0)); 1142 m_data.SetData(buffer_sp, 0); 1143 data.CopyByteOrderedData (0, 1144 byte_size, 1145 const_cast<uint8_t *>(m_data.GetDataStart()), 1146 byte_size, 1147 m_data.GetByteOrder()); 1148 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); 1149 } 1150 break; 1151 case Value::eValueTypeFileAddress: 1152 case Value::eValueTypeVector: 1153 break; 1154 } 1155 1156 // If we have reached this point, then we have successfully changed the value. 1157 SetNeedsUpdate(); 1158 return true; 1159} 1160 1161// will compute strlen(str), but without consuming more than 1162// maxlen bytes out of str (this serves the purpose of reading 1163// chunks of a string without having to worry about 1164// missing NULL terminators in the chunk) 1165// of course, if strlen(str) > maxlen, the function will return 1166// maxlen_value (which should be != maxlen, because that allows you 1167// to know whether strlen(str) == maxlen or strlen(str) > maxlen) 1168static uint32_t 1169strlen_or_inf (const char* str, 1170 uint32_t maxlen, 1171 uint32_t maxlen_value) 1172{ 1173 uint32_t len = 0; 1174 if (str) 1175 { 1176 while(*str) 1177 { 1178 len++;str++; 1179 if (len >= maxlen) 1180 return maxlen_value; 1181 } 1182 } 1183 return len; 1184} 1185 1186size_t 1187ValueObject::ReadPointedString (Stream& s, 1188 Error& error, 1189 uint32_t max_length, 1190 bool honor_array, 1191 Format item_format) 1192{ 1193 ExecutionContext exe_ctx (GetExecutionContextRef()); 1194 Target* target = exe_ctx.GetTargetPtr(); 1195 1196 if (!target) 1197 { 1198 s << "<no target to read from>"; 1199 error.SetErrorString("no target to read from"); 1200 return 0; 1201 } 1202 1203 if (max_length == 0) 1204 max_length = target->GetMaximumSizeOfStringSummary(); 1205 1206 size_t bytes_read = 0; 1207 size_t total_bytes_read = 0; 1208 1209 ClangASTType clang_type = GetClangType(); 1210 ClangASTType elem_or_pointee_clang_type; 1211 const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type)); 1212 if (type_flags.AnySet (ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) && 1213 elem_or_pointee_clang_type.IsCharType ()) 1214 { 1215 addr_t cstr_address = LLDB_INVALID_ADDRESS; 1216 AddressType cstr_address_type = eAddressTypeInvalid; 1217 1218 size_t cstr_len = 0; 1219 bool capped_data = false; 1220 if (type_flags.Test (ClangASTType::eTypeIsArray)) 1221 { 1222 // We have an array 1223 uint64_t array_size = 0; 1224 if (clang_type.IsArrayType(NULL, &array_size, NULL)) 1225 { 1226 cstr_len = array_size; 1227 if (cstr_len > max_length) 1228 { 1229 capped_data = true; 1230 cstr_len = max_length; 1231 } 1232 } 1233 cstr_address = GetAddressOf (true, &cstr_address_type); 1234 } 1235 else 1236 { 1237 // We have a pointer 1238 cstr_address = GetPointerValue (&cstr_address_type); 1239 } 1240 1241 if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) 1242 { 1243 s << "<invalid address>"; 1244 error.SetErrorString("invalid address"); 1245 return 0; 1246 } 1247 1248 Address cstr_so_addr (cstr_address); 1249 DataExtractor data; 1250 if (cstr_len > 0 && honor_array) 1251 { 1252 // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host 1253 // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this 1254 GetPointeeData(data, 0, cstr_len); 1255 1256 if ((bytes_read = data.GetByteSize()) > 0) 1257 { 1258 total_bytes_read = bytes_read; 1259 s << '"'; 1260 data.Dump (&s, 1261 0, // Start offset in "data" 1262 item_format, 1263 1, // Size of item (1 byte for a char!) 1264 bytes_read, // How many bytes to print? 1265 UINT32_MAX, // num per line 1266 LLDB_INVALID_ADDRESS,// base address 1267 0, // bitfield bit size 1268 0); // bitfield bit offset 1269 if (capped_data) 1270 s << "..."; 1271 s << '"'; 1272 } 1273 } 1274 else 1275 { 1276 cstr_len = max_length; 1277 const size_t k_max_buf_size = 64; 1278 1279 size_t offset = 0; 1280 1281 int cstr_len_displayed = -1; 1282 bool capped_cstr = false; 1283 // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host 1284 // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this 1285 while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) 1286 { 1287 total_bytes_read += bytes_read; 1288 const char *cstr = data.PeekCStr(0); 1289 size_t len = strlen_or_inf (cstr, k_max_buf_size, k_max_buf_size+1); 1290 if (len > k_max_buf_size) 1291 len = k_max_buf_size; 1292 if (cstr && cstr_len_displayed < 0) 1293 s << '"'; 1294 1295 if (cstr_len_displayed < 0) 1296 cstr_len_displayed = len; 1297 1298 if (len == 0) 1299 break; 1300 cstr_len_displayed += len; 1301 if (len > bytes_read) 1302 len = bytes_read; 1303 if (len > cstr_len) 1304 len = cstr_len; 1305 1306 data.Dump (&s, 1307 0, // Start offset in "data" 1308 item_format, 1309 1, // Size of item (1 byte for a char!) 1310 len, // How many bytes to print? 1311 UINT32_MAX, // num per line 1312 LLDB_INVALID_ADDRESS,// base address 1313 0, // bitfield bit size 1314 0); // bitfield bit offset 1315 1316 if (len < k_max_buf_size) 1317 break; 1318 1319 if (len >= cstr_len) 1320 { 1321 capped_cstr = true; 1322 break; 1323 } 1324 1325 cstr_len -= len; 1326 offset += len; 1327 } 1328 1329 if (cstr_len_displayed >= 0) 1330 { 1331 s << '"'; 1332 if (capped_cstr) 1333 s << "..."; 1334 } 1335 } 1336 } 1337 else 1338 { 1339 error.SetErrorString("not a string object"); 1340 s << "<not a string object>"; 1341 } 1342 return total_bytes_read; 1343} 1344 1345const char * 1346ValueObject::GetObjectDescription () 1347{ 1348 1349 if (!UpdateValueIfNeeded (true)) 1350 return NULL; 1351 1352 if (!m_object_desc_str.empty()) 1353 return m_object_desc_str.c_str(); 1354 1355 ExecutionContext exe_ctx (GetExecutionContextRef()); 1356 Process *process = exe_ctx.GetProcessPtr(); 1357 if (process == NULL) 1358 return NULL; 1359 1360 StreamString s; 1361 1362 LanguageType language = GetObjectRuntimeLanguage(); 1363 LanguageRuntime *runtime = process->GetLanguageRuntime(language); 1364 1365 if (runtime == NULL) 1366 { 1367 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway... 1368 ClangASTType clang_type = GetClangType(); 1369 if (clang_type) 1370 { 1371 bool is_signed; 1372 if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType ()) 1373 { 1374 runtime = process->GetLanguageRuntime(eLanguageTypeObjC); 1375 } 1376 } 1377 } 1378 1379 if (runtime && runtime->GetObjectDescription(s, *this)) 1380 { 1381 m_object_desc_str.append (s.GetData()); 1382 } 1383 1384 if (m_object_desc_str.empty()) 1385 return NULL; 1386 else 1387 return m_object_desc_str.c_str(); 1388} 1389 1390bool 1391ValueObject::GetValueAsCString (lldb::Format format, 1392 std::string& destination) 1393{ 1394 if (GetClangType().IsAggregateType () == false && UpdateValueIfNeeded(false)) 1395 { 1396 const Value::ContextType context_type = m_value.GetContextType(); 1397 1398 if (context_type == Value::eContextTypeRegisterInfo) 1399 { 1400 const RegisterInfo *reg_info = m_value.GetRegisterInfo(); 1401 if (reg_info) 1402 { 1403 ExecutionContext exe_ctx (GetExecutionContextRef()); 1404 1405 StreamString reg_sstr; 1406 m_data.Dump (®_sstr, 1407 0, 1408 format, 1409 reg_info->byte_size, 1410 1, 1411 UINT32_MAX, 1412 LLDB_INVALID_ADDRESS, 1413 0, 1414 0, 1415 exe_ctx.GetBestExecutionContextScope()); 1416 destination.swap(reg_sstr.GetString()); 1417 } 1418 } 1419 else 1420 { 1421 ClangASTType clang_type = GetClangType (); 1422 if (clang_type) 1423 { 1424 // put custom bytes to display in this DataExtractor to override the default value logic 1425 lldb_private::DataExtractor special_format_data; 1426 if (format == eFormatCString) 1427 { 1428 Flags type_flags(clang_type.GetTypeInfo(NULL)); 1429 if (type_flags.Test(ClangASTType::eTypeIsPointer) && !type_flags.Test(ClangASTType::eTypeIsObjC)) 1430 { 1431 // if we are dumping a pointer as a c-string, get the pointee data as a string 1432 TargetSP target_sp(GetTargetSP()); 1433 if (target_sp) 1434 { 1435 size_t max_len = target_sp->GetMaximumSizeOfStringSummary(); 1436 Error error; 1437 DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0)); 1438 Address address(GetPointerValue()); 1439 if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success()) 1440 special_format_data.SetData(buffer_sp); 1441 } 1442 } 1443 } 1444 1445 StreamString sstr; 1446 ExecutionContext exe_ctx (GetExecutionContextRef()); 1447 clang_type.DumpTypeValue (&sstr, // The stream to use for display 1448 format, // Format to display this type with 1449 special_format_data.GetByteSize() ? 1450 special_format_data: m_data, // Data to extract from 1451 0, // Byte offset into "m_data" 1452 GetByteSize(), // Byte size of item in "m_data" 1453 GetBitfieldBitSize(), // Bitfield bit size 1454 GetBitfieldBitOffset(), // Bitfield bit offset 1455 exe_ctx.GetBestExecutionContextScope()); 1456 // Don't set the m_error to anything here otherwise 1457 // we won't be able to re-format as anything else. The 1458 // code for ClangASTType::DumpTypeValue() should always 1459 // return something, even if that something contains 1460 // an error messsage. "m_error" is used to detect errors 1461 // when reading the valid object, not for formatting errors. 1462 if (sstr.GetString().empty()) 1463 destination.clear(); 1464 else 1465 destination.swap(sstr.GetString()); 1466 } 1467 } 1468 return !destination.empty(); 1469 } 1470 else 1471 return false; 1472} 1473 1474const char * 1475ValueObject::GetValueAsCString () 1476{ 1477 if (UpdateValueIfNeeded(true)) 1478 { 1479 lldb::Format my_format = GetFormat(); 1480 if (my_format == lldb::eFormatDefault) 1481 { 1482 if (m_type_format_sp) 1483 my_format = m_type_format_sp->GetFormat(); 1484 else 1485 { 1486 if (m_is_bitfield_for_scalar) 1487 my_format = eFormatUnsigned; 1488 else 1489 { 1490 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo) 1491 { 1492 const RegisterInfo *reg_info = m_value.GetRegisterInfo(); 1493 if (reg_info) 1494 my_format = reg_info->format; 1495 } 1496 else 1497 { 1498 my_format = GetClangType().GetFormat(); 1499 } 1500 } 1501 } 1502 } 1503 if (my_format != m_last_format || m_value_str.empty()) 1504 { 1505 m_last_format = my_format; 1506 if (GetValueAsCString(my_format, m_value_str)) 1507 { 1508 if (!m_value_did_change && m_old_value_valid) 1509 { 1510 // The value was gotten successfully, so we consider the 1511 // value as changed if the value string differs 1512 SetValueDidChange (m_old_value_str != m_value_str); 1513 } 1514 } 1515 } 1516 } 1517 if (m_value_str.empty()) 1518 return NULL; 1519 return m_value_str.c_str(); 1520} 1521 1522// if > 8bytes, 0 is returned. this method should mostly be used 1523// to read address values out of pointers 1524uint64_t 1525ValueObject::GetValueAsUnsigned (uint64_t fail_value, bool *success) 1526{ 1527 // If our byte size is zero this is an aggregate type that has children 1528 if (!GetClangType().IsAggregateType()) 1529 { 1530 Scalar scalar; 1531 if (ResolveValue (scalar)) 1532 { 1533 if (success) 1534 *success = true; 1535 return scalar.ULongLong(fail_value); 1536 } 1537 // fallthrough, otherwise... 1538 } 1539 1540 if (success) 1541 *success = false; 1542 return fail_value; 1543} 1544 1545int64_t 1546ValueObject::GetValueAsSigned (int64_t fail_value, bool *success) 1547{ 1548 // If our byte size is zero this is an aggregate type that has children 1549 if (!GetClangType().IsAggregateType()) 1550 { 1551 Scalar scalar; 1552 if (ResolveValue (scalar)) 1553 { 1554 if (success) 1555 *success = true; 1556 return scalar.SLongLong(fail_value); 1557 } 1558 // fallthrough, otherwise... 1559 } 1560 1561 if (success) 1562 *success = false; 1563 return fail_value; 1564} 1565 1566// if any more "special cases" are added to ValueObject::DumpPrintableRepresentation() please keep 1567// this call up to date by returning true for your new special cases. We will eventually move 1568// to checking this call result before trying to display special cases 1569bool 1570ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display, 1571 Format custom_format) 1572{ 1573 Flags flags(GetTypeInfo()); 1574 if (flags.AnySet(ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) 1575 && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) 1576 { 1577 if (IsCStringContainer(true) && 1578 (custom_format == eFormatCString || 1579 custom_format == eFormatCharArray || 1580 custom_format == eFormatChar || 1581 custom_format == eFormatVectorOfChar)) 1582 return true; 1583 1584 if (flags.Test(ClangASTType::eTypeIsArray)) 1585 { 1586 if ((custom_format == eFormatBytes) || 1587 (custom_format == eFormatBytesWithASCII)) 1588 return true; 1589 1590 if ((custom_format == eFormatVectorOfChar) || 1591 (custom_format == eFormatVectorOfFloat32) || 1592 (custom_format == eFormatVectorOfFloat64) || 1593 (custom_format == eFormatVectorOfSInt16) || 1594 (custom_format == eFormatVectorOfSInt32) || 1595 (custom_format == eFormatVectorOfSInt64) || 1596 (custom_format == eFormatVectorOfSInt8) || 1597 (custom_format == eFormatVectorOfUInt128) || 1598 (custom_format == eFormatVectorOfUInt16) || 1599 (custom_format == eFormatVectorOfUInt32) || 1600 (custom_format == eFormatVectorOfUInt64) || 1601 (custom_format == eFormatVectorOfUInt8)) 1602 return true; 1603 } 1604 } 1605 return false; 1606} 1607 1608bool 1609ValueObject::DumpPrintableRepresentation(Stream& s, 1610 ValueObjectRepresentationStyle val_obj_display, 1611 Format custom_format, 1612 PrintableRepresentationSpecialCases special) 1613{ 1614 1615 Flags flags(GetTypeInfo()); 1616 1617 bool allow_special = ((special & ePrintableRepresentationSpecialCasesAllow) == ePrintableRepresentationSpecialCasesAllow); 1618 bool only_special = ((special & ePrintableRepresentationSpecialCasesOnly) == ePrintableRepresentationSpecialCasesOnly); 1619 1620 if (allow_special) 1621 { 1622 if (flags.AnySet(ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) 1623 && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) 1624 { 1625 // when being asked to get a printable display an array or pointer type directly, 1626 // try to "do the right thing" 1627 1628 if (IsCStringContainer(true) && 1629 (custom_format == eFormatCString || 1630 custom_format == eFormatCharArray || 1631 custom_format == eFormatChar || 1632 custom_format == eFormatVectorOfChar)) // print char[] & char* directly 1633 { 1634 Error error; 1635 ReadPointedString(s, 1636 error, 1637 0, 1638 (custom_format == eFormatVectorOfChar) || 1639 (custom_format == eFormatCharArray)); 1640 return !error.Fail(); 1641 } 1642 1643 if (custom_format == eFormatEnum) 1644 return false; 1645 1646 // this only works for arrays, because I have no way to know when 1647 // the pointed memory ends, and no special \0 end of data marker 1648 if (flags.Test(ClangASTType::eTypeIsArray)) 1649 { 1650 if ((custom_format == eFormatBytes) || 1651 (custom_format == eFormatBytesWithASCII)) 1652 { 1653 const size_t count = GetNumChildren(); 1654 1655 s << '['; 1656 for (size_t low = 0; low < count; low++) 1657 { 1658 1659 if (low) 1660 s << ','; 1661 1662 ValueObjectSP child = GetChildAtIndex(low,true); 1663 if (!child.get()) 1664 { 1665 s << "<invalid child>"; 1666 continue; 1667 } 1668 child->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleValue, custom_format); 1669 } 1670 1671 s << ']'; 1672 1673 return true; 1674 } 1675 1676 if ((custom_format == eFormatVectorOfChar) || 1677 (custom_format == eFormatVectorOfFloat32) || 1678 (custom_format == eFormatVectorOfFloat64) || 1679 (custom_format == eFormatVectorOfSInt16) || 1680 (custom_format == eFormatVectorOfSInt32) || 1681 (custom_format == eFormatVectorOfSInt64) || 1682 (custom_format == eFormatVectorOfSInt8) || 1683 (custom_format == eFormatVectorOfUInt128) || 1684 (custom_format == eFormatVectorOfUInt16) || 1685 (custom_format == eFormatVectorOfUInt32) || 1686 (custom_format == eFormatVectorOfUInt64) || 1687 (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly 1688 { 1689 const size_t count = GetNumChildren(); 1690 1691 Format format = FormatManager::GetSingleItemFormat(custom_format); 1692 1693 s << '['; 1694 for (size_t low = 0; low < count; low++) 1695 { 1696 1697 if (low) 1698 s << ','; 1699 1700 ValueObjectSP child = GetChildAtIndex(low,true); 1701 if (!child.get()) 1702 { 1703 s << "<invalid child>"; 1704 continue; 1705 } 1706 child->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleValue, format); 1707 } 1708 1709 s << ']'; 1710 1711 return true; 1712 } 1713 } 1714 1715 if ((custom_format == eFormatBoolean) || 1716 (custom_format == eFormatBinary) || 1717 (custom_format == eFormatChar) || 1718 (custom_format == eFormatCharPrintable) || 1719 (custom_format == eFormatComplexFloat) || 1720 (custom_format == eFormatDecimal) || 1721 (custom_format == eFormatHex) || 1722 (custom_format == eFormatHexUppercase) || 1723 (custom_format == eFormatFloat) || 1724 (custom_format == eFormatOctal) || 1725 (custom_format == eFormatOSType) || 1726 (custom_format == eFormatUnicode16) || 1727 (custom_format == eFormatUnicode32) || 1728 (custom_format == eFormatUnsigned) || 1729 (custom_format == eFormatPointer) || 1730 (custom_format == eFormatComplexInteger) || 1731 (custom_format == eFormatComplex) || 1732 (custom_format == eFormatDefault)) // use the [] operator 1733 return false; 1734 } 1735 } 1736 1737 if (only_special) 1738 return false; 1739 1740 bool var_success = false; 1741 1742 { 1743 const char *cstr = NULL; 1744 1745 // this is a local stream that we are using to ensure that the data pointed to by cstr survives 1746 // long enough for us to copy it to its destination - it is necessary to have this temporary storage 1747 // area for cases where our desired output is not backed by some other longer-term storage 1748 StreamString strm; 1749 1750 if (custom_format != eFormatInvalid) 1751 SetFormat(custom_format); 1752 1753 switch(val_obj_display) 1754 { 1755 case eValueObjectRepresentationStyleValue: 1756 cstr = GetValueAsCString(); 1757 break; 1758 1759 case eValueObjectRepresentationStyleSummary: 1760 cstr = GetSummaryAsCString(); 1761 break; 1762 1763 case eValueObjectRepresentationStyleLanguageSpecific: 1764 cstr = GetObjectDescription(); 1765 break; 1766 1767 case eValueObjectRepresentationStyleLocation: 1768 cstr = GetLocationAsCString(); 1769 break; 1770 1771 case eValueObjectRepresentationStyleChildrenCount: 1772 strm.Printf("%zu", GetNumChildren()); 1773 cstr = strm.GetString().c_str(); 1774 break; 1775 1776 case eValueObjectRepresentationStyleType: 1777 cstr = GetTypeName().AsCString(); 1778 break; 1779 1780 case eValueObjectRepresentationStyleName: 1781 cstr = GetName().AsCString(); 1782 break; 1783 1784 case eValueObjectRepresentationStyleExpressionPath: 1785 GetExpressionPath(strm, false); 1786 cstr = strm.GetString().c_str(); 1787 break; 1788 } 1789 1790 if (!cstr) 1791 { 1792 if (val_obj_display == eValueObjectRepresentationStyleValue) 1793 cstr = GetSummaryAsCString(); 1794 else if (val_obj_display == eValueObjectRepresentationStyleSummary) 1795 { 1796 if (GetClangType().IsAggregateType()) 1797 { 1798 strm.Printf("%s @ %s", GetTypeName().AsCString(), GetLocationAsCString()); 1799 cstr = strm.GetString().c_str(); 1800 } 1801 else 1802 cstr = GetValueAsCString(); 1803 } 1804 } 1805 1806 if (cstr) 1807 s.PutCString(cstr); 1808 else 1809 { 1810 if (m_error.Fail()) 1811 s.Printf("<%s>", m_error.AsCString()); 1812 else if (val_obj_display == eValueObjectRepresentationStyleSummary) 1813 s.PutCString("<no summary available>"); 1814 else if (val_obj_display == eValueObjectRepresentationStyleValue) 1815 s.PutCString("<no value available>"); 1816 else if (val_obj_display == eValueObjectRepresentationStyleLanguageSpecific) 1817 s.PutCString("<not a valid Objective-C object>"); // edit this if we have other runtimes that support a description 1818 else 1819 s.PutCString("<no printable representation>"); 1820 } 1821 1822 // we should only return false here if we could not do *anything* 1823 // even if we have an error message as output, that's a success 1824 // from our callers' perspective, so return true 1825 var_success = true; 1826 1827 if (custom_format != eFormatInvalid) 1828 SetFormat(eFormatDefault); 1829 } 1830 1831 return var_success; 1832} 1833 1834addr_t 1835ValueObject::GetAddressOf (bool scalar_is_load_address, AddressType *address_type) 1836{ 1837 if (!UpdateValueIfNeeded(false)) 1838 return LLDB_INVALID_ADDRESS; 1839 1840 switch (m_value.GetValueType()) 1841 { 1842 case Value::eValueTypeScalar: 1843 case Value::eValueTypeVector: 1844 if (scalar_is_load_address) 1845 { 1846 if(address_type) 1847 *address_type = eAddressTypeLoad; 1848 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1849 } 1850 break; 1851 1852 case Value::eValueTypeLoadAddress: 1853 case Value::eValueTypeFileAddress: 1854 case Value::eValueTypeHostAddress: 1855 { 1856 if(address_type) 1857 *address_type = m_value.GetValueAddressType (); 1858 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1859 } 1860 break; 1861 } 1862 if (address_type) 1863 *address_type = eAddressTypeInvalid; 1864 return LLDB_INVALID_ADDRESS; 1865} 1866 1867addr_t 1868ValueObject::GetPointerValue (AddressType *address_type) 1869{ 1870 addr_t address = LLDB_INVALID_ADDRESS; 1871 if(address_type) 1872 *address_type = eAddressTypeInvalid; 1873 1874 if (!UpdateValueIfNeeded(false)) 1875 return address; 1876 1877 switch (m_value.GetValueType()) 1878 { 1879 case Value::eValueTypeScalar: 1880 case Value::eValueTypeVector: 1881 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1882 break; 1883 1884 case Value::eValueTypeHostAddress: 1885 case Value::eValueTypeLoadAddress: 1886 case Value::eValueTypeFileAddress: 1887 { 1888 lldb::offset_t data_offset = 0; 1889 address = m_data.GetPointer(&data_offset); 1890 } 1891 break; 1892 } 1893 1894 if (address_type) 1895 *address_type = GetAddressTypeOfChildren(); 1896 1897 return address; 1898} 1899 1900bool 1901ValueObject::SetValueFromCString (const char *value_str, Error& error) 1902{ 1903 error.Clear(); 1904 // Make sure our value is up to date first so that our location and location 1905 // type is valid. 1906 if (!UpdateValueIfNeeded(false)) 1907 { 1908 error.SetErrorString("unable to read value"); 1909 return false; 1910 } 1911 1912 uint64_t count = 0; 1913 const Encoding encoding = GetClangType().GetEncoding (count); 1914 1915 const size_t byte_size = GetByteSize(); 1916 1917 Value::ValueType value_type = m_value.GetValueType(); 1918 1919 if (value_type == Value::eValueTypeScalar) 1920 { 1921 // If the value is already a scalar, then let the scalar change itself: 1922 m_value.GetScalar().SetValueFromCString (value_str, encoding, byte_size); 1923 } 1924 else if (byte_size <= Scalar::GetMaxByteSize()) 1925 { 1926 // If the value fits in a scalar, then make a new scalar and again let the 1927 // scalar code do the conversion, then figure out where to put the new value. 1928 Scalar new_scalar; 1929 error = new_scalar.SetValueFromCString (value_str, encoding, byte_size); 1930 if (error.Success()) 1931 { 1932 switch (value_type) 1933 { 1934 case Value::eValueTypeLoadAddress: 1935 { 1936 // If it is a load address, then the scalar value is the storage location 1937 // of the data, and we have to shove this value down to that load location. 1938 ExecutionContext exe_ctx (GetExecutionContextRef()); 1939 Process *process = exe_ctx.GetProcessPtr(); 1940 if (process) 1941 { 1942 addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1943 size_t bytes_written = process->WriteScalarToMemory (target_addr, 1944 new_scalar, 1945 byte_size, 1946 error); 1947 if (!error.Success()) 1948 return false; 1949 if (bytes_written != byte_size) 1950 { 1951 error.SetErrorString("unable to write value to memory"); 1952 return false; 1953 } 1954 } 1955 } 1956 break; 1957 case Value::eValueTypeHostAddress: 1958 { 1959 // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data. 1960 DataExtractor new_data; 1961 new_data.SetByteOrder (m_data.GetByteOrder()); 1962 1963 DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0)); 1964 m_data.SetData(buffer_sp, 0); 1965 bool success = new_scalar.GetData(new_data); 1966 if (success) 1967 { 1968 new_data.CopyByteOrderedData (0, 1969 byte_size, 1970 const_cast<uint8_t *>(m_data.GetDataStart()), 1971 byte_size, 1972 m_data.GetByteOrder()); 1973 } 1974 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); 1975 1976 } 1977 break; 1978 case Value::eValueTypeFileAddress: 1979 case Value::eValueTypeScalar: 1980 case Value::eValueTypeVector: 1981 break; 1982 } 1983 } 1984 else 1985 { 1986 return false; 1987 } 1988 } 1989 else 1990 { 1991 // We don't support setting things bigger than a scalar at present. 1992 error.SetErrorString("unable to write aggregate data type"); 1993 return false; 1994 } 1995 1996 // If we have reached this point, then we have successfully changed the value. 1997 SetNeedsUpdate(); 1998 return true; 1999} 2000 2001bool 2002ValueObject::GetDeclaration (Declaration &decl) 2003{ 2004 decl.Clear(); 2005 return false; 2006} 2007 2008ConstString 2009ValueObject::GetTypeName() 2010{ 2011 return GetClangType().GetConstTypeName(); 2012} 2013 2014ConstString 2015ValueObject::GetQualifiedTypeName() 2016{ 2017 return GetClangType().GetConstQualifiedTypeName(); 2018} 2019 2020 2021LanguageType 2022ValueObject::GetObjectRuntimeLanguage () 2023{ 2024 return GetClangType().GetMinimumLanguage (); 2025} 2026 2027void 2028ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj) 2029{ 2030 m_synthetic_children[key] = valobj; 2031} 2032 2033ValueObjectSP 2034ValueObject::GetSyntheticChild (const ConstString &key) const 2035{ 2036 ValueObjectSP synthetic_child_sp; 2037 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key); 2038 if (pos != m_synthetic_children.end()) 2039 synthetic_child_sp = pos->second->GetSP(); 2040 return synthetic_child_sp; 2041} 2042 2043uint32_t 2044ValueObject::GetTypeInfo (ClangASTType *pointee_or_element_clang_type) 2045{ 2046 return GetClangType().GetTypeInfo (pointee_or_element_clang_type); 2047} 2048 2049bool 2050ValueObject::IsPointerType () 2051{ 2052 return GetClangType().IsPointerType(); 2053} 2054 2055bool 2056ValueObject::IsArrayType () 2057{ 2058 return GetClangType().IsArrayType (NULL, NULL, NULL); 2059} 2060 2061bool 2062ValueObject::IsScalarType () 2063{ 2064 return GetClangType().IsScalarType (); 2065} 2066 2067bool 2068ValueObject::IsIntegerType (bool &is_signed) 2069{ 2070 return GetClangType().IsIntegerType (is_signed); 2071} 2072 2073bool 2074ValueObject::IsPointerOrReferenceType () 2075{ 2076 return GetClangType().IsPointerOrReferenceType (); 2077} 2078 2079bool 2080ValueObject::IsPossibleDynamicType () 2081{ 2082 ExecutionContext exe_ctx (GetExecutionContextRef()); 2083 Process *process = exe_ctx.GetProcessPtr(); 2084 if (process) 2085 return process->IsPossibleDynamicValue(*this); 2086 else 2087 return GetClangType().IsPossibleDynamicType (NULL, true, true); 2088} 2089 2090bool 2091ValueObject::IsObjCNil () 2092{ 2093 const uint32_t mask = ClangASTType::eTypeIsObjC | ClangASTType::eTypeIsPointer; 2094 bool isObjCpointer = (((GetClangType().GetTypeInfo(NULL)) & mask) == mask); 2095 if (!isObjCpointer) 2096 return false; 2097 bool canReadValue = true; 2098 bool isZero = GetValueAsUnsigned(0,&canReadValue) == 0; 2099 return canReadValue && isZero; 2100} 2101 2102ValueObjectSP 2103ValueObject::GetSyntheticArrayMember (size_t index, bool can_create) 2104{ 2105 const uint32_t type_info = GetTypeInfo (); 2106 if (type_info & ClangASTType::eTypeIsArray) 2107 return GetSyntheticArrayMemberFromArray(index, can_create); 2108 2109 if (type_info & ClangASTType::eTypeIsPointer) 2110 return GetSyntheticArrayMemberFromPointer(index, can_create); 2111 2112 return ValueObjectSP(); 2113 2114} 2115 2116ValueObjectSP 2117ValueObject::GetSyntheticArrayMemberFromPointer (size_t index, bool can_create) 2118{ 2119 ValueObjectSP synthetic_child_sp; 2120 if (IsPointerType ()) 2121 { 2122 char index_str[64]; 2123 snprintf(index_str, sizeof(index_str), "[%zu]", index); 2124 ConstString index_const_str(index_str); 2125 // Check if we have already created a synthetic array member in this 2126 // valid object. If we have we will re-use it. 2127 synthetic_child_sp = GetSyntheticChild (index_const_str); 2128 if (!synthetic_child_sp) 2129 { 2130 ValueObject *synthetic_child; 2131 // We haven't made a synthetic array member for INDEX yet, so 2132 // lets make one and cache it for any future reference. 2133 synthetic_child = CreateChildAtIndex(0, true, index); 2134 2135 // Cache the value if we got one back... 2136 if (synthetic_child) 2137 { 2138 AddSyntheticChild(index_const_str, synthetic_child); 2139 synthetic_child_sp = synthetic_child->GetSP(); 2140 synthetic_child_sp->SetName(ConstString(index_str)); 2141 synthetic_child_sp->m_is_array_item_for_pointer = true; 2142 } 2143 } 2144 } 2145 return synthetic_child_sp; 2146} 2147 2148// This allows you to create an array member using and index 2149// that doesn't not fall in the normal bounds of the array. 2150// Many times structure can be defined as: 2151// struct Collection 2152// { 2153// uint32_t item_count; 2154// Item item_array[0]; 2155// }; 2156// The size of the "item_array" is 1, but many times in practice 2157// there are more items in "item_array". 2158 2159ValueObjectSP 2160ValueObject::GetSyntheticArrayMemberFromArray (size_t index, bool can_create) 2161{ 2162 ValueObjectSP synthetic_child_sp; 2163 if (IsArrayType ()) 2164 { 2165 char index_str[64]; 2166 snprintf(index_str, sizeof(index_str), "[%zu]", index); 2167 ConstString index_const_str(index_str); 2168 // Check if we have already created a synthetic array member in this 2169 // valid object. If we have we will re-use it. 2170 synthetic_child_sp = GetSyntheticChild (index_const_str); 2171 if (!synthetic_child_sp) 2172 { 2173 ValueObject *synthetic_child; 2174 // We haven't made a synthetic array member for INDEX yet, so 2175 // lets make one and cache it for any future reference. 2176 synthetic_child = CreateChildAtIndex(0, true, index); 2177 2178 // Cache the value if we got one back... 2179 if (synthetic_child) 2180 { 2181 AddSyntheticChild(index_const_str, synthetic_child); 2182 synthetic_child_sp = synthetic_child->GetSP(); 2183 synthetic_child_sp->SetName(ConstString(index_str)); 2184 synthetic_child_sp->m_is_array_item_for_pointer = true; 2185 } 2186 } 2187 } 2188 return synthetic_child_sp; 2189} 2190 2191ValueObjectSP 2192ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create) 2193{ 2194 ValueObjectSP synthetic_child_sp; 2195 if (IsScalarType ()) 2196 { 2197 char index_str[64]; 2198 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to); 2199 ConstString index_const_str(index_str); 2200 // Check if we have already created a synthetic array member in this 2201 // valid object. If we have we will re-use it. 2202 synthetic_child_sp = GetSyntheticChild (index_const_str); 2203 if (!synthetic_child_sp) 2204 { 2205 // We haven't made a synthetic array member for INDEX yet, so 2206 // lets make one and cache it for any future reference. 2207 ValueObjectChild *synthetic_child = new ValueObjectChild (*this, 2208 GetClangType(), 2209 index_const_str, 2210 GetByteSize(), 2211 0, 2212 to-from+1, 2213 from, 2214 false, 2215 false, 2216 eAddressTypeInvalid); 2217 2218 // Cache the value if we got one back... 2219 if (synthetic_child) 2220 { 2221 AddSyntheticChild(index_const_str, synthetic_child); 2222 synthetic_child_sp = synthetic_child->GetSP(); 2223 synthetic_child_sp->SetName(ConstString(index_str)); 2224 synthetic_child_sp->m_is_bitfield_for_scalar = true; 2225 } 2226 } 2227 } 2228 return synthetic_child_sp; 2229} 2230 2231ValueObjectSP 2232ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create) 2233{ 2234 2235 ValueObjectSP synthetic_child_sp; 2236 2237 char name_str[64]; 2238 snprintf(name_str, sizeof(name_str), "@%i", offset); 2239 ConstString name_const_str(name_str); 2240 2241 // Check if we have already created a synthetic array member in this 2242 // valid object. If we have we will re-use it. 2243 synthetic_child_sp = GetSyntheticChild (name_const_str); 2244 2245 if (synthetic_child_sp.get()) 2246 return synthetic_child_sp; 2247 2248 if (!can_create) 2249 return ValueObjectSP(); 2250 2251 ValueObjectChild *synthetic_child = new ValueObjectChild(*this, 2252 type, 2253 name_const_str, 2254 type.GetByteSize(), 2255 offset, 2256 0, 2257 0, 2258 false, 2259 false, 2260 eAddressTypeInvalid); 2261 if (synthetic_child) 2262 { 2263 AddSyntheticChild(name_const_str, synthetic_child); 2264 synthetic_child_sp = synthetic_child->GetSP(); 2265 synthetic_child_sp->SetName(name_const_str); 2266 synthetic_child_sp->m_is_child_at_offset = true; 2267 } 2268 return synthetic_child_sp; 2269} 2270 2271// your expression path needs to have a leading . or -> 2272// (unless it somehow "looks like" an array, in which case it has 2273// a leading [ symbol). while the [ is meaningful and should be shown 2274// to the user, . and -> are just parser design, but by no means 2275// added information for the user.. strip them off 2276static const char* 2277SkipLeadingExpressionPathSeparators(const char* expression) 2278{ 2279 if (!expression || !expression[0]) 2280 return expression; 2281 if (expression[0] == '.') 2282 return expression+1; 2283 if (expression[0] == '-' && expression[1] == '>') 2284 return expression+2; 2285 return expression; 2286} 2287 2288ValueObjectSP 2289ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_create) 2290{ 2291 ValueObjectSP synthetic_child_sp; 2292 ConstString name_const_string(expression); 2293 // Check if we have already created a synthetic array member in this 2294 // valid object. If we have we will re-use it. 2295 synthetic_child_sp = GetSyntheticChild (name_const_string); 2296 if (!synthetic_child_sp) 2297 { 2298 // We haven't made a synthetic array member for expression yet, so 2299 // lets make one and cache it for any future reference. 2300 synthetic_child_sp = GetValueForExpressionPath(expression, 2301 NULL, NULL, NULL, 2302 GetValueForExpressionPathOptions().DontAllowSyntheticChildren()); 2303 2304 // Cache the value if we got one back... 2305 if (synthetic_child_sp.get()) 2306 { 2307 // FIXME: this causes a "real" child to end up with its name changed to the contents of expression 2308 AddSyntheticChild(name_const_string, synthetic_child_sp.get()); 2309 synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression))); 2310 } 2311 } 2312 return synthetic_child_sp; 2313} 2314 2315void 2316ValueObject::CalculateSyntheticValue (bool use_synthetic) 2317{ 2318 if (use_synthetic == false) 2319 return; 2320 2321 TargetSP target_sp(GetTargetSP()); 2322 if (target_sp && target_sp->GetEnableSyntheticValue() == false) 2323 { 2324 m_synthetic_value = NULL; 2325 return; 2326 } 2327 2328 lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp); 2329 2330 if (!UpdateFormatsIfNeeded() && m_synthetic_value) 2331 return; 2332 2333 if (m_synthetic_children_sp.get() == NULL) 2334 return; 2335 2336 if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value) 2337 return; 2338 2339 m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp); 2340} 2341 2342void 2343ValueObject::CalculateDynamicValue (DynamicValueType use_dynamic) 2344{ 2345 if (use_dynamic == eNoDynamicValues) 2346 return; 2347 2348 if (!m_dynamic_value && !IsDynamic()) 2349 { 2350 ExecutionContext exe_ctx (GetExecutionContextRef()); 2351 Process *process = exe_ctx.GetProcessPtr(); 2352 if (process && process->IsPossibleDynamicValue(*this)) 2353 { 2354 ClearDynamicTypeInformation (); 2355 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic); 2356 } 2357 } 2358} 2359 2360ValueObjectSP 2361ValueObject::GetDynamicValue (DynamicValueType use_dynamic) 2362{ 2363 if (use_dynamic == eNoDynamicValues) 2364 return ValueObjectSP(); 2365 2366 if (!IsDynamic() && m_dynamic_value == NULL) 2367 { 2368 CalculateDynamicValue(use_dynamic); 2369 } 2370 if (m_dynamic_value) 2371 return m_dynamic_value->GetSP(); 2372 else 2373 return ValueObjectSP(); 2374} 2375 2376ValueObjectSP 2377ValueObject::GetStaticValue() 2378{ 2379 return GetSP(); 2380} 2381 2382lldb::ValueObjectSP 2383ValueObject::GetNonSyntheticValue () 2384{ 2385 return GetSP(); 2386} 2387 2388ValueObjectSP 2389ValueObject::GetSyntheticValue (bool use_synthetic) 2390{ 2391 if (use_synthetic == false) 2392 return ValueObjectSP(); 2393 2394 CalculateSyntheticValue(use_synthetic); 2395 2396 if (m_synthetic_value) 2397 return m_synthetic_value->GetSP(); 2398 else 2399 return ValueObjectSP(); 2400} 2401 2402bool 2403ValueObject::HasSyntheticValue() 2404{ 2405 UpdateFormatsIfNeeded(); 2406 2407 if (m_synthetic_children_sp.get() == NULL) 2408 return false; 2409 2410 CalculateSyntheticValue(true); 2411 2412 if (m_synthetic_value) 2413 return true; 2414 else 2415 return false; 2416} 2417 2418bool 2419ValueObject::GetBaseClassPath (Stream &s) 2420{ 2421 if (IsBaseClass()) 2422 { 2423 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s); 2424 ClangASTType clang_type = GetClangType(); 2425 std::string cxx_class_name; 2426 bool this_had_base_class = clang_type.GetCXXClassName (cxx_class_name); 2427 if (this_had_base_class) 2428 { 2429 if (parent_had_base_class) 2430 s.PutCString("::"); 2431 s.PutCString(cxx_class_name.c_str()); 2432 } 2433 return parent_had_base_class || this_had_base_class; 2434 } 2435 return false; 2436} 2437 2438 2439ValueObject * 2440ValueObject::GetNonBaseClassParent() 2441{ 2442 if (GetParent()) 2443 { 2444 if (GetParent()->IsBaseClass()) 2445 return GetParent()->GetNonBaseClassParent(); 2446 else 2447 return GetParent(); 2448 } 2449 return NULL; 2450} 2451 2452void 2453ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat) 2454{ 2455 const bool is_deref_of_parent = IsDereferenceOfParent (); 2456 2457 if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers) 2458 { 2459 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely 2460 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName. 2461 // the eHonorPointers mode is meant to produce strings in this latter format 2462 s.PutCString("*("); 2463 } 2464 2465 ValueObject* parent = GetParent(); 2466 2467 if (parent) 2468 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat); 2469 2470 // if we are a deref_of_parent just because we are synthetic array 2471 // members made up to allow ptr[%d] syntax to work in variable 2472 // printing, then add our name ([%d]) to the expression path 2473 if (m_is_array_item_for_pointer && epformat == eGetExpressionPathFormatHonorPointers) 2474 s.PutCString(m_name.AsCString()); 2475 2476 if (!IsBaseClass()) 2477 { 2478 if (!is_deref_of_parent) 2479 { 2480 ValueObject *non_base_class_parent = GetNonBaseClassParent(); 2481 if (non_base_class_parent) 2482 { 2483 ClangASTType non_base_class_parent_clang_type = non_base_class_parent->GetClangType(); 2484 if (non_base_class_parent_clang_type) 2485 { 2486 if (parent && parent->IsDereferenceOfParent() && epformat == eGetExpressionPathFormatHonorPointers) 2487 { 2488 s.PutCString("->"); 2489 } 2490 else 2491 { 2492 const uint32_t non_base_class_parent_type_info = non_base_class_parent_clang_type.GetTypeInfo(); 2493 2494 if (non_base_class_parent_type_info & ClangASTType::eTypeIsPointer) 2495 { 2496 s.PutCString("->"); 2497 } 2498 else if ((non_base_class_parent_type_info & ClangASTType::eTypeHasChildren) && 2499 !(non_base_class_parent_type_info & ClangASTType::eTypeIsArray)) 2500 { 2501 s.PutChar('.'); 2502 } 2503 } 2504 } 2505 } 2506 2507 const char *name = GetName().GetCString(); 2508 if (name) 2509 { 2510 if (qualify_cxx_base_classes) 2511 { 2512 if (GetBaseClassPath (s)) 2513 s.PutCString("::"); 2514 } 2515 s.PutCString(name); 2516 } 2517 } 2518 } 2519 2520 if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers) 2521 { 2522 s.PutChar(')'); 2523 } 2524} 2525 2526ValueObjectSP 2527ValueObject::GetValueForExpressionPath(const char* expression, 2528 const char** first_unparsed, 2529 ExpressionPathScanEndReason* reason_to_stop, 2530 ExpressionPathEndResultType* final_value_type, 2531 const GetValueForExpressionPathOptions& options, 2532 ExpressionPathAftermath* final_task_on_target) 2533{ 2534 2535 const char* dummy_first_unparsed; 2536 ExpressionPathScanEndReason dummy_reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnknown; 2537 ExpressionPathEndResultType dummy_final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid; 2538 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing; 2539 2540 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression, 2541 first_unparsed ? first_unparsed : &dummy_first_unparsed, 2542 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop, 2543 final_value_type ? final_value_type : &dummy_final_value_type, 2544 options, 2545 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target); 2546 2547 if (!final_task_on_target || *final_task_on_target == ValueObject::eExpressionPathAftermathNothing) 2548 return ret_val; 2549 2550 if (ret_val.get() && ((final_value_type ? *final_value_type : dummy_final_value_type) == eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress of plain objects 2551 { 2552 if ( (final_task_on_target ? *final_task_on_target : dummy_final_task_on_target) == ValueObject::eExpressionPathAftermathDereference) 2553 { 2554 Error error; 2555 ValueObjectSP final_value = ret_val->Dereference(error); 2556 if (error.Fail() || !final_value.get()) 2557 { 2558 if (reason_to_stop) 2559 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed; 2560 if (final_value_type) 2561 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid; 2562 return ValueObjectSP(); 2563 } 2564 else 2565 { 2566 if (final_task_on_target) 2567 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing; 2568 return final_value; 2569 } 2570 } 2571 if (*final_task_on_target == ValueObject::eExpressionPathAftermathTakeAddress) 2572 { 2573 Error error; 2574 ValueObjectSP final_value = ret_val->AddressOf(error); 2575 if (error.Fail() || !final_value.get()) 2576 { 2577 if (reason_to_stop) 2578 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonTakingAddressFailed; 2579 if (final_value_type) 2580 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid; 2581 return ValueObjectSP(); 2582 } 2583 else 2584 { 2585 if (final_task_on_target) 2586 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing; 2587 return final_value; 2588 } 2589 } 2590 } 2591 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it 2592} 2593 2594int 2595ValueObject::GetValuesForExpressionPath(const char* expression, 2596 ValueObjectListSP& list, 2597 const char** first_unparsed, 2598 ExpressionPathScanEndReason* reason_to_stop, 2599 ExpressionPathEndResultType* final_value_type, 2600 const GetValueForExpressionPathOptions& options, 2601 ExpressionPathAftermath* final_task_on_target) 2602{ 2603 const char* dummy_first_unparsed; 2604 ExpressionPathScanEndReason dummy_reason_to_stop; 2605 ExpressionPathEndResultType dummy_final_value_type; 2606 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing; 2607 2608 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression, 2609 first_unparsed ? first_unparsed : &dummy_first_unparsed, 2610 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop, 2611 final_value_type ? final_value_type : &dummy_final_value_type, 2612 options, 2613 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target); 2614 2615 if (!ret_val.get()) // if there are errors, I add nothing to the list 2616 return 0; 2617 2618 if ( (reason_to_stop ? *reason_to_stop : dummy_reason_to_stop) != eExpressionPathScanEndReasonArrayRangeOperatorMet) 2619 { 2620 // I need not expand a range, just post-process the final value and return 2621 if (!final_task_on_target || *final_task_on_target == ValueObject::eExpressionPathAftermathNothing) 2622 { 2623 list->Append(ret_val); 2624 return 1; 2625 } 2626 if (ret_val.get() && (final_value_type ? *final_value_type : dummy_final_value_type) == eExpressionPathEndResultTypePlain) // I can only deref and takeaddress of plain objects 2627 { 2628 if (*final_task_on_target == ValueObject::eExpressionPathAftermathDereference) 2629 { 2630 Error error; 2631 ValueObjectSP final_value = ret_val->Dereference(error); 2632 if (error.Fail() || !final_value.get()) 2633 { 2634 if (reason_to_stop) 2635 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed; 2636 if (final_value_type) 2637 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid; 2638 return 0; 2639 } 2640 else 2641 { 2642 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing; 2643 list->Append(final_value); 2644 return 1; 2645 } 2646 } 2647 if (*final_task_on_target == ValueObject::eExpressionPathAftermathTakeAddress) 2648 { 2649 Error error; 2650 ValueObjectSP final_value = ret_val->AddressOf(error); 2651 if (error.Fail() || !final_value.get()) 2652 { 2653 if (reason_to_stop) 2654 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonTakingAddressFailed; 2655 if (final_value_type) 2656 *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid; 2657 return 0; 2658 } 2659 else 2660 { 2661 *final_task_on_target = ValueObject::eExpressionPathAftermathNothing; 2662 list->Append(final_value); 2663 return 1; 2664 } 2665 } 2666 } 2667 } 2668 else 2669 { 2670 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed, 2671 first_unparsed ? first_unparsed : &dummy_first_unparsed, 2672 ret_val, 2673 list, 2674 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop, 2675 final_value_type ? final_value_type : &dummy_final_value_type, 2676 options, 2677 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target); 2678 } 2679 // in any non-covered case, just do the obviously right thing 2680 list->Append(ret_val); 2681 return 1; 2682} 2683 2684ValueObjectSP 2685ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, 2686 const char** first_unparsed, 2687 ExpressionPathScanEndReason* reason_to_stop, 2688 ExpressionPathEndResultType* final_result, 2689 const GetValueForExpressionPathOptions& options, 2690 ExpressionPathAftermath* what_next) 2691{ 2692 ValueObjectSP root = GetSP(); 2693 2694 if (!root.get()) 2695 return ValueObjectSP(); 2696 2697 *first_unparsed = expression_cstr; 2698 2699 while (true) 2700 { 2701 2702 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr 2703 2704 ClangASTType root_clang_type = root->GetClangType(); 2705 ClangASTType pointee_clang_type; 2706 Flags pointee_clang_type_info; 2707 2708 Flags root_clang_type_info(root_clang_type.GetTypeInfo(&pointee_clang_type)); 2709 if (pointee_clang_type) 2710 pointee_clang_type_info.Reset(pointee_clang_type.GetTypeInfo()); 2711 2712 if (!expression_cstr || *expression_cstr == '\0') 2713 { 2714 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 2715 return root; 2716 } 2717 2718 switch (*expression_cstr) 2719 { 2720 case '-': 2721 { 2722 if (options.m_check_dot_vs_arrow_syntax && 2723 root_clang_type_info.Test(ClangASTType::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error 2724 { 2725 *first_unparsed = expression_cstr; 2726 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot; 2727 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2728 return ValueObjectSP(); 2729 } 2730 if (root_clang_type_info.Test(ClangASTType::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden 2731 root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && 2732 options.m_no_fragile_ivar) 2733 { 2734 *first_unparsed = expression_cstr; 2735 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed; 2736 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2737 return ValueObjectSP(); 2738 } 2739 if (expression_cstr[1] != '>') 2740 { 2741 *first_unparsed = expression_cstr; 2742 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 2743 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2744 return ValueObjectSP(); 2745 } 2746 expression_cstr++; // skip the - 2747 } 2748 case '.': // or fallthrough from -> 2749 { 2750 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' && 2751 root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error 2752 { 2753 *first_unparsed = expression_cstr; 2754 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow; 2755 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2756 return ValueObjectSP(); 2757 } 2758 expression_cstr++; // skip . 2759 const char *next_separator = strpbrk(expression_cstr+1,"-.["); 2760 ConstString child_name; 2761 if (!next_separator) // if no other separator just expand this last layer 2762 { 2763 child_name.SetCString (expression_cstr); 2764 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true); 2765 2766 if (child_valobj_sp.get()) // we know we are done, so just return 2767 { 2768 *first_unparsed = ""; 2769 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 2770 *final_result = ValueObject::eExpressionPathEndResultTypePlain; 2771 return child_valobj_sp; 2772 } 2773 else if (options.m_no_synthetic_children == false) // let's try with synthetic children 2774 { 2775 if (root->IsSynthetic()) 2776 { 2777 *first_unparsed = expression_cstr; 2778 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 2779 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2780 return ValueObjectSP(); 2781 } 2782 2783 child_valobj_sp = root->GetSyntheticValue(); 2784 if (child_valobj_sp.get()) 2785 child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); 2786 } 2787 2788 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP, 2789 // so we hit the "else" branch, and return an error 2790 if(child_valobj_sp.get()) // if it worked, just return 2791 { 2792 *first_unparsed = ""; 2793 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 2794 *final_result = ValueObject::eExpressionPathEndResultTypePlain; 2795 return child_valobj_sp; 2796 } 2797 else 2798 { 2799 *first_unparsed = expression_cstr; 2800 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 2801 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2802 return ValueObjectSP(); 2803 } 2804 } 2805 else // other layers do expand 2806 { 2807 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr); 2808 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true); 2809 if (child_valobj_sp.get()) // store the new root and move on 2810 { 2811 root = child_valobj_sp; 2812 *first_unparsed = next_separator; 2813 *final_result = ValueObject::eExpressionPathEndResultTypePlain; 2814 continue; 2815 } 2816 else if (options.m_no_synthetic_children == false) // let's try with synthetic children 2817 { 2818 if (root->IsSynthetic()) 2819 { 2820 *first_unparsed = expression_cstr; 2821 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 2822 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2823 return ValueObjectSP(); 2824 } 2825 2826 child_valobj_sp = root->GetSyntheticValue(true); 2827 if (child_valobj_sp) 2828 child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); 2829 } 2830 2831 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP, 2832 // so we hit the "else" branch, and return an error 2833 if(child_valobj_sp.get()) // if it worked, move on 2834 { 2835 root = child_valobj_sp; 2836 *first_unparsed = next_separator; 2837 *final_result = ValueObject::eExpressionPathEndResultTypePlain; 2838 continue; 2839 } 2840 else 2841 { 2842 *first_unparsed = expression_cstr; 2843 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 2844 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2845 return ValueObjectSP(); 2846 } 2847 } 2848 break; 2849 } 2850 case '[': 2851 { 2852 if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray) && !root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && !root_clang_type_info.Test(ClangASTType::eTypeIsVector)) // if this is not a T[] nor a T* 2853 { 2854 if (!root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // if this is not even a scalar... 2855 { 2856 if (options.m_no_synthetic_children) // ...only chance left is synthetic 2857 { 2858 *first_unparsed = expression_cstr; 2859 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid; 2860 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2861 return ValueObjectSP(); 2862 } 2863 } 2864 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields 2865 { 2866 *first_unparsed = expression_cstr; 2867 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed; 2868 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2869 return ValueObjectSP(); 2870 } 2871 } 2872 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays 2873 { 2874 if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray)) 2875 { 2876 *first_unparsed = expression_cstr; 2877 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed; 2878 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2879 return ValueObjectSP(); 2880 } 2881 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it 2882 { 2883 *first_unparsed = expression_cstr+2; 2884 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet; 2885 *final_result = ValueObject::eExpressionPathEndResultTypeUnboundedRange; 2886 return root; 2887 } 2888 } 2889 const char *separator_position = ::strchr(expression_cstr+1,'-'); 2890 const char *close_bracket_position = ::strchr(expression_cstr+1,']'); 2891 if (!close_bracket_position) // if there is no ], this is a syntax error 2892 { 2893 *first_unparsed = expression_cstr; 2894 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 2895 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2896 return ValueObjectSP(); 2897 } 2898 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N] 2899 { 2900 char *end = NULL; 2901 unsigned long index = ::strtoul (expression_cstr+1, &end, 0); 2902 if (!end || end != close_bracket_position) // if something weird is in our way return an error 2903 { 2904 *first_unparsed = expression_cstr; 2905 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 2906 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2907 return ValueObjectSP(); 2908 } 2909 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays 2910 { 2911 if (root_clang_type_info.Test(ClangASTType::eTypeIsArray)) 2912 { 2913 *first_unparsed = expression_cstr+2; 2914 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet; 2915 *final_result = ValueObject::eExpressionPathEndResultTypeUnboundedRange; 2916 return root; 2917 } 2918 else 2919 { 2920 *first_unparsed = expression_cstr; 2921 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed; 2922 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2923 return ValueObjectSP(); 2924 } 2925 } 2926 // from here on we do have a valid index 2927 if (root_clang_type_info.Test(ClangASTType::eTypeIsArray)) 2928 { 2929 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true); 2930 if (!child_valobj_sp) 2931 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true); 2932 if (!child_valobj_sp) 2933 if (root->HasSyntheticValue() && root->GetSyntheticValue()->GetNumChildren() > index) 2934 child_valobj_sp = root->GetSyntheticValue()->GetChildAtIndex(index, true); 2935 if (child_valobj_sp) 2936 { 2937 root = child_valobj_sp; 2938 *first_unparsed = end+1; // skip ] 2939 *final_result = ValueObject::eExpressionPathEndResultTypePlain; 2940 continue; 2941 } 2942 else 2943 { 2944 *first_unparsed = expression_cstr; 2945 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 2946 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2947 return ValueObjectSP(); 2948 } 2949 } 2950 else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) 2951 { 2952 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 2953 pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar)) 2954 { 2955 Error error; 2956 root = root->Dereference(error); 2957 if (error.Fail() || !root.get()) 2958 { 2959 *first_unparsed = expression_cstr; 2960 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed; 2961 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2962 return ValueObjectSP(); 2963 } 2964 else 2965 { 2966 *what_next = eExpressionPathAftermathNothing; 2967 continue; 2968 } 2969 } 2970 else 2971 { 2972 if (root->GetClangType().GetMinimumLanguage() == eLanguageTypeObjC 2973 && pointee_clang_type_info.AllClear(ClangASTType::eTypeIsPointer) 2974 && root->HasSyntheticValue() 2975 && options.m_no_synthetic_children == false) 2976 { 2977 root = root->GetSyntheticValue()->GetChildAtIndex(index, true); 2978 } 2979 else 2980 root = root->GetSyntheticArrayMemberFromPointer(index, true); 2981 if (!root.get()) 2982 { 2983 *first_unparsed = expression_cstr; 2984 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 2985 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 2986 return ValueObjectSP(); 2987 } 2988 else 2989 { 2990 *first_unparsed = end+1; // skip ] 2991 *final_result = ValueObject::eExpressionPathEndResultTypePlain; 2992 continue; 2993 } 2994 } 2995 } 2996 else if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) 2997 { 2998 root = root->GetSyntheticBitFieldChild(index, index, true); 2999 if (!root.get()) 3000 { 3001 *first_unparsed = expression_cstr; 3002 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 3003 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3004 return ValueObjectSP(); 3005 } 3006 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing 3007 { 3008 *first_unparsed = end+1; // skip ] 3009 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonBitfieldRangeOperatorMet; 3010 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield; 3011 return root; 3012 } 3013 } 3014 else if (root_clang_type_info.Test(ClangASTType::eTypeIsVector)) 3015 { 3016 root = root->GetChildAtIndex(index, true); 3017 if (!root.get()) 3018 { 3019 *first_unparsed = expression_cstr; 3020 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 3021 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3022 return ValueObjectSP(); 3023 } 3024 else 3025 { 3026 *first_unparsed = end+1; // skip ] 3027 *final_result = ValueObject::eExpressionPathEndResultTypePlain; 3028 continue; 3029 } 3030 } 3031 else if (options.m_no_synthetic_children == false) 3032 { 3033 if (root->HasSyntheticValue()) 3034 root = root->GetSyntheticValue(); 3035 else if (!root->IsSynthetic()) 3036 { 3037 *first_unparsed = expression_cstr; 3038 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing; 3039 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3040 return ValueObjectSP(); 3041 } 3042 // if we are here, then root itself is a synthetic VO.. should be good to go 3043 3044 if (!root.get()) 3045 { 3046 *first_unparsed = expression_cstr; 3047 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing; 3048 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3049 return ValueObjectSP(); 3050 } 3051 root = root->GetChildAtIndex(index, true); 3052 if (!root.get()) 3053 { 3054 *first_unparsed = expression_cstr; 3055 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 3056 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3057 return ValueObjectSP(); 3058 } 3059 else 3060 { 3061 *first_unparsed = end+1; // skip ] 3062 *final_result = ValueObject::eExpressionPathEndResultTypePlain; 3063 continue; 3064 } 3065 } 3066 else 3067 { 3068 *first_unparsed = expression_cstr; 3069 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 3070 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3071 return ValueObjectSP(); 3072 } 3073 } 3074 else // we have a low and a high index 3075 { 3076 char *end = NULL; 3077 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0); 3078 if (!end || end != separator_position) // if something weird is in our way return an error 3079 { 3080 *first_unparsed = expression_cstr; 3081 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 3082 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3083 return ValueObjectSP(); 3084 } 3085 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0); 3086 if (!end || end != close_bracket_position) // if something weird is in our way return an error 3087 { 3088 *first_unparsed = expression_cstr; 3089 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 3090 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3091 return ValueObjectSP(); 3092 } 3093 if (index_lower > index_higher) // swap indices if required 3094 { 3095 unsigned long temp = index_lower; 3096 index_lower = index_higher; 3097 index_higher = temp; 3098 } 3099 if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // expansion only works for scalars 3100 { 3101 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true); 3102 if (!root.get()) 3103 { 3104 *first_unparsed = expression_cstr; 3105 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 3106 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3107 return ValueObjectSP(); 3108 } 3109 else 3110 { 3111 *first_unparsed = end+1; // skip ] 3112 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonBitfieldRangeOperatorMet; 3113 *final_result = ValueObject::eExpressionPathEndResultTypeBitfield; 3114 return root; 3115 } 3116 } 3117 else if (root_clang_type_info.Test(ClangASTType::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 3118 *what_next == ValueObject::eExpressionPathAftermathDereference && 3119 pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar)) 3120 { 3121 Error error; 3122 root = root->Dereference(error); 3123 if (error.Fail() || !root.get()) 3124 { 3125 *first_unparsed = expression_cstr; 3126 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed; 3127 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3128 return ValueObjectSP(); 3129 } 3130 else 3131 { 3132 *what_next = ValueObject::eExpressionPathAftermathNothing; 3133 continue; 3134 } 3135 } 3136 else 3137 { 3138 *first_unparsed = expression_cstr; 3139 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet; 3140 *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange; 3141 return root; 3142 } 3143 } 3144 break; 3145 } 3146 default: // some non-separator is in the way 3147 { 3148 *first_unparsed = expression_cstr; 3149 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 3150 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3151 return ValueObjectSP(); 3152 break; 3153 } 3154 } 3155 } 3156} 3157 3158int 3159ValueObject::ExpandArraySliceExpression(const char* expression_cstr, 3160 const char** first_unparsed, 3161 ValueObjectSP root, 3162 ValueObjectListSP& list, 3163 ExpressionPathScanEndReason* reason_to_stop, 3164 ExpressionPathEndResultType* final_result, 3165 const GetValueForExpressionPathOptions& options, 3166 ExpressionPathAftermath* what_next) 3167{ 3168 if (!root.get()) 3169 return 0; 3170 3171 *first_unparsed = expression_cstr; 3172 3173 while (true) 3174 { 3175 3176 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr 3177 3178 ClangASTType root_clang_type = root->GetClangType(); 3179 ClangASTType pointee_clang_type; 3180 Flags pointee_clang_type_info; 3181 Flags root_clang_type_info(root_clang_type.GetTypeInfo(&pointee_clang_type)); 3182 if (pointee_clang_type) 3183 pointee_clang_type_info.Reset(pointee_clang_type.GetTypeInfo()); 3184 3185 if (!expression_cstr || *expression_cstr == '\0') 3186 { 3187 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString; 3188 list->Append(root); 3189 return 1; 3190 } 3191 3192 switch (*expression_cstr) 3193 { 3194 case '[': 3195 { 3196 if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray) && !root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) // if this is not a T[] nor a T* 3197 { 3198 if (!root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong! 3199 { 3200 *first_unparsed = expression_cstr; 3201 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid; 3202 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3203 return 0; 3204 } 3205 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields 3206 { 3207 *first_unparsed = expression_cstr; 3208 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed; 3209 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3210 return 0; 3211 } 3212 } 3213 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays 3214 { 3215 if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray)) 3216 { 3217 *first_unparsed = expression_cstr; 3218 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed; 3219 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3220 return 0; 3221 } 3222 else // expand this into list 3223 { 3224 const size_t max_index = root->GetNumChildren() - 1; 3225 for (size_t index = 0; index < max_index; index++) 3226 { 3227 ValueObjectSP child = 3228 root->GetChildAtIndex(index, true); 3229 list->Append(child); 3230 } 3231 *first_unparsed = expression_cstr+2; 3232 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded; 3233 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList; 3234 return max_index; // tell me number of items I added to the VOList 3235 } 3236 } 3237 const char *separator_position = ::strchr(expression_cstr+1,'-'); 3238 const char *close_bracket_position = ::strchr(expression_cstr+1,']'); 3239 if (!close_bracket_position) // if there is no ], this is a syntax error 3240 { 3241 *first_unparsed = expression_cstr; 3242 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 3243 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3244 return 0; 3245 } 3246 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N] 3247 { 3248 char *end = NULL; 3249 unsigned long index = ::strtoul (expression_cstr+1, &end, 0); 3250 if (!end || end != close_bracket_position) // if something weird is in our way return an error 3251 { 3252 *first_unparsed = expression_cstr; 3253 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 3254 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3255 return 0; 3256 } 3257 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays 3258 { 3259 if (root_clang_type_info.Test(ClangASTType::eTypeIsArray)) 3260 { 3261 const size_t max_index = root->GetNumChildren() - 1; 3262 for (size_t index = 0; index < max_index; index++) 3263 { 3264 ValueObjectSP child = 3265 root->GetChildAtIndex(index, true); 3266 list->Append(child); 3267 } 3268 *first_unparsed = expression_cstr+2; 3269 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded; 3270 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList; 3271 return max_index; // tell me number of items I added to the VOList 3272 } 3273 else 3274 { 3275 *first_unparsed = expression_cstr; 3276 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed; 3277 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3278 return 0; 3279 } 3280 } 3281 // from here on we do have a valid index 3282 if (root_clang_type_info.Test(ClangASTType::eTypeIsArray)) 3283 { 3284 root = root->GetChildAtIndex(index, true); 3285 if (!root.get()) 3286 { 3287 *first_unparsed = expression_cstr; 3288 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 3289 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3290 return 0; 3291 } 3292 else 3293 { 3294 list->Append(root); 3295 *first_unparsed = end+1; // skip ] 3296 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded; 3297 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList; 3298 return 1; 3299 } 3300 } 3301 else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) 3302 { 3303 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 3304 pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar)) 3305 { 3306 Error error; 3307 root = root->Dereference(error); 3308 if (error.Fail() || !root.get()) 3309 { 3310 *first_unparsed = expression_cstr; 3311 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed; 3312 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3313 return 0; 3314 } 3315 else 3316 { 3317 *what_next = eExpressionPathAftermathNothing; 3318 continue; 3319 } 3320 } 3321 else 3322 { 3323 root = root->GetSyntheticArrayMemberFromPointer(index, true); 3324 if (!root.get()) 3325 { 3326 *first_unparsed = expression_cstr; 3327 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 3328 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3329 return 0; 3330 } 3331 else 3332 { 3333 list->Append(root); 3334 *first_unparsed = end+1; // skip ] 3335 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded; 3336 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList; 3337 return 1; 3338 } 3339 } 3340 } 3341 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/ 3342 { 3343 root = root->GetSyntheticBitFieldChild(index, index, true); 3344 if (!root.get()) 3345 { 3346 *first_unparsed = expression_cstr; 3347 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 3348 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3349 return 0; 3350 } 3351 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing 3352 { 3353 list->Append(root); 3354 *first_unparsed = end+1; // skip ] 3355 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded; 3356 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList; 3357 return 1; 3358 } 3359 } 3360 } 3361 else // we have a low and a high index 3362 { 3363 char *end = NULL; 3364 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0); 3365 if (!end || end != separator_position) // if something weird is in our way return an error 3366 { 3367 *first_unparsed = expression_cstr; 3368 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 3369 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3370 return 0; 3371 } 3372 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0); 3373 if (!end || end != close_bracket_position) // if something weird is in our way return an error 3374 { 3375 *first_unparsed = expression_cstr; 3376 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 3377 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3378 return 0; 3379 } 3380 if (index_lower > index_higher) // swap indices if required 3381 { 3382 unsigned long temp = index_lower; 3383 index_lower = index_higher; 3384 index_higher = temp; 3385 } 3386 if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // expansion only works for scalars 3387 { 3388 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true); 3389 if (!root.get()) 3390 { 3391 *first_unparsed = expression_cstr; 3392 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; 3393 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3394 return 0; 3395 } 3396 else 3397 { 3398 list->Append(root); 3399 *first_unparsed = end+1; // skip ] 3400 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded; 3401 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList; 3402 return 1; 3403 } 3404 } 3405 else if (root_clang_type_info.Test(ClangASTType::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 3406 *what_next == ValueObject::eExpressionPathAftermathDereference && 3407 pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar)) 3408 { 3409 Error error; 3410 root = root->Dereference(error); 3411 if (error.Fail() || !root.get()) 3412 { 3413 *first_unparsed = expression_cstr; 3414 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed; 3415 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3416 return 0; 3417 } 3418 else 3419 { 3420 *what_next = ValueObject::eExpressionPathAftermathNothing; 3421 continue; 3422 } 3423 } 3424 else 3425 { 3426 for (unsigned long index = index_lower; 3427 index <= index_higher; index++) 3428 { 3429 ValueObjectSP child = 3430 root->GetChildAtIndex(index, true); 3431 list->Append(child); 3432 } 3433 *first_unparsed = end+1; 3434 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded; 3435 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList; 3436 return index_higher-index_lower+1; // tell me number of items I added to the VOList 3437 } 3438 } 3439 break; 3440 } 3441 default: // some non-[ separator, or something entirely wrong, is in the way 3442 { 3443 *first_unparsed = expression_cstr; 3444 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol; 3445 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; 3446 return 0; 3447 break; 3448 } 3449 } 3450 } 3451} 3452 3453void 3454ValueObject::LogValueObject (Log *log) 3455{ 3456 if (log) 3457 return LogValueObject (log, DumpValueObjectOptions::DefaultOptions()); 3458} 3459 3460void 3461ValueObject::LogValueObject (Log *log, const DumpValueObjectOptions& options) 3462{ 3463 if (log) 3464 { 3465 StreamString s; 3466 Dump (s, options); 3467 if (s.GetSize()) 3468 log->PutCString(s.GetData()); 3469 } 3470} 3471 3472void 3473ValueObject::Dump (Stream &s) 3474{ 3475 3476 ValueObjectPrinter printer(this,&s,DumpValueObjectOptions::DefaultOptions()); 3477 printer.PrintValueObject(); 3478} 3479 3480void 3481ValueObject::Dump (Stream &s, 3482 const DumpValueObjectOptions& options) 3483{ 3484 ValueObjectPrinter printer(this,&s,options); 3485 printer.PrintValueObject(); 3486} 3487 3488ValueObjectSP 3489ValueObject::CreateConstantValue (const ConstString &name) 3490{ 3491 ValueObjectSP valobj_sp; 3492 3493 if (UpdateValueIfNeeded(false) && m_error.Success()) 3494 { 3495 ExecutionContext exe_ctx (GetExecutionContextRef()); 3496 3497 DataExtractor data; 3498 data.SetByteOrder (m_data.GetByteOrder()); 3499 data.SetAddressByteSize(m_data.GetAddressByteSize()); 3500 3501 if (IsBitfield()) 3502 { 3503 Value v(Scalar(GetValueAsUnsigned(UINT64_MAX))); 3504 m_error = v.GetValueAsData (&exe_ctx, data, 0, GetModule().get()); 3505 } 3506 else 3507 m_error = m_value.GetValueAsData (&exe_ctx, data, 0, GetModule().get()); 3508 3509 valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), 3510 GetClangType(), 3511 name, 3512 data, 3513 GetAddressOf()); 3514 } 3515 3516 if (!valobj_sp) 3517 { 3518 valobj_sp = ValueObjectConstResult::Create (NULL, m_error); 3519 } 3520 return valobj_sp; 3521} 3522 3523ValueObjectSP 3524ValueObject::Dereference (Error &error) 3525{ 3526 if (m_deref_valobj) 3527 return m_deref_valobj->GetSP(); 3528 3529 const bool is_pointer_type = IsPointerType(); 3530 if (is_pointer_type) 3531 { 3532 bool omit_empty_base_classes = true; 3533 bool ignore_array_bounds = false; 3534 3535 std::string child_name_str; 3536 uint32_t child_byte_size = 0; 3537 int32_t child_byte_offset = 0; 3538 uint32_t child_bitfield_bit_size = 0; 3539 uint32_t child_bitfield_bit_offset = 0; 3540 bool child_is_base_class = false; 3541 bool child_is_deref_of_parent = false; 3542 const bool transparent_pointers = false; 3543 ClangASTType clang_type = GetClangType(); 3544 ClangASTType child_clang_type; 3545 3546 ExecutionContext exe_ctx (GetExecutionContextRef()); 3547 3548 child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx, 3549 GetName().GetCString(), 3550 0, 3551 transparent_pointers, 3552 omit_empty_base_classes, 3553 ignore_array_bounds, 3554 child_name_str, 3555 child_byte_size, 3556 child_byte_offset, 3557 child_bitfield_bit_size, 3558 child_bitfield_bit_offset, 3559 child_is_base_class, 3560 child_is_deref_of_parent); 3561 if (child_clang_type && child_byte_size) 3562 { 3563 ConstString child_name; 3564 if (!child_name_str.empty()) 3565 child_name.SetCString (child_name_str.c_str()); 3566 3567 m_deref_valobj = new ValueObjectChild (*this, 3568 child_clang_type, 3569 child_name, 3570 child_byte_size, 3571 child_byte_offset, 3572 child_bitfield_bit_size, 3573 child_bitfield_bit_offset, 3574 child_is_base_class, 3575 child_is_deref_of_parent, 3576 eAddressTypeInvalid); 3577 } 3578 } 3579 3580 if (m_deref_valobj) 3581 { 3582 error.Clear(); 3583 return m_deref_valobj->GetSP(); 3584 } 3585 else 3586 { 3587 StreamString strm; 3588 GetExpressionPath(strm, true); 3589 3590 if (is_pointer_type) 3591 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str()); 3592 else 3593 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str()); 3594 return ValueObjectSP(); 3595 } 3596} 3597 3598ValueObjectSP 3599ValueObject::AddressOf (Error &error) 3600{ 3601 if (m_addr_of_valobj_sp) 3602 return m_addr_of_valobj_sp; 3603 3604 AddressType address_type = eAddressTypeInvalid; 3605 const bool scalar_is_load_address = false; 3606 addr_t addr = GetAddressOf (scalar_is_load_address, &address_type); 3607 error.Clear(); 3608 if (addr != LLDB_INVALID_ADDRESS) 3609 { 3610 switch (address_type) 3611 { 3612 case eAddressTypeInvalid: 3613 { 3614 StreamString expr_path_strm; 3615 GetExpressionPath(expr_path_strm, true); 3616 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str()); 3617 } 3618 break; 3619 3620 case eAddressTypeFile: 3621 case eAddressTypeLoad: 3622 case eAddressTypeHost: 3623 { 3624 ClangASTType clang_type = GetClangType(); 3625 if (clang_type) 3626 { 3627 std::string name (1, '&'); 3628 name.append (m_name.AsCString("")); 3629 ExecutionContext exe_ctx (GetExecutionContextRef()); 3630 m_addr_of_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), 3631 clang_type.GetPointerType(), 3632 ConstString (name.c_str()), 3633 addr, 3634 eAddressTypeInvalid, 3635 m_data.GetAddressByteSize()); 3636 } 3637 } 3638 break; 3639 } 3640 } 3641 else 3642 { 3643 StreamString expr_path_strm; 3644 GetExpressionPath(expr_path_strm, true); 3645 error.SetErrorStringWithFormat("'%s' doesn't have a valid address", expr_path_strm.GetString().c_str()); 3646 } 3647 3648 return m_addr_of_valobj_sp; 3649} 3650 3651ValueObjectSP 3652ValueObject::Cast (const ClangASTType &clang_ast_type) 3653{ 3654 return ValueObjectCast::Create (*this, GetName(), clang_ast_type); 3655} 3656 3657ValueObjectSP 3658ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type) 3659{ 3660 ValueObjectSP valobj_sp; 3661 AddressType address_type; 3662 addr_t ptr_value = GetPointerValue (&address_type); 3663 3664 if (ptr_value != LLDB_INVALID_ADDRESS) 3665 { 3666 Address ptr_addr (ptr_value); 3667 ExecutionContext exe_ctx (GetExecutionContextRef()); 3668 valobj_sp = ValueObjectMemory::Create (exe_ctx.GetBestExecutionContextScope(), 3669 name, 3670 ptr_addr, 3671 clang_ast_type); 3672 } 3673 return valobj_sp; 3674} 3675 3676ValueObjectSP 3677ValueObject::CastPointerType (const char *name, TypeSP &type_sp) 3678{ 3679 ValueObjectSP valobj_sp; 3680 AddressType address_type; 3681 addr_t ptr_value = GetPointerValue (&address_type); 3682 3683 if (ptr_value != LLDB_INVALID_ADDRESS) 3684 { 3685 Address ptr_addr (ptr_value); 3686 ExecutionContext exe_ctx (GetExecutionContextRef()); 3687 valobj_sp = ValueObjectMemory::Create (exe_ctx.GetBestExecutionContextScope(), 3688 name, 3689 ptr_addr, 3690 type_sp); 3691 } 3692 return valobj_sp; 3693} 3694 3695ValueObject::EvaluationPoint::EvaluationPoint () : 3696 m_mod_id(), 3697 m_exe_ctx_ref(), 3698 m_needs_update (true), 3699 m_first_update (true) 3700{ 3701} 3702 3703ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected): 3704 m_mod_id(), 3705 m_exe_ctx_ref(), 3706 m_needs_update (true), 3707 m_first_update (true) 3708{ 3709 ExecutionContext exe_ctx(exe_scope); 3710 TargetSP target_sp (exe_ctx.GetTargetSP()); 3711 if (target_sp) 3712 { 3713 m_exe_ctx_ref.SetTargetSP (target_sp); 3714 ProcessSP process_sp (exe_ctx.GetProcessSP()); 3715 if (!process_sp) 3716 process_sp = target_sp->GetProcessSP(); 3717 3718 if (process_sp) 3719 { 3720 m_mod_id = process_sp->GetModID(); 3721 m_exe_ctx_ref.SetProcessSP (process_sp); 3722 3723 ThreadSP thread_sp (exe_ctx.GetThreadSP()); 3724 3725 if (!thread_sp) 3726 { 3727 if (use_selected) 3728 thread_sp = process_sp->GetThreadList().GetSelectedThread(); 3729 } 3730 3731 if (thread_sp) 3732 { 3733 m_exe_ctx_ref.SetThreadSP(thread_sp); 3734 3735 StackFrameSP frame_sp (exe_ctx.GetFrameSP()); 3736 if (!frame_sp) 3737 { 3738 if (use_selected) 3739 frame_sp = thread_sp->GetSelectedFrame(); 3740 } 3741 if (frame_sp) 3742 m_exe_ctx_ref.SetFrameSP(frame_sp); 3743 } 3744 } 3745 } 3746} 3747 3748ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) : 3749 m_mod_id(), 3750 m_exe_ctx_ref(rhs.m_exe_ctx_ref), 3751 m_needs_update (true), 3752 m_first_update (true) 3753{ 3754} 3755 3756ValueObject::EvaluationPoint::~EvaluationPoint () 3757{ 3758} 3759 3760// This function checks the EvaluationPoint against the current process state. If the current 3761// state matches the evaluation point, or the evaluation point is already invalid, then we return 3762// false, meaning "no change". If the current state is different, we update our state, and return 3763// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so 3764// future calls to NeedsUpdate will return true. 3765// exe_scope will be set to the current execution context scope. 3766 3767bool 3768ValueObject::EvaluationPoint::SyncWithProcessState() 3769{ 3770 3771 // Start with the target, if it is NULL, then we're obviously not going to get any further: 3772 ExecutionContext exe_ctx(m_exe_ctx_ref.Lock()); 3773 3774 if (exe_ctx.GetTargetPtr() == NULL) 3775 return false; 3776 3777 // If we don't have a process nothing can change. 3778 Process *process = exe_ctx.GetProcessPtr(); 3779 if (process == NULL) 3780 return false; 3781 3782 // If our stop id is the current stop ID, nothing has changed: 3783 ProcessModID current_mod_id = process->GetModID(); 3784 3785 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared. 3786 // In either case, we aren't going to be able to sync with the process state. 3787 if (current_mod_id.GetStopID() == 0) 3788 return false; 3789 3790 bool changed = false; 3791 const bool was_valid = m_mod_id.IsValid(); 3792 if (was_valid) 3793 { 3794 if (m_mod_id == current_mod_id) 3795 { 3796 // Everything is already up to date in this object, no need to 3797 // update the execution context scope. 3798 changed = false; 3799 } 3800 else 3801 { 3802 m_mod_id = current_mod_id; 3803 m_needs_update = true; 3804 changed = true; 3805 } 3806 } 3807 3808 // Now re-look up the thread and frame in case the underlying objects have gone away & been recreated. 3809 // That way we'll be sure to return a valid exe_scope. 3810 // If we used to have a thread or a frame but can't find it anymore, then mark ourselves as invalid. 3811 3812 if (m_exe_ctx_ref.HasThreadRef()) 3813 { 3814 ThreadSP thread_sp (m_exe_ctx_ref.GetThreadSP()); 3815 if (thread_sp) 3816 { 3817 if (m_exe_ctx_ref.HasFrameRef()) 3818 { 3819 StackFrameSP frame_sp (m_exe_ctx_ref.GetFrameSP()); 3820 if (!frame_sp) 3821 { 3822 // We used to have a frame, but now it is gone 3823 SetInvalid(); 3824 changed = was_valid; 3825 } 3826 } 3827 } 3828 else 3829 { 3830 // We used to have a thread, but now it is gone 3831 SetInvalid(); 3832 changed = was_valid; 3833 } 3834 3835 } 3836 return changed; 3837} 3838 3839void 3840ValueObject::EvaluationPoint::SetUpdated () 3841{ 3842 ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP()); 3843 if (process_sp) 3844 m_mod_id = process_sp->GetModID(); 3845 m_first_update = false; 3846 m_needs_update = false; 3847} 3848 3849 3850 3851void 3852ValueObject::ClearUserVisibleData(uint32_t clear_mask) 3853{ 3854 if ((clear_mask & eClearUserVisibleDataItemsValue) == eClearUserVisibleDataItemsValue) 3855 m_value_str.clear(); 3856 3857 if ((clear_mask & eClearUserVisibleDataItemsLocation) == eClearUserVisibleDataItemsLocation) 3858 m_location_str.clear(); 3859 3860 if ((clear_mask & eClearUserVisibleDataItemsSummary) == eClearUserVisibleDataItemsSummary) 3861 { 3862 m_summary_str.clear(); 3863 } 3864 3865 if ((clear_mask & eClearUserVisibleDataItemsDescription) == eClearUserVisibleDataItemsDescription) 3866 m_object_desc_str.clear(); 3867 3868 if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) == eClearUserVisibleDataItemsSyntheticChildren) 3869 { 3870 if (m_synthetic_value) 3871 m_synthetic_value = NULL; 3872 } 3873} 3874 3875SymbolContextScope * 3876ValueObject::GetSymbolContextScope() 3877{ 3878 if (m_parent) 3879 { 3880 if (!m_parent->IsPointerOrReferenceType()) 3881 return m_parent->GetSymbolContextScope(); 3882 } 3883 return NULL; 3884} 3885 3886lldb::ValueObjectSP 3887ValueObject::CreateValueObjectFromExpression (const char* name, 3888 const char* expression, 3889 const ExecutionContext& exe_ctx) 3890{ 3891 lldb::ValueObjectSP retval_sp; 3892 lldb::TargetSP target_sp(exe_ctx.GetTargetSP()); 3893 if (!target_sp) 3894 return retval_sp; 3895 if (!expression || !*expression) 3896 return retval_sp; 3897 target_sp->EvaluateExpression (expression, 3898 exe_ctx.GetFrameSP().get(), 3899 retval_sp); 3900 if (retval_sp && name && *name) 3901 retval_sp->SetName(ConstString(name)); 3902 return retval_sp; 3903} 3904 3905lldb::ValueObjectSP 3906ValueObject::CreateValueObjectFromAddress (const char* name, 3907 uint64_t address, 3908 const ExecutionContext& exe_ctx, 3909 ClangASTType type) 3910{ 3911 if (type) 3912 { 3913 ClangASTType pointer_type(type.GetPointerType()); 3914 if (pointer_type) 3915 { 3916 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); 3917 lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), 3918 pointer_type, 3919 ConstString(name), 3920 buffer, 3921 lldb::endian::InlHostByteOrder(), 3922 exe_ctx.GetAddressByteSize())); 3923 if (ptr_result_valobj_sp) 3924 { 3925 ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress); 3926 Error err; 3927 ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err); 3928 if (ptr_result_valobj_sp && name && *name) 3929 ptr_result_valobj_sp->SetName(ConstString(name)); 3930 } 3931 return ptr_result_valobj_sp; 3932 } 3933 } 3934 return lldb::ValueObjectSP(); 3935} 3936 3937lldb::ValueObjectSP 3938ValueObject::CreateValueObjectFromData (const char* name, 3939 DataExtractor& data, 3940 const ExecutionContext& exe_ctx, 3941 ClangASTType type) 3942{ 3943 lldb::ValueObjectSP new_value_sp; 3944 new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), 3945 type, 3946 ConstString(name), 3947 data, 3948 LLDB_INVALID_ADDRESS); 3949 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad); 3950 if (new_value_sp && name && *name) 3951 new_value_sp->SetName(ConstString(name)); 3952 return new_value_sp; 3953} 3954 3955ModuleSP 3956ValueObject::GetModule () 3957{ 3958 ValueObject* root(GetRoot()); 3959 if (root != this) 3960 return root->GetModule(); 3961 return lldb::ModuleSP(); 3962} 3963 3964ValueObject* 3965ValueObject::GetRoot () 3966{ 3967 if (m_root) 3968 return m_root; 3969 ValueObject* parent = m_parent; 3970 if (!parent) 3971 return (m_root = this); 3972 while (parent->m_parent) 3973 { 3974 if (parent->m_root) 3975 return (m_root = parent->m_root); 3976 parent = parent->m_parent; 3977 } 3978 return (m_root = parent); 3979} 3980 3981AddressType 3982ValueObject::GetAddressTypeOfChildren() 3983{ 3984 if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) 3985 { 3986 ValueObject* root(GetRoot()); 3987 if (root != this) 3988 return root->GetAddressTypeOfChildren(); 3989 } 3990 return m_address_type_of_ptr_or_ref_children; 3991} 3992 3993lldb::DynamicValueType 3994ValueObject::GetDynamicValueType () 3995{ 3996 ValueObject* with_dv_info = this; 3997 while (with_dv_info) 3998 { 3999 if (with_dv_info->HasDynamicValueTypeInfo()) 4000 return with_dv_info->GetDynamicValueTypeImpl(); 4001 with_dv_info = with_dv_info->m_parent; 4002 } 4003 return lldb::eNoDynamicValues; 4004} 4005 4006lldb::Format 4007ValueObject::GetFormat () const 4008{ 4009 const ValueObject* with_fmt_info = this; 4010 while (with_fmt_info) 4011 { 4012 if (with_fmt_info->m_format != lldb::eFormatDefault) 4013 return with_fmt_info->m_format; 4014 with_fmt_info = with_fmt_info->m_parent; 4015 } 4016 return m_format; 4017} 4018