summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/ValueObject.h2
-rw-r--r--lldb/include/lldb/Core/ValueObjectSyntheticFilter.h12
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj2
-rw-r--r--lldb/source/Core/Debugger.cpp6
-rw-r--r--lldb/source/Core/ValueObject.cpp48
-rw-r--r--lldb/source/Target/StackFrame.cpp35
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py4
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py44
8 files changed, 125 insertions, 28 deletions
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h
index a46ffcf4caf..dc9dcdfe495 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -581,7 +581,7 @@ public:
lldb::ValueObjectSP
GetSyntheticValue (lldb::SyntheticValueType use_synthetic);
- bool
+ virtual bool
HasSyntheticValue();
virtual lldb::ValueObjectSP
diff --git a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
index ccfbacf9ead..0a1b0f157c4 100644
--- a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
+++ b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
@@ -65,6 +65,18 @@ public:
IsInScope ();
virtual bool
+ HasSyntheticValue()
+ {
+ return true; // we are our own synthetic value
+ }
+
+ virtual void
+ CalculateSyntheticValue (lldb::SyntheticValueType use_synthetic)
+ {
+ m_synthetic_value = this;
+ }
+
+ virtual bool
IsDynamic ()
{
if (m_parent)
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index 010397739c3..fac774857fa 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -1161,6 +1161,7 @@
69A01E1E1236C5D400C660B5 /* Mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mutex.cpp; sourceTree = "<group>"; };
69A01E1F1236C5D400C660B5 /* Symbols.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symbols.cpp; sourceTree = "<group>"; };
69A01E201236C5D400C660B5 /* TimeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeValue.cpp; sourceTree = "<group>"; };
+ 94005E0313F438DF001EF42D /* python-wrapper.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-wrapper.swig"; sourceTree = "<group>"; };
94031A9B13CF484600DCFF3C /* InputReaderEZ.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InputReaderEZ.h; path = include/lldb/Core/InputReaderEZ.h; sourceTree = "<group>"; };
94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputReaderEZ.cpp; path = source/Core/InputReaderEZ.cpp; sourceTree = "<group>"; };
94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PriorityPointerPair.h; path = include/lldb/Utility/PriorityPointerPair.h; sourceTree = "<group>"; };
@@ -1734,6 +1735,7 @@
266960611199F4230075C61A /* edit-swig-python-wrapper-file.py */,
266960621199F4230075C61A /* finish-swig-Python-lldb.sh */,
9A48A3A7124AAA5A00922451 /* python-extensions.swig */,
+ 94005E0313F438DF001EF42D /* python-wrapper.swig */,
);
path = Python;
sourceTree = "<group>";
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 8d13293640e..08cbb1c4755 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -795,7 +795,7 @@ ScanBracketedRange(const char* var_name_begin,
*index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
*index_higher = *index_lower;
if (log)
- log->Printf("[%d] detected, high index is same",index_lower);
+ log->Printf("[%d] detected, high index is same", *index_lower);
}
else if (*close_bracket_position && *close_bracket_position < var_name_end)
{
@@ -803,7 +803,7 @@ ScanBracketedRange(const char* var_name_begin,
*index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
*index_higher = ::strtoul (*separator_position+1, &end, 0);
if (log)
- log->Printf("[%d-%d] detected",index_lower,index_higher);
+ log->Printf("[%d-%d] detected", *index_lower, *index_higher);
}
else
{
@@ -1044,7 +1044,7 @@ Debugger::FormatPrompt
ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
ValueObject::eDereference : ValueObject::eNothing);
ValueObject::GetValueForExpressionPathOptions options;
- options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar();
+ options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eDisplaySummary;
ValueObject* target = NULL;
lldb::Format custom_format = eFormatInvalid;
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 80c8d5acd0f..fe27d712842 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -2032,13 +2032,28 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
if (!next_separator) // if no other separator just expand this last layer
{
child_name.SetCString (expression_cstr);
- root = root->GetChildMemberWithName(child_name, true);
- if (root.get()) // we know we are done, so just return
+ ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
+
+ if (child_valobj_sp.get()) // we know we are done, so just return
{
*first_unparsed = '\0';
*reason_to_stop = ValueObject::eEndOfString;
*final_result = ValueObject::ePlain;
- return root;
+ return child_valobj_sp;
+ }
+ else if (options.m_no_synthetic_children == false) // let's try with synthetic children
+ {
+ child_valobj_sp = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildMemberWithName(child_name, true);
+ }
+
+ // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
+ // so we hit the "else" branch, and return an error
+ if(child_valobj_sp.get()) // if it worked, just return
+ {
+ *first_unparsed = '\0';
+ *reason_to_stop = ValueObject::eEndOfString;
+ *final_result = ValueObject::ePlain;
+ return child_valobj_sp;
}
else
{
@@ -2051,9 +2066,24 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
else // other layers do expand
{
child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
- root = root->GetChildMemberWithName(child_name, true);
- if (root.get()) // store the new root and move on
+ ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
+ if (child_valobj_sp.get()) // store the new root and move on
+ {
+ root = child_valobj_sp;
+ *first_unparsed = next_separator;
+ *final_result = ValueObject::ePlain;
+ continue;
+ }
+ else if (options.m_no_synthetic_children == false) // let's try with synthetic children
+ {
+ child_valobj_sp = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildMemberWithName(child_name, true);
+ }
+
+ // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
+ // so we hit the "else" branch, and return an error
+ if(child_valobj_sp.get()) // if it worked, move on
{
+ root = child_valobj_sp;
*first_unparsed = next_separator;
*final_result = ValueObject::ePlain;
continue;
@@ -2236,7 +2266,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
return root;
}
}
- else if (root->HasSyntheticValue() && options.m_no_synthetic_children)
+ else if (root->HasSyntheticValue() && options.m_no_synthetic_children == false)
{
root = root->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildAtIndex(index, true);
if (!root.get())
@@ -2246,6 +2276,12 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
*final_result = ValueObject::eInvalid;
return ValueObjectSP();
}
+ else
+ {
+ *first_unparsed = end+1; // skip ]
+ *final_result = ValueObject::ePlain;
+ continue;
+ }
}
else
{
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 9ce7590a2dd..299fdd1139c 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -641,23 +641,28 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
if (!child_valobj_sp)
{
- // No child member with name "child_name"
- valobj_sp->GetExpressionPath (var_expr_path_strm, false);
- if (child_name)
- {
- error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"",
- child_name.GetCString(),
- valobj_sp->GetTypeName().AsCString("<invalid type>"),
- var_expr_path_strm.GetString().c_str());
- }
- else
+ if (no_synth_child == false)
+ child_valobj_sp = valobj_sp->GetSyntheticValue(lldb::eUseSyntheticFilter)->GetChildMemberWithName (child_name, true);
+
+ if (no_synth_child || !child_valobj_sp)
{
- error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
- var_expr_path_strm.GetString().c_str(),
- var_expr_cstr);
+ // No child member with name "child_name"
+ valobj_sp->GetExpressionPath (var_expr_path_strm, false);
+ if (child_name)
+ {
+ error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"",
+ child_name.GetCString(),
+ valobj_sp->GetTypeName().AsCString("<invalid type>"),
+ var_expr_path_strm.GetString().c_str());
+ }
+ else
+ {
+ error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
+ var_expr_path_strm.GetString().c_str(),
+ var_expr_cstr);
+ }
+ return ValueObjectSP();
}
-
- return ValueObjectSP();
}
// Remove the child name from the path
var_path.erase(0, child_name.GetLength());
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py b/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
index 70994d41a2a..745800a70b1 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
+++ b/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
@@ -194,6 +194,10 @@ class DataFormatterTestCase(TestBase):
'content = ',
'Process Name: a.out Process Id:'])
+ # check that access to synthetic children by name works
+ self.expect("frame variable str12->mutable",
+ substrs = ['(int) mutable = 0'])
+
# delete the synth and set a summary
self.runCmd("type synth delete NSString")
self.runCmd("type summary add -F CFString_SummaryProvider NSString")
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py b/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
index f06740e261f..ca1bc4e31e0 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
+++ b/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
@@ -70,10 +70,34 @@ class DataFormatterTestCase(TestBase):
'fake_a = 16777216',
'a = 0']);
- # check that we do not get the extra vars and that we cache results
+ # check that we do not get the extra vars
self.expect("frame variable f00_1", matching=False,
- substrs = ['looking for',
- 'b = 1']);
+ substrs = ['b = 1']);
+
+ # check access to members by name
+ self.expect('frame variable f00_1.fake_a',
+ substrs = ['16777216'])
+
+ # check access to members by index
+ self.expect('frame variable f00_1[1]',
+ substrs = ['16777216'])
+
+ # put synthetic children in summary in several combinations
+ self.runCmd("type summary add -f \"fake_a=${svar.fake_a}\" foo")
+ self.expect('frame variable f00_1',
+ substrs = ['fake_a=16777216'])
+ self.runCmd("type summary add -f \"fake_a=${var.fake_a}\" foo")
+ self.expect('frame variable f00_1',
+ substrs = ['fake_a=16777216'])
+ self.runCmd("type summary add -f \"fake_a=${var[1]}\" foo")
+ self.expect('frame variable f00_1',
+ substrs = ['fake_a=16777216'])
+ self.runCmd("type summary add -f \"fake_a=${svar[1]}\" foo")
+ self.expect('frame variable f00_1',
+ substrs = ['fake_a=16777216'])
+
+ # clear the summary
+ self.runCmd("type summary delete foo")
# check that the caching does not span beyond the stopoint
self.runCmd("n")
@@ -150,6 +174,20 @@ class DataFormatterTestCase(TestBase):
'[2] = 123',
'[3] = 1234',
'}'])
+
+ # check access to synthetic children
+ self.runCmd("type summary add -f \"item 0 is ${var[0]}\" std::int_vect int_vect")
+ self.expect('frame variable numbers',
+ substrs = ['item 0 is 1']);
+
+ self.runCmd("type summary add -f \"item 0 is ${svar[0]}\" std::int_vect int_vect")
+ #import time
+ #time.sleep(19)
+ self.expect('frame variable numbers',
+ substrs = ['item 0 is 1']);
+ # move on with synths
+ self.runCmd("type summary delete std::int_vect")
+ self.runCmd("type summary delete int_vect")
# add some more data
self.runCmd("n");self.runCmd("n");self.runCmd("n");
OpenPOWER on IntegriCloud