[Lldb-commits] [lldb] r138080 - in /lldb/trunk: include/lldb/Core/ include/lldb/Target/ source/Core/ source/Target/ test/functionalities/data-formatter/data-formatter-cpp/ test/functionalities/data-formatter/rdar-9973865/ test/functionalities/data-formatter/rdar-9973992/
Enrico Granata
granata.enrico at gmail.com
Fri Aug 19 14:13:46 PDT 2011
Author: enrico
Date: Fri Aug 19 16:13:46 2011
New Revision: 138080
URL: http://llvm.org/viewvc/llvm-project?rev=138080&view=rev
Log:
- Now using ${var} as the summary for an aggregate type will produce "name-of-type @ object-location" instead of giving an error
e.g. you may get "foo_class @ 0x123456" when typing "type summary add -f ${var} foo_class"
- Added a new special formatting token %T for summaries. This shows the type of the object.
Using it, the new "type @ location" summary could be manually generated by writing ${var%T} @ ${var%L}
- Bits and pieces required to support "frame variable array[n-m]"
The feature is not enabled yet because some additional design and support code is required, but the basics
are getting there
- Fixed a potential issue where a ValueObjectSyntheticFilter was not holding on to its SyntheticChildrenSP
Because of the way VOSF are being built now, this has never been an actual issue, but it is still sensible for
a VOSF to hold on to the SyntheticChildrenSP as well as to its FrontEnd
Added:
lldb/trunk/test/functionalities/data-formatter/rdar-9973992/
lldb/trunk/test/functionalities/data-formatter/rdar-9973992/Makefile
lldb/trunk/test/functionalities/data-formatter/rdar-9973992/Test-rdar-9973992.py
lldb/trunk/test/functionalities/data-formatter/rdar-9973992/main.cpp
Modified:
lldb/trunk/include/lldb/Core/FormatClasses.h
lldb/trunk/include/lldb/Core/ValueObject.h
lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
lldb/trunk/include/lldb/Target/StackFrame.h
lldb/trunk/source/Core/Debugger.cpp
lldb/trunk/source/Core/FormatClasses.cpp
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
lldb/trunk/source/Target/StackFrame.cpp
lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
lldb/trunk/test/functionalities/data-formatter/rdar-9973865/Test-rdar-9973865.py
Modified: lldb/trunk/include/lldb/Core/FormatClasses.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatClasses.h?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatClasses.h (original)
+++ lldb/trunk/include/lldb/Core/FormatClasses.h Fri Aug 19 16:13:46 2011
@@ -384,6 +384,241 @@
};
+struct SyntheticArrayRange
+{
+private:
+ int m_low;
+ int m_high;
+ SyntheticArrayRange* m_next;
+
+public:
+
+ SyntheticArrayRange () :
+ m_low(-1),
+ m_high(-2),
+ m_next(NULL)
+ {}
+
+ SyntheticArrayRange (int L) :
+ m_low(L),
+ m_high(L),
+ m_next(NULL)
+ {}
+
+ SyntheticArrayRange (int L, int H) :
+ m_low(L),
+ m_high(H),
+ m_next(NULL)
+ {}
+
+ SyntheticArrayRange (int L, int H, SyntheticArrayRange* N) :
+ m_low(L),
+ m_high(H),
+ m_next(N)
+ {}
+
+ inline int
+ GetLow ()
+ {
+ return m_low;
+ }
+
+ inline int
+ GetHigh ()
+ {
+ return m_high;
+ }
+
+ inline void
+ SetLow (int L)
+ {
+ m_low = L;
+ }
+
+ inline void
+ SetHigh (int H)
+ {
+ m_high = H;
+ }
+
+ inline int
+ GetSelfCount()
+ {
+ return GetHigh() - GetLow() + 1;
+ }
+
+ int
+ GetCount()
+ {
+ int count = GetSelfCount();
+ if (m_next)
+ count += m_next->GetCount();
+ return count;
+ }
+
+ inline SyntheticArrayRange*
+ GetNext()
+ {
+ return m_next;
+ }
+
+ void
+ SetNext(SyntheticArrayRange* N)
+ {
+ if (m_next)
+ delete m_next;
+ m_next = N;
+ }
+
+ void
+ SetNext(int L, int H)
+ {
+ if (m_next)
+ delete m_next;
+ m_next = new SyntheticArrayRange(L, H);
+ }
+
+ void
+ SetNext(int L)
+ {
+ if (m_next)
+ delete m_next;
+ m_next = new SyntheticArrayRange(L);
+ }
+
+ ~SyntheticArrayRange()
+ {
+ delete m_next;
+ m_next = NULL;
+ }
+
+};
+
+class SyntheticArrayView : public SyntheticChildren
+{
+ SyntheticArrayRange m_head;
+ SyntheticArrayRange *m_tail;
+public:
+ SyntheticArrayView(bool casc = false,
+ bool skipptr = false,
+ bool skipref = false) :
+ SyntheticChildren(casc, skipptr, skipref),
+ m_head(),
+ m_tail(&m_head)
+ {
+ }
+
+ void
+ AddRange(int L, int H)
+ {
+ m_tail->SetLow(L);
+ m_tail->SetHigh(H);
+ m_tail->SetNext(new SyntheticArrayRange());
+ m_tail = m_tail->GetNext();
+ }
+
+ int
+ GetCount()
+ {
+ return m_head.GetCount();
+ }
+
+ const int
+ GetRealIndexForIndex(int i)
+ {
+ if (i >= GetCount())
+ return -1;
+
+ SyntheticArrayRange* ptr = &m_head;
+
+ int residual = i;
+
+ while(ptr && ptr != m_tail)
+ {
+ if (residual >= ptr->GetSelfCount())
+ {
+ residual -= ptr->GetSelfCount();
+ ptr = ptr->GetNext();
+ }
+
+ return ptr->GetLow() + residual;
+ }
+
+ return -1;
+
+ }
+
+ bool
+ IsScripted()
+ {
+ return false;
+ }
+
+ std::string
+ GetDescription();
+
+ class FrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ SyntheticArrayView* filter;
+ public:
+
+ FrontEnd(SyntheticArrayView* flt,
+ lldb::ValueObjectSP be) :
+ SyntheticChildrenFrontEnd(be),
+ filter(flt)
+ {}
+
+ virtual
+ ~FrontEnd()
+ {
+ }
+
+ virtual uint32_t
+ CalculateNumChildren()
+ {
+ return filter->GetCount();
+ }
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (uint32_t idx, bool can_create)
+ {
+ if (idx >= filter->GetCount())
+ return lldb::ValueObjectSP();
+ return m_backend->GetSyntheticArrayMember(filter->GetRealIndexForIndex(idx), can_create);
+ }
+
+ virtual void
+ Update() {}
+
+ virtual uint32_t
+ GetIndexOfChildWithName (const ConstString &name_cs)
+ {
+ const char* name_cstr = name_cs.GetCString();
+ if (*name_cstr != '[')
+ return UINT32_MAX;
+ std::string name(name_cstr+1);
+ if (name[name.size()-1] != ']')
+ return UINT32_MAX;
+ name = name.erase(name.size()-1,1);
+ int index = Args::StringToSInt32 (name.c_str(), -1);
+ if (index < 0)
+ return UINT32_MAX;
+ return index;
+ }
+
+ typedef lldb::SharedPtr<SyntheticChildrenFrontEnd>::Type SharedPointer;
+
+ };
+
+ virtual SyntheticChildrenFrontEnd::SharedPointer
+ GetFrontEnd(lldb::ValueObjectSP backend)
+ {
+ return SyntheticChildrenFrontEnd::SharedPointer(new FrontEnd(this, backend));
+ }
+
+};
+
struct SummaryFormat
{
Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Fri Aug 19 16:13:46 2011
@@ -79,7 +79,8 @@
eDisplaySummary,
eDisplayLanguageSpecific,
eDisplayLocation,
- eDisplayChildrenCount
+ eDisplayChildrenCount,
+ eDisplayType
};
enum ExpressionPathScanEndReason
@@ -658,6 +659,10 @@
lldb::Format custom_format = lldb::eFormatInvalid);
bool
+ HasSpecialCasesForPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
+ lldb::Format custom_format);
+
+ bool
DumpPrintableRepresentation(Stream& s,
ValueObjectRepresentationStyle val_obj_display = eDisplaySummary,
lldb::Format custom_format = lldb::eFormatInvalid,
@@ -693,6 +698,9 @@
public:
lldb::ValueObjectSP
GetSyntheticChild (const ConstString &key) const;
+
+ lldb::ValueObjectSP
+ GetSyntheticArrayMember (int32_t index, bool can_create);
lldb::ValueObjectSP
GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create);
@@ -704,6 +712,9 @@
GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create);
lldb::ValueObjectSP
+ GetSyntheticArrayRangeChild (uint32_t from, uint32_t to, bool can_create);
+
+ lldb::ValueObjectSP
GetSyntheticExpressionPathChild(const char* expression, bool can_create);
virtual lldb::ValueObjectSP
Modified: lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h Fri Aug 19 16:13:46 2011
@@ -24,9 +24,9 @@
//----------------------------------------------------------------------
// A ValueObject that obtains its children from some source other than
// real information
-// This is currently used to implement children filtering, where only
-// a subset of the real children are shown, but it can be used for any
-// source of made-up children information
+// This is currently used to implement Python-based children and filters
+// but you can bind it to any source of synthetic information and have
+// it behave accordingly
//----------------------------------------------------------------------
class ValueObjectSynthetic : public ValueObject
{
@@ -121,6 +121,7 @@
lldb::TypeSP m_type_sp;
lldb::ValueObjectSP m_owning_valobj_sp;
lldb::SyntheticValueType m_use_synthetic;
+ lldb::SyntheticChildrenSP m_synth_sp; // hold on to your synthetic children provider
lldb::SyntheticChildrenFrontEndSP m_synth_filter;
typedef std::map<uint32_t, lldb::ValueObjectSP> ByIndexMap;
Modified: lldb/trunk/include/lldb/Target/StackFrame.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StackFrame.h (original)
+++ lldb/trunk/include/lldb/Target/StackFrame.h Fri Aug 19 16:13:46 2011
@@ -32,9 +32,10 @@
public:
enum ExpressionPathOption
{
- eExpressionPathOptionCheckPtrVsMember = (1u << 0),
- eExpressionPathOptionsNoFragileObjcIvar = (1u << 1),
- eExpressionPathOptionsNoSyntheticChildren = (1u << 2)
+ eExpressionPathOptionCheckPtrVsMember = (1u << 0),
+ eExpressionPathOptionsNoFragileObjcIvar = (1u << 1),
+ eExpressionPathOptionsNoSyntheticChildren = (1u << 2),
+ eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3),
};
//------------------------------------------------------------------
// Constructors and Destructors
Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Fri Aug 19 16:13:46 2011
@@ -744,6 +744,8 @@
*val_obj_display = ValueObject::eDisplaySummary;
else if (*format_name == '#')
*val_obj_display = ValueObject::eDisplayChildrenCount;
+ else if (*format_name == 'T')
+ *val_obj_display = ValueObject::eDisplayType;
else if (log)
log->Printf("%s is an error, leaving the previous value alone", format_name);
}
@@ -1165,25 +1167,52 @@
StreamString str_temp;
if (log)
log->Printf("I am into array || pointer && !range");
- // try to use the special cases
- var_success = target->DumpPrintableRepresentation(str_temp,
- val_obj_display,
- custom_format);
- if (log)
- log->Printf("special cases did%s match", var_success ? "" : "n't");
- if (!var_success)
+
+ if (target->HasSpecialCasesForPrintableRepresentation(val_obj_display,
+ custom_format))
{
- s << "<invalid usage of pointer value as object>";
+ // try to use the special cases
+ var_success = target->DumpPrintableRepresentation(str_temp,
+ val_obj_display,
+ custom_format);
+ if (log)
+ log->Printf("special cases did%s match", var_success ? "" : "n't");
+
+ // should not happen
+ if (!var_success)
+ s << "<invalid usage of pointer value as object>";
+ else
+ s << str_temp.GetData();
var_success = true;
+ break;
}
else
- s << str_temp.GetData();
+ {
+ // if ${var}
+ if (was_plain_var)
+ {
+ s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
+ }
+ else
+ {
+ s << "<invalid usage of pointer value as object>";
+ }
+ var_success = true;
+ break;
+ }
+ }
+
+ // if directly trying to print ${var}, and this is an aggregate, display a nice
+ // type @ location message
+ if (is_aggregate && was_plain_var)
+ {
+ s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
+ var_success = true;
break;
}
- // if directly trying to print ${var} using its value, and this is an aggregate, display a nice
- // error message about it (and avoid recursion in DumpPrintableRepresentation)
- if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eDisplayValue) || was_plain_var))
+ // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
+ if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eDisplayValue)))
{
s << "<invalid use of aggregate type>";
var_success = true;
Modified: lldb/trunk/source/Core/FormatClasses.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatClasses.cpp?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatClasses.cpp (original)
+++ lldb/trunk/source/Core/FormatClasses.cpp Fri Aug 19 16:13:46 2011
@@ -181,6 +181,31 @@
return sstr.GetString();
}
+std::string
+SyntheticArrayView::GetDescription()
+{
+ StreamString sstr;
+ sstr.Printf("%s%s%s {\n",
+ m_cascades ? "" : " (not cascading)",
+ m_skip_pointers ? " (skip pointers)" : "",
+ m_skip_references ? " (skip references)" : "");
+ SyntheticArrayRange* ptr = &m_head;
+ while (ptr && ptr != m_tail)
+ {
+ if (ptr->GetLow() == ptr->GetHigh())
+ sstr.Printf(" [%d]\n",
+ ptr->GetLow());
+ else
+ sstr.Printf(" [%d-%d]\n",
+ ptr->GetLow(),
+ ptr->GetHigh());
+ ptr = ptr->GetNext();
+ }
+
+ sstr.Printf("}");
+ return sstr.GetString();
+}
+
SyntheticScriptProvider::FrontEnd::FrontEnd(std::string pclass,
lldb::ValueObjectSP be) :
SyntheticChildrenFrontEnd(be),
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Fri Aug 19 16:13:46 2011
@@ -989,6 +989,9 @@
snprintf((char*)return_value, 512, "%d", count);
break;
}
+ case eDisplayType:
+ return_value = GetTypeName().AsCString();
+ break;
default:
break;
}
@@ -1007,7 +1010,11 @@
// this thing has no value, and it seems to have no summary
// some combination of unitialized data and other factors can also
// raise this condition, so let's print a nice generic error message
- return_value = "<no available summary>";
+ {
+ alloc_mem.resize(684);
+ return_value = &alloc_mem[0];
+ snprintf((char*)return_value, 684, "%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
+ }
}
else
return_value = GetValueAsCString();
@@ -1026,6 +1033,50 @@
}
+// if any more "special cases" are added to ValueObject::DumpPrintableRepresentation() please keep
+// this call up to date by returning true for your new special cases. We will eventually move
+// to checking this call result before trying to display special cases
+bool
+ValueObject::HasSpecialCasesForPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
+ lldb::Format custom_format)
+{
+ clang_type_t elem_or_pointee_type;
+ Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
+
+ if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
+ && val_obj_display == ValueObject::eDisplayValue)
+ {
+ if (IsCStringContainer(true) &&
+ (custom_format == lldb::eFormatCString ||
+ custom_format == lldb::eFormatCharArray ||
+ custom_format == lldb::eFormatChar ||
+ custom_format == lldb::eFormatVectorOfChar))
+ return true;
+
+ if (flags.Test(ClangASTContext::eTypeIsArray))
+ {
+ if ((custom_format == lldb::eFormatBytes) ||
+ (custom_format == lldb::eFormatBytesWithASCII))
+ return true;
+
+ if ((custom_format == lldb::eFormatVectorOfChar) ||
+ (custom_format == lldb::eFormatVectorOfFloat32) ||
+ (custom_format == lldb::eFormatVectorOfFloat64) ||
+ (custom_format == lldb::eFormatVectorOfSInt16) ||
+ (custom_format == lldb::eFormatVectorOfSInt32) ||
+ (custom_format == lldb::eFormatVectorOfSInt64) ||
+ (custom_format == lldb::eFormatVectorOfSInt8) ||
+ (custom_format == lldb::eFormatVectorOfUInt128) ||
+ (custom_format == lldb::eFormatVectorOfUInt16) ||
+ (custom_format == lldb::eFormatVectorOfUInt32) ||
+ (custom_format == lldb::eFormatVectorOfUInt64) ||
+ (custom_format == lldb::eFormatVectorOfUInt8))
+ return true;
+ }
+ }
+ return false;
+}
+
bool
ValueObject::DumpPrintableRepresentation(Stream& s,
ValueObjectRepresentationStyle val_obj_display,
@@ -1380,6 +1431,19 @@
return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType());
}
+lldb::ValueObjectSP
+ValueObject::GetSyntheticArrayMember (int32_t index, bool can_create)
+{
+ if (IsArrayType())
+ return GetSyntheticArrayMemberFromArray(index, can_create);
+
+ if (IsPointerType())
+ return GetSyntheticArrayMemberFromPointer(index, can_create);
+
+ return ValueObjectSP();
+
+}
+
ValueObjectSP
ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
{
@@ -1497,6 +1561,42 @@
}
lldb::ValueObjectSP
+ValueObject::GetSyntheticArrayRangeChild (uint32_t from, uint32_t to, bool can_create)
+{
+ ValueObjectSP synthetic_child_sp;
+ if (IsArrayType () || IsPointerType ())
+ {
+ char index_str[64];
+ snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
+ ConstString index_const_str(index_str);
+ // Check if we have already created a synthetic array member in this
+ // valid object. If we have we will re-use it.
+ synthetic_child_sp = GetSyntheticChild (index_const_str);
+ if (!synthetic_child_sp)
+ {
+ ValueObjectSynthetic *synthetic_child;
+
+ // We haven't made a synthetic array member for INDEX yet, so
+ // lets make one and cache it for any future reference.
+ SyntheticArrayView *view = new SyntheticArrayView();
+ view->AddRange(from,to);
+ SyntheticChildrenSP view_sp(view);
+ synthetic_child = new ValueObjectSynthetic(*this, view_sp);
+
+ // Cache the value if we got one back...
+ if (synthetic_child)
+ {
+ AddSyntheticChild(index_const_str, synthetic_child);
+ synthetic_child_sp = synthetic_child->GetSP();
+ synthetic_child_sp->SetName(ConstString(index_str));
+ synthetic_child_sp->m_is_bitfield_for_scalar = true;
+ }
+ }
+ }
+ return synthetic_child_sp;
+}
+
+lldb::ValueObjectSP
ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
{
Modified: lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp Fri Aug 19 16:13:46 2011
@@ -40,6 +40,7 @@
m_address (),
m_type_sp(),
m_use_synthetic (lldb::eUseSyntheticFilter),
+ m_synth_sp(filter),
m_synth_filter(filter->GetFrontEnd(parent.GetSP())),
m_children_byindex(),
m_name_toindex()
Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Fri Aug 19 16:13:46 2011
@@ -526,6 +526,7 @@
const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0;
const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
+ const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0;
error.Clear();
bool deref = false;
bool address_of = false;
@@ -861,6 +862,7 @@
// this is most probably a BitField, let's take a look
char *real_end = NULL;
long final_index = ::strtol (end+1, &real_end, 0);
+ bool expand_bitfield = true;
if (real_end && *real_end == ']')
{
// if the format given is [high-low], swap range
@@ -908,15 +910,31 @@
valobj_sp = temp;
deref = false;
}
+ /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType())
+ {
+ child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true);
+ expand_bitfield = false;
+ if (!child_valobj_sp)
+ {
+ valobj_sp->GetExpressionPath (var_expr_path_strm, false);
+ error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"",
+ child_index, final_index,
+ valobj_sp->GetTypeName().AsCString("<invalid type>"),
+ var_expr_path_strm.GetString().c_str());
+ }
+ }*/
- child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
- if (!child_valobj_sp)
+ if (expand_bitfield)
{
- valobj_sp->GetExpressionPath (var_expr_path_strm, false);
- error.SetErrorStringWithFormat ("bitfield range %i-%i is not valid for \"(%s) %s\"",
- child_index, final_index,
- valobj_sp->GetTypeName().AsCString("<invalid type>"),
- var_expr_path_strm.GetString().c_str());
+ child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
+ if (!child_valobj_sp)
+ {
+ valobj_sp->GetExpressionPath (var_expr_path_strm, false);
+ error.SetErrorStringWithFormat ("bitfield range %i-%i is not valid for \"(%s) %s\"",
+ child_index, final_index,
+ valobj_sp->GetTypeName().AsCString("<invalid type>"),
+ var_expr_path_strm.GetString().c_str());
+ }
}
}
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py Fri Aug 19 16:13:46 2011
@@ -195,7 +195,34 @@
'[2] = cool object @ 0x',
'[3] = cool object @ 0x',
'[4] = cool object @ 0x'])
+
+ # test getting similar output by exploiting ${var} = 'type @ location' for aggregates
+ self.runCmd("type summary add -f \"${var}\" i_am_cool")
+
+ # this test might fail if the compiler tries to store
+ # these values into registers.. hopefully this is not
+ # going to be the case
+ self.expect("frame variable cool_array",
+ substrs = ['[0] = i_am_cool @ 0x',
+ '[1] = i_am_cool @ 0x',
+ '[2] = i_am_cool @ 0x',
+ '[3] = i_am_cool @ 0x',
+ '[4] = i_am_cool @ 0x'])
+
+ # test getting same output by exploiting %T and %L together for aggregates
+ self.runCmd("type summary add -f \"${var%T} @ ${var%L}\" i_am_cool")
+
+ # this test might fail if the compiler tries to store
+ # these values into registers.. hopefully this is not
+ # going to be the case
+ self.expect("frame variable cool_array",
+ substrs = ['[0] = i_am_cool @ 0x',
+ '[1] = i_am_cool @ 0x',
+ '[2] = i_am_cool @ 0x',
+ '[3] = i_am_cool @ 0x',
+ '[4] = i_am_cool @ 0x'])
+
self.runCmd("type summary add -f \"goofy\" i_am_cool")
self.runCmd("type summary add -f \"${var.second_cool%S}\" i_am_cooler")
Modified: lldb/trunk/test/functionalities/data-formatter/rdar-9973865/Test-rdar-9973865.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-9973865/Test-rdar-9973865.py?rev=138080&r1=138079&r2=138080&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-9973865/Test-rdar-9973865.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-9973865/Test-rdar-9973865.py Fri Aug 19 16:13:46 2011
@@ -56,10 +56,10 @@
self.runCmd("type summary add -f \"SUMMARY SUCCESS ${var}\" Summarize")
self.expect('frame variable mine_ptr',
- substrs = ['SUMMARY SUCCESS <invalid usage of pointer value as object>'])
+ substrs = ['SUMMARY SUCCESS summarize_ptr_t @ '])
self.expect('frame variable *mine_ptr',
- substrs = ['SUMMARY SUCCESS <invalid use of aggregate type>'])
+ substrs = ['SUMMARY SUCCESS summarize_t @'])
self.runCmd("type summary add -f \"SUMMARY SUCCESS ${var.first}\" Summarize")
Added: lldb/trunk/test/functionalities/data-formatter/rdar-9973992/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-9973992/Makefile?rev=138080&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-9973992/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-9973992/Makefile Fri Aug 19 16:13:46 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
Added: lldb/trunk/test/functionalities/data-formatter/rdar-9973992/Test-rdar-9973992.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-9973992/Test-rdar-9973992.py?rev=138080&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-9973992/Test-rdar-9973992.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-9973992/Test-rdar-9973992.py Fri Aug 19 16:13:46 2011
@@ -0,0 +1,90 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class DataFormatterTestCase(TestBase):
+
+ # test for rdar://problem/9973992 (What should we do for "${var}" in summaries of aggregate types?)
+ mydir = os.path.join("functionalities", "data-formatter", "rdar-9973992")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", 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 summary clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type summary add -f \"SUMMARY SUCCESS ${var}\" Summarize")
+
+ self.expect('frame variable mine_ptr',
+ substrs = ['SUMMARY SUCCESS summarize_ptr_t @ '])
+
+ self.expect('frame variable *mine_ptr',
+ substrs = ['SUMMARY SUCCESS summarize_t @'])
+
+ self.runCmd("type summary add -f \"SUMMARY SUCCESS ${var.first}\" Summarize")
+
+ self.expect('frame variable mine_ptr',
+ substrs = ['SUMMARY SUCCESS 10'])
+
+ self.expect('frame variable *mine_ptr',
+ substrs = ['SUMMARY SUCCESS 10'])
+
+ self.runCmd("type summary add -f \"${var}\" Summarize")
+ self.runCmd("type summary add -f \"${var}\" -e TwoSummarizes")
+
+ self.expect('frame variable',
+ substrs = ['(TwoSummarizes) twos = TwoSummarizes @ ',
+ 'first = summarize_t @ ',
+ 'second = summarize_t @ '])
+
+ self.runCmd("type summary add -f \"SUMMARY SUCCESS ${var.first}\" Summarize")
+ self.expect('frame variable',
+ substrs = ['(TwoSummarizes) twos = TwoSummarizes @ ',
+ 'first = SUMMARY SUCCESS 1',
+ 'second = SUMMARY SUCCESS 3'])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/functionalities/data-formatter/rdar-9973992/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-9973992/main.cpp?rev=138080&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-9973992/main.cpp (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-9973992/main.cpp Fri Aug 19 16:13:46 2011
@@ -0,0 +1,41 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+struct Summarize
+{
+ int first;
+ int second;
+};
+
+typedef struct Summarize summarize_t;
+typedef summarize_t *summarize_ptr_t;
+
+summarize_t global_mine = {30, 40};
+
+struct TwoSummarizes
+{
+ summarize_t first;
+ summarize_t second;
+};
+
+int
+main()
+{
+ summarize_t mine = {10, 20};
+ summarize_ptr_t mine_ptr = &mine;
+
+ TwoSummarizes twos = { {1,2}, {3,4} };
+
+ printf ("Summarize: first: %d second: %d and address: 0x%p\n", mine.first, mine.second, mine_ptr); // Set break point at this line.
+ printf ("Global summarize: first: %d second: %d.\n", global_mine.first, global_mine.second);
+ return 0;
+}
+
+
More information about the lldb-commits
mailing list