[Lldb-commits] [lldb] r153495 - in /lldb/trunk: examples/synthetic/ include/lldb/API/ include/lldb/Core/ include/lldb/Target/ scripts/Python/interface/ source/API/ source/Core/ source/Interpreter/ source/Target/ test/functionalities/completion/ test/functionalities/data-formatter/data-formatter-stl/libcxx/map/ test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/ test/functionalities/data-formatter/data-formatter-synth/ test/python_api/formatters/
Enrico Granata
egranata at apple.com
Mon Mar 26 19:35:13 PDT 2012
Author: enrico
Date: Mon Mar 26 21:35:13 2012
New Revision: 153495
URL: http://llvm.org/viewvc/llvm-project?rev=153495&view=rev
Log:
Synthetic values are now automatically enabled and active by default. SBValue is set up to always wrap a synthetic value when one is available.
A new setting enable-synthetic-value is provided on the target to disable this behavior.
There also is a new GetNonSyntheticValue() API call on SBValue to go back from synthetic to non-synthetic. There is no call to go from non-synthetic to synthetic.
The test suite has been changed accordingly.
Fallout from changes to type searching: an hack has to be played to make it possible to use maps that contain std::string due to the special name replacement operated by clang
Fixing a test case that was using libstdcpp instead of libc++ - caught as a consequence of said changes to type searching
Modified:
lldb/trunk/examples/synthetic/gnu_libstdcpp.py
lldb/trunk/examples/synthetic/libcxx.py
lldb/trunk/include/lldb/API/SBValue.h
lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
lldb/trunk/include/lldb/Target/Target.h
lldb/trunk/scripts/Python/interface/SBValue.i
lldb/trunk/source/API/SBValue.cpp
lldb/trunk/source/Core/Debugger.cpp
lldb/trunk/source/Core/FormatManager.cpp
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
lldb/trunk/source/Target/Target.cpp
lldb/trunk/test/functionalities/completion/TestCompletion.py
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py
lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py
lldb/trunk/test/python_api/formatters/TestFormattersSBAPI.py
lldb/trunk/test/python_api/formatters/jas_synth.py
lldb/trunk/test/python_api/formatters/main.cpp
Modified: lldb/trunk/examples/synthetic/gnu_libstdcpp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/gnu_libstdcpp.py?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/examples/synthetic/gnu_libstdcpp.py (original)
+++ lldb/trunk/examples/synthetic/gnu_libstdcpp.py Mon Mar 26 21:35:13 2012
@@ -85,6 +85,8 @@
def extract_type(self):
list_type = self.valobj.GetType().GetUnqualifiedType()
+ if list_type.IsReferenceType():
+ list_type = list_type.GetDereferencedType()
if list_type.GetNumberOfTemplateArguments() > 0:
data_type = list_type.GetTemplateArgumentType(0)
else:
@@ -200,15 +202,15 @@
# to replace the longer versions of std::string with the shorter one in order to be able
# to find the type name
def fixup_class_name(self, class_name):
- if class_name == 'std::basic_string<char, class std::char_traits<char>, class std::allocator<char> >':
- return 'std::basic_string<char>'
- if class_name == 'basic_string<char, class std::char_traits<char>, class std::allocator<char> >':
- return 'std::basic_string<char>'
if class_name == 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >':
- return 'std::basic_string<char>'
+ return 'std::basic_string<char>',True
if class_name == 'basic_string<char, std::char_traits<char>, std::allocator<char> >':
- return 'std::basic_string<char>'
- return class_name
+ return 'std::basic_string<char>',True
+ if class_name == 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >':
+ return 'std::basic_string<char>',True
+ if class_name == 'basic_string<char, std::char_traits<char>, std::allocator<char> >':
+ return 'std::basic_string<char>',True
+ return class_name,False
def update(self):
try:
@@ -216,13 +218,27 @@
self.Mimpl = self.Mt.GetChildMemberWithName('_M_impl')
self.Mheader = self.Mimpl.GetChildMemberWithName('_M_header')
- map_arg_0 = str(self.valobj.GetType().GetTemplateArgumentType(0).GetName())
- map_arg_1 = str(self.valobj.GetType().GetTemplateArgumentType(1).GetName())
+ map_type = self.valobj.GetType()
+ if map_type.IsReferenceType():
+ map_type = map_type.GetDereferencedType()
+
+ map_arg_0 = str(map_type.GetTemplateArgumentType(0).GetName())
+ map_arg_1 = str(map_type.GetTemplateArgumentType(1).GetName())
- map_arg_0 = self.fixup_class_name(map_arg_0)
- map_arg_1 = self.fixup_class_name(map_arg_1)
+ map_arg_0,fixed_0 = self.fixup_class_name(map_arg_0)
+ map_arg_1,fixed_1 = self.fixup_class_name(map_arg_1)
+
+ # HACK: this is related to the above issue with the typename for std::string
+ # being shortened by clang - the changes to typename display and searching to honor
+ # namespaces make it so that we go looking for std::pair<const std::basic_string<char>, ...>
+ # but when we find a type for this, we then compare it against the fully-qualified
+ # std::pair<const std::basic_string<char, std::char_traits... and of course fail
+ # the way to bypass this problem is to avoid using the std:: prefix in this specific case
+ if fixed_0 or fixed_1:
+ map_arg_type = "pair<const " + map_arg_0 + ", " + map_arg_1
+ else:
+ map_arg_type = "std::pair<const " + map_arg_0 + ", " + map_arg_1
- map_arg_type = "std::pair<const " + map_arg_0 + ", " + map_arg_1
if map_arg_1[-1] == '>':
map_arg_type = map_arg_type + " >"
else:
Modified: lldb/trunk/examples/synthetic/libcxx.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/libcxx.py?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/examples/synthetic/libcxx.py (original)
+++ lldb/trunk/examples/synthetic/libcxx.py Mon Mar 26 21:35:13 2012
@@ -253,6 +253,8 @@
def extract_type(self):
list_type = self.valobj.GetType().GetUnqualifiedType()
+ if list_type.IsReferenceType():
+ list_type = list_type.GetDereferencedType()
if list_type.GetNumberOfTemplateArguments() > 0:
data_type = list_type.GetTemplateArgumentType(0)
else:
Modified: lldb/trunk/include/lldb/API/SBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBValue.h (original)
+++ lldb/trunk/include/lldb/API/SBValue.h Mon Mar 26 21:35:13 2012
@@ -92,6 +92,9 @@
lldb::SBValue
GetStaticValue ();
+ lldb::SBValue
+ GetNonSyntheticValue ();
+
bool
IsDynamic();
@@ -370,6 +373,10 @@
lldb::ValueObjectSP
GetSP () const;
+ // anyone who needs to set the value of the SP on this SBValue should rely on SetSP() exclusively
+ // since this function contains logic to "do the right thing" with regard to providing to the user
+ // a synthetic value when possible - in the future the same should automatically occur with
+ // dynamic values
void
SetSP (const lldb::ValueObjectSP &sp);
Modified: lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h Mon Mar 26 21:35:13 2012
@@ -120,7 +120,7 @@
ByIndexMap m_children_byindex;
NameToIndexMap m_name_toindex;
- uint32_t m_children_count;
+ uint32_t m_synthetic_children_count; // FIXME use the ValueObject's ChildrenManager instead of a special purpose solution
private:
friend class ValueObject;
Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Mon Mar 26 21:35:13 2012
@@ -74,7 +74,19 @@
{
return (lldb::DynamicValueType) g_dynamic_value_types[m_prefer_dynamic_value].value;
}
+
+ bool
+ GetEnableSyntheticValue ()
+ {
+ return m_enable_synthetic_value;
+ }
+ void
+ SetEnableSyntheticValue (bool b)
+ {
+ m_enable_synthetic_value = b;
+ }
+
bool
GetSkipPrologue()
{
@@ -236,6 +248,7 @@
OptionValueFileSpec m_expr_prefix_file;
std::string m_expr_prefix_contents;
int m_prefer_dynamic_value;
+ OptionValueBoolean m_enable_synthetic_value;
OptionValueBoolean m_skip_prologue;
PathMappingList m_source_map;
FileSpecList m_exe_search_paths;
@@ -1024,6 +1037,20 @@
return m_suppress_stop_hooks;
}
+ bool
+ SetSuppressSyntheticValue (bool suppress)
+ {
+ bool old_value = m_suppress_synthetic_value;
+ m_suppress_synthetic_value = suppress;
+ return old_value;
+ }
+
+ bool
+ GetSuppressSyntheticValue ()
+ {
+ return m_suppress_synthetic_value;
+ }
+
// StopHookSP &
// GetStopHookByIndex (size_t index);
//
@@ -1169,6 +1196,7 @@
StopHookCollection m_stop_hooks;
lldb::user_id_t m_stop_hook_next_id;
bool m_suppress_stop_hooks;
+ bool m_suppress_synthetic_value;
static void
ImageSearchPathsChanged (const PathMappingList &path_list,
Modified: lldb/trunk/scripts/Python/interface/SBValue.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBValue.i?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBValue.i (original)
+++ lldb/trunk/scripts/Python/interface/SBValue.i Mon Mar 26 21:35:13 2012
@@ -127,6 +127,9 @@
lldb::SBValue
GetStaticValue ();
+ lldb::SBValue
+ GetNonSyntheticValue ();
+
bool
IsDynamic();
@@ -378,81 +381,78 @@
%pythoncode %{
__swig_getmethods__["name"] = GetName
- if _newclass: x = property(GetName, None)
+ if _newclass: name = property(GetName, None, doc='Returns the name of this SBValue as a string')
__swig_getmethods__["type"] = GetType
- if _newclass: x = property(GetType, None)
+ if _newclass: type = property(GetType, None, doc='Returns an SBType that represents the type of this SBValue')
__swig_getmethods__["size"] = GetByteSize
- if _newclass: x = property(GetByteSize, None)
-
- __swig_getmethods__["name"] = GetName
- if _newclass: x = property(GetName, None)
+ if _newclass: size = property(GetByteSize, None, doc='Returns the size (in bytes) of the data contained in this SBValue')
__swig_getmethods__["is_in_scope"] = IsInScope
- if _newclass: x = property(IsInScope, None)
+ if _newclass: is_in_scope = property(IsInScope, None, doc='Returns True if this SBValue represents an item that is currently in lexical scope')
__swig_getmethods__["format"] = GetFormat
__swig_setmethods__["format"] = SetFormat
- if _newclass: x = property(GetName, SetFormat)
+ if _newclass: format = property(GetName, SetFormat, doc='Returns the format for this SBValue')
__swig_getmethods__["value"] = GetValue
__swig_setmethods__["value"] = SetValueFromCString
- if _newclass: x = property(GetValue, SetValueFromCString)
+ if _newclass: value = property(GetValue, SetValueFromCString, doc='Returns the value of this SBValue as a string')
__swig_getmethods__["value_type"] = GetValueType
- if _newclass: x = property(GetValueType, None)
+ if _newclass: value_type = property(GetValueType, None, doc='Returns the type of entry stored in this SBValue')
__swig_getmethods__["changed"] = GetValueDidChange
- if _newclass: x = property(GetValueDidChange, None)
+ if _newclass: changed = property(GetValueDidChange, None, doc='Returns True if this SBValue represents an item that has changed')
__swig_getmethods__["data"] = GetData
- if _newclass: x = property(GetData, None)
+ if _newclass: data = property(GetData, None, doc='Returns an SBData wrapping the contents of this SBValue')
__swig_getmethods__["load_addr"] = GetLoadAddress
- if _newclass: x = property(GetLoadAddress, None)
+ if _newclass: load_addr = property(GetLoadAddress, None, doc='Returns the load address (target address) of this SBValue as a number')
__swig_getmethods__["addr"] = GetAddress
- if _newclass: x = property(GetAddress, None)
+ if _newclass: addr = property(GetAddress, None, doc='Returns the address of this SBValue as an SBAddress')
__swig_getmethods__["deref"] = Dereference
- if _newclass: x = property(Dereference, None)
+ if _newclass: deref = property(Dereference, None, doc='Returns an SBValue that is created by dereferencing this SBValue')
__swig_getmethods__["address_of"] = AddressOf
- if _newclass: x = property(AddressOf, None)
+ if _newclass: address_of = property(AddressOf, None, doc='Returns an SBValue that wraps the address-of this SBValue')
__swig_getmethods__["error"] = GetError
- if _newclass: x = property(GetError, None)
+ if _newclass: error = property(GetError, None, doc='Returns the SBError currently associated to this SBValue')
__swig_getmethods__["summary"] = GetSummary
- if _newclass: x = property(GetSummary, None)
+ if _newclass: summary = property(GetSummary, None, doc='Returns the summary for this SBValue as a string')
__swig_getmethods__["description"] = GetObjectDescription
- if _newclass: x = property(GetObjectDescription, None)
+ if _newclass: description = property(GetObjectDescription, None, doc='Returns the language-specific description of this SBValue as a string')
__swig_getmethods__["location"] = GetLocation
- if _newclass: x = property(GetLocation, None)
+ if _newclass: location = property(GetLocation, None, doc='Returns the location of this SBValue as a string')
__swig_getmethods__["target"] = GetTarget
- if _newclass: x = property(GetTarget, None)
+ if _newclass: target = property(GetTarget, None, doc='Returns an SBTarget for the target from which this SBValue comes')
__swig_getmethods__["process"] = GetProcess
- if _newclass: x = property(GetProcess, None)
+ if _newclass: process = property(GetProcess, None, doc='Returns an SBProcess for the process from which this SBValue comes')
__swig_getmethods__["thread"] = GetThread
- if _newclass: x = property(GetThread, None)
+ if _newclass: thread = property(GetThread, None, doc='Returns an SBThread for the thread from which this SBValue comes')
__swig_getmethods__["frame"] = GetFrame
- if _newclass: x = property(GetFrame, None)
+ if _newclass: frame = property(GetFrame, None, doc='Returns an SBFrame for the stack frame from which this SBValue comes')
__swig_getmethods__["num_children"] = GetNumChildren
- if _newclass: x = property(GetNumChildren, None)
+ if _newclass: num_children = property(GetNumChildren, None, doc='Returns the number of child SBValues that this SBValue has')
__swig_getmethods__["unsigned"] = GetValueAsUnsigned
- if _newclass: x = property(GetValueAsUnsigned, None)
+ if _newclass: unsigned = property(GetValueAsUnsigned, None, doc='Returns the value of this SBValue as an unsigned number')
__swig_getmethods__["signed"] = GetValueAsSigned
- if _newclass: x = property(GetValueAsSigned, None)
+ if _newclass: signed = property(GetValueAsSigned, None, doc='Returns the value of this SBValue as a signed number')
def get_expr_path(self):
s = SBStream()
@@ -460,7 +460,7 @@
return s.GetData()
__swig_getmethods__["path"] = get_expr_path
- if _newclass: x = property(get_expr_path, None)
+ if _newclass: path = property(get_expr_path, None, doc='Returns the expression path that one can use to reach this SBValue')
%}
};
Modified: lldb/trunk/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/source/API/SBValue.cpp (original)
+++ lldb/trunk/source/API/SBValue.cpp Mon Mar 26 21:35:13 2012
@@ -51,21 +51,23 @@
{
}
-SBValue::SBValue (const lldb::ValueObjectSP &value_sp) :
- m_opaque_sp (value_sp)
+SBValue::SBValue (const lldb::ValueObjectSP &value_sp)
{
+ SetSP(value_sp); // whenever setting the SP call SetSP() since it knows how to deal with synthetic values properly
}
-SBValue::SBValue(const SBValue &rhs) :
- m_opaque_sp (rhs.m_opaque_sp)
+SBValue::SBValue(const SBValue &rhs)
{
+ SetSP(rhs.m_opaque_sp); // whenever setting the SP call SetSP() since it knows how to deal with synthetic values properly
}
SBValue &
SBValue::operator = (const SBValue &rhs)
{
if (this != &rhs)
- m_opaque_sp = rhs.m_opaque_sp;
+ {
+ SetSP(rhs.m_opaque_sp); // whenever setting the SP call SetSP() since it knows how to deal with synthetic values properly
+ }
return *this;
}
@@ -809,6 +811,30 @@
return SBValue();
}
+lldb::SBValue
+SBValue::GetNonSyntheticValue ()
+{
+ SBValue sb_value;
+ lldb::ValueObjectSP value_sp(GetSP());
+ if (value_sp)
+ {
+ if (value_sp->IsSynthetic())
+ {
+ TargetSP target_sp(value_sp->GetTargetSP());
+ if (target_sp)
+ {
+ Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ // deliberately breaking the rules here to optimize the case where we DO NOT want
+ // the synthetic value to be returned to the user - if we did not do this, we would have to tell
+ // the target to suppress the synthetic value, and then return the flag to its original value
+ if (value_sp->GetParent())
+ sb_value.m_opaque_sp = value_sp->GetParent()->GetSP();
+ }
+ }
+ }
+ return sb_value;
+}
+
bool
SBValue::IsDynamic()
{
@@ -1124,6 +1150,8 @@
SBValue::SetSP (const lldb::ValueObjectSP &sp)
{
m_opaque_sp = sp;
+ if (IsValid() && m_opaque_sp->HasSyntheticValue())
+ m_opaque_sp = m_opaque_sp->GetSyntheticValue();
}
Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Mon Mar 26 21:35:13 2012
@@ -1164,7 +1164,8 @@
if (*var_name_begin == 's')
{
- valobj = valobj->GetSyntheticValue().get();
+ if (!valobj->IsSynthetic())
+ valobj = valobj->GetSyntheticValue().get();
if (!valobj)
break;
var_name_begin++;
Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Mon Mar 26 21:35:13 2012
@@ -639,18 +639,24 @@
SyntheticChildren::Flags stl_synth_flags;
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
- gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?vector<.+>$")),
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"gnu_libstdcpp.StdVectorSynthProvider")));
- gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?map<.+> >$")),
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"gnu_libstdcpp.StdMapSynthProvider")));
- gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?list<.+>$")),
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::list<.+>(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"gnu_libstdcpp.StdListSynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
- gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?vector<.+>$")),
+ gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
+ "size=${svar%#}")));
+ gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
+ "size=${svar%#}")));
+ gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::list<.+>(( )?&)?$")),
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
"size=${svar%#}")));
#endif
@@ -682,22 +688,22 @@
SyntheticChildren::Flags stl_synth_flags;
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)vector<.+>$")),
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"libcxx.stdvector_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)list<.+>$")),
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::list<.+>(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"libcxx.stdlist_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)map<.+> >$")),
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::map<.+> >(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"libcxx.stdmap_SynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)vector<.+>$")),
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?")),
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)list<.+>$")),
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::list<.+>(( )?&)?$")),
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)map<.+> >$")),
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::map<.+> >(( )?&)?$")),
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
#endif
}
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Mon Mar 26 21:35:13 2012
@@ -572,6 +572,7 @@
uint32_t
ValueObject::GetNumChildren ()
{
+ UpdateValueIfNeeded();
if (!m_children_count_valid)
{
SetNumChildren (CalculateNumChildren());
@@ -2009,6 +2010,13 @@
if (use_synthetic == false)
return;
+ TargetSP target_sp(GetTargetSP());
+ if (target_sp && (target_sp->GetEnableSyntheticValue() == false || target_sp->GetSuppressSyntheticValue() == true))
+ {
+ m_synthetic_value = NULL;
+ return;
+ }
+
if (!UpdateFormatsIfNeeded(m_last_format_mgr_dynamic) && m_synthetic_value)
return;
@@ -3317,6 +3325,7 @@
ValueObject* synth_valobj;
ValueObjectSP synth_valobj_sp = valobj->GetSyntheticValue (options.m_use_synthetic);
synth_valobj = (synth_valobj_sp ? synth_valobj_sp.get() : valobj);
+
uint32_t num_children = synth_valobj->GetNumChildren();
bool print_dotdotdot = false;
if (num_children)
Modified: lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp Mon Mar 26 21:35:13 2012
@@ -25,7 +25,7 @@
m_synth_filter_ap(filter->GetFrontEnd(parent)),
m_children_byindex(),
m_name_toindex(),
- m_children_count(UINT32_MAX)
+ m_synthetic_children_count(UINT32_MAX)
{
#ifdef LLDB_CONFIGURATION_DEBUG
std::string new_name(parent.GetName().AsCString());
@@ -56,9 +56,9 @@
ValueObjectSynthetic::CalculateNumChildren()
{
UpdateValueIfNeeded();
- if (m_children_count < UINT32_MAX)
- return m_children_count;
- return (m_children_count = m_synth_filter_ap->CalculateNumChildren());
+ if (m_synthetic_children_count < UINT32_MAX)
+ return m_synthetic_children_count;
+ return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren());
}
clang::ASTContext *
@@ -99,7 +99,11 @@
// filter said that cached values are stale
m_children_byindex.clear();
m_name_toindex.clear();
- m_children_count = UINT32_MAX;
+ // usually, an object's value can change but this does not alter its children count
+ // for a synthetic VO that might indeed happen, so we need to tell the upper echelons
+ // that they need to come back to us asking for children
+ m_children_count_valid = false;
+ m_synthetic_children_count = UINT32_MAX;
}
SetValueIsValid(true);
Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Mon Mar 26 21:35:13 2012
@@ -234,6 +234,24 @@
DoFreeLock();
}
+class ForceDisableSyntheticChildren
+{
+public:
+ ForceDisableSyntheticChildren (Target* target) :
+ m_target(target)
+ {
+ m_old_value = target->GetSuppressSyntheticValue();
+ target->SetSuppressSyntheticValue(true);
+ }
+ ~ForceDisableSyntheticChildren ()
+ {
+ m_target->SetSuppressSyntheticValue(m_old_value);
+ }
+private:
+ Target* m_target;
+ bool m_old_value;
+};
+
ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
ScriptInterpreter (interpreter, eScriptLanguagePython),
m_embedded_python_pty (),
@@ -1328,6 +1346,7 @@
{
Locker py_lock(this);
+ ForceDisableSyntheticChildren no_synthetics(target);
ret_val = g_swig_synthetic_script (class_name,
python_interpreter->m_dictionary_name.c_str(),
valobj);
@@ -1586,6 +1605,7 @@
{
Locker py_lock(this);
+ ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get());
ret_val = g_swig_calc_children (implementor);
}
@@ -1612,6 +1632,7 @@
{
Locker py_lock(this);
+ ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get());
child_ptr = g_swig_get_child_index (implementor,idx);
if (child_ptr != NULL && child_ptr != Py_None)
{
@@ -1648,6 +1669,7 @@
{
Locker py_lock(this);
+ ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get());
ret_val = g_swig_get_index_child (implementor, child_name);
}
@@ -1672,6 +1694,7 @@
{
Locker py_lock(this);
+ ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get());
ret_val = g_swig_update_provider (implementor);
}
Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Mon Mar 26 21:35:13 2012
@@ -73,7 +73,8 @@
m_source_manager(*this),
m_stop_hooks (),
m_stop_hook_next_id (0),
- m_suppress_stop_hooks (false)
+ m_suppress_stop_hooks (false),
+ m_suppress_synthetic_value(false)
{
SetEventName (eBroadcastBitBreakpointChanged, "breakpoint-changed");
SetEventName (eBroadcastBitModulesLoaded, "modules-loaded");
@@ -183,6 +184,7 @@
m_stop_hooks.clear();
m_stop_hook_next_id = 0;
m_suppress_stop_hooks = false;
+ m_suppress_synthetic_value = false;
}
@@ -2106,6 +2108,7 @@
#define TSC_DEFAULT_ARCH "default-arch"
#define TSC_EXPR_PREFIX "expr-prefix"
#define TSC_PREFER_DYNAMIC "prefer-dynamic-value"
+#define TSC_ENABLE_SYNTHETIC "enable-synthetic-value"
#define TSC_SKIP_PROLOGUE "skip-prologue"
#define TSC_SOURCE_MAP "source-map"
#define TSC_EXE_SEARCH_PATHS "exec-search-paths"
@@ -2144,6 +2147,13 @@
}
static const ConstString &
+GetSettingNameForEnableSyntheticValue ()
+{
+ static ConstString g_const_string (TSC_ENABLE_SYNTHETIC);
+ return g_const_string;
+}
+
+static const ConstString &
GetSettingNameForSourcePathMap ()
{
static ConstString g_const_string (TSC_SOURCE_MAP);
@@ -2291,6 +2301,7 @@
m_expr_prefix_file (),
m_expr_prefix_contents (),
m_prefer_dynamic_value (2),
+ m_enable_synthetic_value(true, true),
m_skip_prologue (true, true),
m_source_map (NULL, NULL),
m_exe_search_paths (),
@@ -2330,6 +2341,7 @@
m_expr_prefix_file (rhs.m_expr_prefix_file),
m_expr_prefix_contents (rhs.m_expr_prefix_contents),
m_prefer_dynamic_value (rhs.m_prefer_dynamic_value),
+ m_enable_synthetic_value(rhs.m_enable_synthetic_value),
m_skip_prologue (rhs.m_skip_prologue),
m_source_map (rhs.m_source_map),
m_exe_search_paths (rhs.m_exe_search_paths),
@@ -2365,6 +2377,7 @@
m_expr_prefix_file = rhs.m_expr_prefix_file;
m_expr_prefix_contents = rhs.m_expr_prefix_contents;
m_prefer_dynamic_value = rhs.m_prefer_dynamic_value;
+ m_enable_synthetic_value = rhs.m_enable_synthetic_value;
m_skip_prologue = rhs.m_skip_prologue;
m_source_map = rhs.m_source_map;
m_exe_search_paths = rhs.m_exe_search_paths;
@@ -2442,6 +2455,13 @@
if (err.Success())
m_prefer_dynamic_value = new_value;
}
+ else if (var_name == GetSettingNameForEnableSyntheticValue())
+ {
+ bool ok;
+ bool new_value = Args::StringToBoolean(value, true, &ok);
+ if (ok)
+ m_enable_synthetic_value.SetCurrentValue(new_value);
+ }
else if (var_name == GetSettingNameForSkipPrologue())
{
err = UserSettingsController::UpdateBooleanOptionValue (value, op, m_skip_prologue);
@@ -2626,6 +2646,13 @@
{
value.AppendString (g_dynamic_value_types[m_prefer_dynamic_value].string_value);
}
+ else if (var_name == GetSettingNameForEnableSyntheticValue())
+ {
+ if (m_skip_prologue)
+ value.AppendString ("true");
+ else
+ value.AppendString ("false");
+ }
else if (var_name == GetSettingNameForSkipPrologue())
{
if (m_skip_prologue)
@@ -2824,6 +2851,7 @@
// ================= ================== =============== ======================= ====== ====== =========================================================================
{ TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." },
{ TSC_PREFER_DYNAMIC , eSetVarTypeEnum , NULL , g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." },
+ { TSC_ENABLE_SYNTHETIC , eSetVarTypeBoolean, "true" , NULL, false, false, "Should synthetic values be used by default whenever available." },
{ TSC_SKIP_PROLOGUE , eSetVarTypeBoolean, "true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." },
{ TSC_SOURCE_MAP , eSetVarTypeArray , NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." },
{ TSC_EXE_SEARCH_PATHS , eSetVarTypeArray , NULL , NULL, false, false, "Executable search paths to use when locating executable files whose paths don't match the local file system." },
Modified: lldb/trunk/test/functionalities/completion/TestCompletion.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/completion/TestCompletion.py?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/completion/TestCompletion.py (original)
+++ lldb/trunk/test/functionalities/completion/TestCompletion.py Mon Mar 26 21:35:13 2012
@@ -57,12 +57,12 @@
self.complete_from_to('settings append target.er', 'settings append target.error-path')
def test_settings_insert_after_target_en(self):
- """Test that 'settings insert-after target.en' completes to 'settings insert-after target.env-vars'."""
- self.complete_from_to('settings insert-after target.en', 'settings insert-after target.env-vars')
+ """Test that 'settings insert-after target.env' completes to 'settings insert-after target.env-vars'."""
+ self.complete_from_to('settings insert-after target.env', 'settings insert-after target.env-vars')
def test_settings_insert_before_target_en(self):
- """Test that 'settings insert-before target.en' completes to 'settings insert-before target.env-vars'."""
- self.complete_from_to('settings insert-before target.en', 'settings insert-before target.env-vars')
+ """Test that 'settings insert-before target.env' completes to 'settings insert-before target.env-vars'."""
+ self.complete_from_to('settings insert-before target.env', 'settings insert-before target.env-vars')
def test_settings_replace_target_ru(self):
"""Test that 'settings replace target.ru' completes to 'settings replace target.run-args'."""
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py Mon Mar 26 21:35:13 2012
@@ -9,7 +9,7 @@
class LibcxxMapDataFormatterTestCase(TestBase):
- mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libstdcpp", "map")
+ mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libcxx", "map")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
def test_with_dsym_and_run_command(self):
@@ -56,6 +56,8 @@
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
+ self.expect('image list',substrs=['libc++.1.dylib','libc++abi.dylib'])
+
self.runCmd("frame variable ii -T")
self.runCmd("type summary add -x \"std::__1::map<\" --summary-string \"map has ${svar%#} items\" -e")
@@ -87,19 +89,20 @@
'second = 1'])
self.runCmd("n");self.runCmd("n");
- self.runCmd("n");self.runCmd("n");self.runCmd("n");
+ self.runCmd("n");self.runCmd("n");
+ self.runCmd("frame select 0")
self.expect("frame variable ii",
- substrs = ['map has 9 items',
+ substrs = ['map has 8 items',
'[5] = {',
'first = 5',
'second = 0',
'[7] = {',
'first = 7',
'second = 1'])
-
+
self.expect("p ii",
- substrs = ['map has 9 items',
+ substrs = ['map has 8 items',
'[5] = {',
'first = 5',
'second = 0',
@@ -114,9 +117,6 @@
self.expect("frame variable ii[3]",
substrs = ['first =',
'second =']);
-
- self.expect("frame variable ii[8]", matching=True,
- substrs = ['1234567'])
# check that the expression parser does not make use of
# synthetic children instead of running code
@@ -126,20 +126,19 @@
#self.expect("expression ii[8]", matching=False, error=True,
# substrs = ['1234567'])
- self.runCmd("n")
+ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd('frame select 0')
self.expect('frame variable ii',
substrs = ['map has 0 items',
'{}'])
- self.runCmd("n")
self.runCmd("frame variable si -T")
self.expect('frame variable si',
substrs = ['map has 0 items',
'{}'])
- self.runCmd("n")
+ self.runCmd("n");self.runCmd("n");self.runCmd('frame select 0')
self.expect('frame variable si',
substrs = ['map has 1 items',
@@ -148,9 +147,11 @@
'second = 0'])
self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
+ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n")
+ self.runCmd("n");self.runCmd("n");self.runCmd('frame select 0')
self.expect("frame variable si",
- substrs = ['map has 5 items',
+ substrs = ['map has 4 items',
'[0] = ',
'first = \"zero\"',
'second = 0',
@@ -162,13 +163,10 @@
'second = 2',
'[3] = ',
'first = \"three\"',
- 'second = 3',
- '[4] = ',
- 'first = \"four\"',
- 'second = 4'])
+ 'second = 3'])
self.expect("p si",
- substrs = ['map has 5 items',
+ substrs = ['map has 4 items',
'[0] = ',
'first = \"zero\"',
'second = 0',
@@ -180,15 +178,12 @@
'second = 2',
'[3] = ',
'first = \"three\"',
- 'second = 3',
- '[4] = ',
- 'first = \"four\"',
- 'second = 4'])
+ 'second = 3'])
# check access-by-index
self.expect("frame variable si[0]",
- substrs = ['first = ', 'four',
- 'second = 4']);
+ substrs = ['first = ', 'one',
+ 'second = 1']);
# check that the expression parser does not make use of
# synthetic children instead of running code
@@ -198,7 +193,7 @@
#self.expect("expression si[0]", matching=False, error=True,
# substrs = ['first = ', 'zero'])
- self.runCmd("n")
+ self.runCmd("n");self.runCmd("n");
self.expect('frame variable si',
substrs = ['map has 0 items',
@@ -262,17 +257,18 @@
substrs = ['map has 0 items',
'{}'])
- self.runCmd("n")
+ self.runCmd("n");self.runCmd("n");
self.runCmd("frame variable ss -T")
self.expect('frame variable ss',
substrs = ['map has 0 items',
'{}'])
- self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
+ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
+ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd('frame select 0')
self.expect("frame variable ss",
- substrs = ['map has 4 items',
+ substrs = ['map has 3 items',
'[0] = ',
'second = \"hello\"',
'first = \"ciao\"',
@@ -281,13 +277,10 @@
'first = \"casa\"',
'[2] = ',
'second = \"cat\"',
- 'first = \"gatto\"',
- '[3] = ',
- 'second = \"..is always a Mac!\"',
- 'first = \"a Mac..\"'])
+ 'first = \"gatto\"'])
self.expect("p ss",
- substrs = ['map has 4 items',
+ substrs = ['map has 3 items',
'[0] = ',
'second = \"hello\"',
'first = \"ciao\"',
@@ -296,13 +289,10 @@
'first = \"casa\"',
'[2] = ',
'second = \"cat\"',
- 'first = \"gatto\"',
- '[3] = ',
- 'second = \"..is always a Mac!\"',
- 'first = \"a Mac..\"'])
+ 'first = \"gatto\"'])
# check access-by-index
- self.expect("frame variable ss[3]",
+ self.expect("frame variable ss[2]",
substrs = ['gatto', 'cat']);
# check that the expression parser does not make use of
@@ -313,7 +303,7 @@
#self.expect("expression ss[3]", matching=False, error=True,
# substrs = ['gatto'])
- self.runCmd("n")
+ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd('frame select 0')
self.expect('frame variable ss',
substrs = ['map has 0 items',
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp Mon Mar 26 21:35:13 2012
@@ -1,5 +1,9 @@
-#include <map>
#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+#include <map>
#define intint_map std::map<int, int>
#define strint_map std::map<std::string, int>
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py Mon Mar 26 21:35:13 2012
@@ -64,6 +64,9 @@
self.expect("frame variable numbers_list --raw", matching=False,
substrs = ['list has 0 items',
'{}'])
+ self.expect("frame variable &numbers_list._M_impl._M_node --raw", matching=False,
+ substrs = ['list has 0 items',
+ '{}'])
self.expect("frame variable numbers_list",
substrs = ['list has 0 items',
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py Mon Mar 26 21:35:13 2012
@@ -83,16 +83,16 @@
'z = 8'])
# Summary+Synth must work together
- self.runCmd("type summary add BagOfInts --summary-string \"y=${var.y}\" -e")
+ self.runCmd("type summary add BagOfInts --summary-string \"x=${var.x}\" -e")
self.expect('frame variable int_bag',
- substrs = ['y=7',
+ substrs = ['x=6',
'x = 6',
'z = 8'])
# Same output, but using Python
- self.runCmd("type summary add BagOfInts --python-script \"return 'y=%s' % valobj.GetChildMemberWithName('y').GetValue()\" -e")
+ self.runCmd("type summary add BagOfInts --python-script \"return 'x=%s' % valobj.GetChildMemberWithName('x').GetValue()\" -e")
self.expect('frame variable int_bag',
- substrs = ['y=7',
+ substrs = ['x=6',
'x = 6',
'z = 8'])
@@ -111,10 +111,10 @@
# Add the synth again and check that it's honored deeper in the hierarchy
self.runCmd("type filter add BagOfInts --child x --child z")
self.expect('frame variable bag_bag',
- substrs = ['x = y=70 {',
+ substrs = ['x = x=69 {',
'x = 69',
'z = 71',
- 'y = y=67 {',
+ 'y = x=66 {',
'x = 66',
'z = 68'])
self.expect('frame variable bag_bag', matching=False,
Modified: lldb/trunk/test/python_api/formatters/TestFormattersSBAPI.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/formatters/TestFormattersSBAPI.py?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/test/python_api/formatters/TestFormattersSBAPI.py (original)
+++ lldb/trunk/test/python_api/formatters/TestFormattersSBAPI.py Mon Mar 26 21:35:13 2012
@@ -24,6 +24,13 @@
self.setTearDownCleanup()
self.formatters()
+ @python_api_test
+ def test_force_synth_off(self):
+ """Test that one can have the public API return non-synthetic SBValues if desired"""
+ self.buildDwarf(dictionary={'EXE':'no_synth'})
+ self.setTearDownCleanup()
+ self.force_synth_off()
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -155,7 +162,18 @@
self.expect("frame variable foo", matching=True,
substrs = ['X = 1'])
+ foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo')
+ self.assertTrue(foo_var.IsValid(), 'could not find foo')
+
+ self.assertTrue(foo_var.GetNumChildren() == 2, 'synthetic value has wrong number of child items (synth)')
+ self.assertTrue(foo_var.GetChildMemberWithName('X').GetValueAsUnsigned() == 1, 'foo_synth.X has wrong value (synth)')
+ self.assertFalse(foo_var.GetChildMemberWithName('B').IsValid(), 'foo_synth.B is valid but should not (synth)')
+
self.dbg.GetCategory("JASSynth").SetEnabled(False)
+ foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo')
+ self.assertTrue(foo_var.IsValid(), 'could not find foo')
+
+ self.assertFalse(foo_var.GetNumChildren() == 2, 'still seeing synthetic value')
filter = lldb.SBTypeFilter(0)
filter.AppendExpressionPath("A")
@@ -164,6 +182,13 @@
self.expect("frame variable foo",
substrs = ['A = 1', 'D = 6.28'])
+ foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo')
+ self.assertTrue(foo_var.IsValid(), 'could not find foo')
+
+ self.assertTrue(foo_var.GetNumChildren() == 2, 'synthetic value has wrong number of child items (filter)')
+ self.assertTrue(foo_var.GetChildMemberWithName('X').GetValueAsUnsigned() == 0, 'foo_synth.X has wrong value (filter)')
+ self.assertTrue(foo_var.GetChildMemberWithName('A').GetValueAsUnsigned() == 1, 'foo_synth.A has wrong value (filter)')
+
self.assertTrue(filter.ReplaceExpressionPathAtIndex(0,"C"), "failed to replace an expression path in filter")
self.expect("frame variable foo",
substrs = ['A = 1', 'D = 6.28'])
@@ -180,6 +205,10 @@
self.expect("frame variable bar",
substrs = ["C = 'e'", 'D = 6.28'])
+ foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo')
+ self.assertTrue(foo_var.IsValid(), 'could not find foo')
+ self.assertTrue(foo_var.GetChildMemberWithName('C').GetValueAsUnsigned() == ord('e'), 'foo_synth.C has wrong value (filter)')
+
chosen = self.dbg.GetFilterForType(lldb.SBTypeNameSpecifier("JustAStruct"))
self.assertTrue(chosen.count == 2, "wrong filter found for JustAStruct")
self.assertTrue(chosen.GetExpressionPathAtIndex(0) == 'C', "wrong item at index 0 for JustAStruct")
@@ -269,6 +298,58 @@
self.assertTrue(summary.IsValid(), "no summary found for foo* when one was in place")
self.assertTrue(summary.GetData() == "hello static world", "wrong summary found for foo*")
+ def force_synth_off(self):
+ """Test that one can have the public API return non-synthetic SBValues if desired"""
+ self.runCmd("file no_synth", CURRENT_EXECUTABLE_SET)
+
+ self.expect("breakpoint set -f main.cpp -l %d" % self.line,
+ BREAKPOINT_CREATED,
+ startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
+ self.line)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synthetic clear', check=False)
+ self.runCmd('type category delete foobar', check=False)
+ self.runCmd('type category delete JASSynth', check=False)
+ self.runCmd('type category delete newbar', check=False)
+ self.runCmd('settings set target.enable-synthetic-value true')
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
+ int_vector = frame.FindVariable("int_vector")
+ if self.TraceOn():
+ print int_vector
+ self.assertTrue(int_vector.GetNumChildren() == 0, 'synthetic vector is empty')
+
+ self.runCmd('settings set target.enable-synthetic-value false')
+ frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
+ int_vector = frame.FindVariable("int_vector")
+ if self.TraceOn():
+ print int_vector
+ self.assertFalse(int_vector.GetNumChildren() == 0, '"physical" vector is not empty')
+
+ self.runCmd('settings set target.enable-synthetic-value true')
+ frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
+ int_vector = frame.FindVariable("int_vector")
+ if self.TraceOn():
+ print int_vector
+ self.assertTrue(int_vector.GetNumChildren() == 0, 'synthetic vector is still empty')
+
+
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
Modified: lldb/trunk/test/python_api/formatters/jas_synth.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/formatters/jas_synth.py?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/test/python_api/formatters/jas_synth.py (original)
+++ lldb/trunk/test/python_api/formatters/jas_synth.py Mon Mar 26 21:35:13 2012
@@ -5,6 +5,7 @@
def num_children(self):
return 2;
def get_child_at_index(self, index):
+ child = None
if index == 0:
child = self.valobj.GetChildMemberWithName('A');
if index == 1:
@@ -15,7 +16,7 @@
return 0;
if name == 'X':
return 1;
- return 2;
+ return None;
def __lldb_init_module(debugger,dict):
debugger.CreateCategory("JASSynth").AddTypeSynthetic(lldb.SBTypeNameSpecifier("JustAStruct"),
Modified: lldb/trunk/test/python_api/formatters/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/formatters/main.cpp?rev=153495&r1=153494&r2=153495&view=diff
==============================================================================
--- lldb/trunk/test/python_api/formatters/main.cpp (original)
+++ lldb/trunk/test/python_api/formatters/main.cpp Mon Mar 26 21:35:13 2012
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <vector>
struct JustAStruct
{
@@ -34,5 +35,6 @@
bar.D = 6.28;
bar.E = 3100419850;
JustAStruct* foo_ptr = &foo;
+ std::vector<int> int_vector;
return 0; // Set break point at this line.
}
More information about the lldb-commits
mailing list