summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEnrico Granata <egranata@apple.com>2015-11-10 22:39:15 +0000
committerEnrico Granata <egranata@apple.com>2015-11-10 22:39:15 +0000
commit608d67c1520b9dd960f69a9137aab1ad78daae10 (patch)
treef0d99348e90f903d4824e614bd3bc7d9c8c67a2c
parent467ab052916ca820eb0332ec499446640b7e0d48 (diff)
downloadbcm5719-llvm-608d67c1520b9dd960f69a9137aab1ad78daae10.tar.gz
bcm5719-llvm-608d67c1520b9dd960f69a9137aab1ad78daae10.zip
Introduce a way for Languages to specify whether values of "reference types" are "nil" (not pointing to anything) or uninitialized (never made to point at anything)
This latter determination may or may not be possible on a per-language basis; and neither is mandatory to implement for any language Use this knowledge in the ValueObjectPrinter to generalize the notion of IsObjCNil() and the respective printout llvm-svn: 252663
-rw-r--r--lldb/include/lldb/Core/ValueObject.h7
-rw-r--r--lldb/include/lldb/DataFormatters/ValueObjectPrinter.h340
-rw-r--r--lldb/include/lldb/Target/Language.h11
-rw-r--r--lldb/source/Core/ValueObject.cpp24
-rw-r--r--lldb/source/DataFormatters/ValueObjectPrinter.cpp29
-rw-r--r--lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp12
-rw-r--r--lldb/source/Plugins/Language/ObjC/ObjCLanguage.h3
-rw-r--r--lldb/source/Target/Language.cpp12
8 files changed, 253 insertions, 185 deletions
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h
index 733207c197b..c066cc7d366 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -424,8 +424,11 @@ public:
virtual bool
IsPossibleDynamicType ();
- virtual bool
- IsObjCNil ();
+ bool
+ IsNilReference ();
+
+ bool
+ IsUninitializedReference ();
virtual bool
IsBaseClass ()
diff --git a/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h b/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
index 54ef126afbe..23d7ee2edf5 100644
--- a/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
+++ b/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
@@ -27,175 +27,179 @@
//#include <set>
namespace lldb_private {
+
+class ValueObjectPrinter
+{
+public:
+
+ ValueObjectPrinter (ValueObject* valobj,
+ Stream* s);
+
+ ValueObjectPrinter (ValueObject* valobj,
+ Stream* s,
+ const DumpValueObjectOptions& options);
+
+ ~ValueObjectPrinter () {}
+
+ bool
+ PrintValueObject ();
+
+protected:
+ typedef std::set<uint64_t> InstancePointersSet;
+ typedef std::shared_ptr<InstancePointersSet> InstancePointersSetSP;
+
+ InstancePointersSetSP m_printed_instance_pointers;
+
+ // only this class (and subclasses, if any) should ever be concerned with
+ // the depth mechanism
+ ValueObjectPrinter (ValueObject* valobj,
+ Stream* s,
+ const DumpValueObjectOptions& options,
+ const DumpValueObjectOptions::PointerDepth& ptr_depth,
+ uint32_t curr_depth,
+ InstancePointersSetSP printed_instance_pointers);
+
+ // we should actually be using delegating constructors here
+ // but some versions of GCC still have trouble with those
+ void
+ Init (ValueObject* valobj,
+ Stream* s,
+ const DumpValueObjectOptions& options,
+ const DumpValueObjectOptions::PointerDepth& ptr_depth,
+ uint32_t curr_depth,
+ InstancePointersSetSP printed_instance_pointers);
+
+ bool
+ GetMostSpecializedValue ();
+
+ const char*
+ GetDescriptionForDisplay ();
+
+ const char*
+ GetRootNameForDisplay (const char* if_fail = nullptr);
+
+ bool
+ ShouldPrintValueObject ();
+
+ bool
+ ShouldPrintValidation ();
+
+ bool
+ IsNil ();
+
+ bool
+ IsUninitialized ();
+
+ bool
+ IsPtr ();
+
+ bool
+ IsRef ();
+
+ bool
+ IsInstancePointer ();
+
+ bool
+ IsAggregate ();
+
+ bool
+ PrintValidationMarkerIfNeeded ();
+
+ bool
+ PrintValidationErrorIfNeeded ();
+
+ bool
+ PrintLocationIfNeeded ();
+
+ void
+ PrintDecl ();
+
+ bool
+ CheckScopeIfNeeded ();
+
+ bool
+ ShouldPrintEmptyBrackets (bool value_printed,
+ bool summary_printed);
+
+ TypeSummaryImpl*
+ GetSummaryFormatter (bool null_if_omitted = true);
+
+ void
+ GetValueSummaryError (std::string& value,
+ std::string& summary,
+ std::string& error);
+
+ bool
+ PrintValueAndSummaryIfNeeded (bool& value_printed,
+ bool& summary_printed);
+
+ bool
+ PrintObjectDescriptionIfNeeded (bool value_printed,
+ bool summary_printed);
+
+ bool
+ ShouldPrintChildren (bool is_failed_description,
+ DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
+
+ bool
+ ShouldExpandEmptyAggregates ();
+
+ ValueObject*
+ GetValueObjectForChildrenGeneration ();
+
+ void
+ PrintChildrenPreamble ();
+
+ void
+ PrintChildrenPostamble (bool print_dotdotdot);
+
+ void
+ PrintChild (lldb::ValueObjectSP child_sp,
+ const DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
+
+ uint32_t
+ GetMaxNumChildrenToPrint (bool& print_dotdotdot);
+
+ void
+ PrintChildren (bool value_printed,
+ bool summary_printed,
+ const DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
+
+ void
+ PrintChildrenIfNeeded (bool value_printed,
+ bool summary_printed);
+
+ bool
+ PrintChildrenOneLiner (bool hide_names);
+
+private:
+
+ ValueObject *m_orig_valobj;
+ ValueObject *m_valobj;
+ Stream *m_stream;
+ DumpValueObjectOptions m_options;
+ Flags m_type_flags;
+ CompilerType m_compiler_type;
+ DumpValueObjectOptions::PointerDepth m_ptr_depth;
+ uint32_t m_curr_depth;
+ LazyBool m_should_print;
+ LazyBool m_is_nil;
+ LazyBool m_is_uninit;
+ LazyBool m_is_ptr;
+ LazyBool m_is_ref;
+ LazyBool m_is_aggregate;
+ LazyBool m_is_instance_ptr;
+ std::pair<TypeSummaryImpl*,bool> m_summary_formatter;
+ std::string m_value;
+ std::string m_summary;
+ std::string m_error;
+ bool m_val_summary_ok;
+ std::pair<TypeValidatorResult,std::string> m_validation;
+
+ friend struct StringSummaryFormat;
- class ValueObjectPrinter
- {
- public:
-
- ValueObjectPrinter (ValueObject* valobj,
- Stream* s);
-
- ValueObjectPrinter (ValueObject* valobj,
- Stream* s,
- const DumpValueObjectOptions& options);
-
- ~ValueObjectPrinter () {}
-
- bool
- PrintValueObject ();
-
- protected:
- typedef std::set<uint64_t> InstancePointersSet;
- typedef std::shared_ptr<InstancePointersSet> InstancePointersSetSP;
-
- InstancePointersSetSP m_printed_instance_pointers;
-
- // only this class (and subclasses, if any) should ever be concerned with
- // the depth mechanism
- ValueObjectPrinter (ValueObject* valobj,
- Stream* s,
- const DumpValueObjectOptions& options,
- const DumpValueObjectOptions::PointerDepth& ptr_depth,
- uint32_t curr_depth,
- InstancePointersSetSP printed_instance_pointers);
-
- // we should actually be using delegating constructors here
- // but some versions of GCC still have trouble with those
- void
- Init (ValueObject* valobj,
- Stream* s,
- const DumpValueObjectOptions& options,
- const DumpValueObjectOptions::PointerDepth& ptr_depth,
- uint32_t curr_depth,
- InstancePointersSetSP printed_instance_pointers);
-
- bool
- GetMostSpecializedValue ();
-
- const char*
- GetDescriptionForDisplay ();
-
- const char*
- GetRootNameForDisplay (const char* if_fail = nullptr);
-
- bool
- ShouldPrintValueObject ();
-
- bool
- ShouldPrintValidation ();
-
- bool
- IsNil ();
-
- bool
- IsPtr ();
-
- bool
- IsRef ();
-
- bool
- IsInstancePointer ();
-
- bool
- IsAggregate ();
-
- bool
- PrintValidationMarkerIfNeeded ();
-
- bool
- PrintValidationErrorIfNeeded ();
-
- bool
- PrintLocationIfNeeded ();
-
- void
- PrintDecl ();
-
- bool
- CheckScopeIfNeeded ();
-
- bool
- ShouldPrintEmptyBrackets (bool value_printed,
- bool summary_printed);
-
- TypeSummaryImpl*
- GetSummaryFormatter (bool null_if_omitted = true);
-
- void
- GetValueSummaryError (std::string& value,
- std::string& summary,
- std::string& error);
-
- bool
- PrintValueAndSummaryIfNeeded (bool& value_printed,
- bool& summary_printed);
-
- bool
- PrintObjectDescriptionIfNeeded (bool value_printed,
- bool summary_printed);
-
- bool
- ShouldPrintChildren (bool is_failed_description,
- DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
-
- bool
- ShouldExpandEmptyAggregates ();
-
- ValueObject*
- GetValueObjectForChildrenGeneration ();
-
- void
- PrintChildrenPreamble ();
-
- void
- PrintChildrenPostamble (bool print_dotdotdot);
-
- void
- PrintChild (lldb::ValueObjectSP child_sp,
- const DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
-
- uint32_t
- GetMaxNumChildrenToPrint (bool& print_dotdotdot);
-
- void
- PrintChildren (bool value_printed,
- bool summary_printed,
- const DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
-
- void
- PrintChildrenIfNeeded (bool value_printed,
- bool summary_printed);
-
- bool
- PrintChildrenOneLiner (bool hide_names);
-
- private:
-
- ValueObject *m_orig_valobj;
- ValueObject *m_valobj;
- Stream *m_stream;
- DumpValueObjectOptions m_options;
- Flags m_type_flags;
- CompilerType m_compiler_type;
- DumpValueObjectOptions::PointerDepth m_ptr_depth;
- uint32_t m_curr_depth;
- LazyBool m_should_print;
- LazyBool m_is_nil;
- LazyBool m_is_ptr;
- LazyBool m_is_ref;
- LazyBool m_is_aggregate;
- LazyBool m_is_instance_ptr;
- std::pair<TypeSummaryImpl*,bool> m_summary_formatter;
- std::string m_value;
- std::string m_summary;
- std::string m_error;
- bool m_val_summary_ok;
- std::pair<TypeValidatorResult,std::string> m_validation;
-
- friend struct StringSummaryFormat;
-
- DISALLOW_COPY_AND_ASSIGN(ValueObjectPrinter);
- };
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectPrinter);
+};
} // namespace lldb_private
diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index 8eb5ed2734d..28c6d485662 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -123,6 +123,17 @@ public:
IsLogicalTrue (ValueObject& valobj,
Error& error);
+ // for a ValueObject of some "reference type", if the value points to the
+ // nil/null object, this method returns true
+ virtual bool
+ IsNilReference (ValueObject& valobj);
+
+ // for a ValueObject of some "reference type", if the language provides a technique
+ // to decide whether the reference has ever been assigned to some object, this method
+ // will return true if such detection is possible, and if the reference has never been assigned
+ virtual bool
+ IsUninitializedReference (ValueObject& valobj);
+
// These are accessors for general information about the Languages lldb knows about:
static lldb::LanguageType
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 75135554f65..fa3f1ff76db 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -2145,15 +2145,23 @@ ValueObject::IsRuntimeSupportValue ()
}
bool
-ValueObject::IsObjCNil ()
+ValueObject::IsNilReference ()
{
- const uint32_t mask = eTypeIsObjC | eTypeIsPointer;
- bool isObjCpointer = (((GetCompilerType().GetTypeInfo(NULL)) & mask) == mask);
- if (!isObjCpointer)
- return false;
- bool canReadValue = true;
- bool isZero = GetValueAsUnsigned(0,&canReadValue) == 0;
- return canReadValue && isZero;
+ if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage()))
+ {
+ return language->IsNilReference(*this);
+ }
+ return false;
+}
+
+bool
+ValueObject::IsUninitializedReference ()
+{
+ if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage()))
+ {
+ return language->IsUninitializedReference(*this);
+ }
+ return false;
}
// This allows you to create an array member using and index
diff --git a/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
index 4bc33fdaa91..4289496c8ff 100644
--- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -73,6 +73,7 @@ ValueObjectPrinter::Init (ValueObject* valobj,
assert (m_stream && "cannot print to a NULL Stream");
m_should_print = eLazyBoolCalculate;
m_is_nil = eLazyBoolCalculate;
+ m_is_uninit = eLazyBoolCalculate;
m_is_ptr = eLazyBoolCalculate;
m_is_ref = eLazyBoolCalculate;
m_is_aggregate = eLazyBoolCalculate;
@@ -100,12 +101,12 @@ ValueObjectPrinter::PrintValueObject ()
PrintDecl();
}
-
+
bool value_printed = false;
bool summary_printed = false;
m_val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed);
-
+
if (m_val_summary_ok)
PrintChildrenIfNeeded (value_printed, summary_printed);
else
@@ -194,8 +195,8 @@ const char*
ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail)
{
const char *root_valobj_name = m_options.m_root_valobj_name.empty() ?
- m_valobj->GetName().AsCString() :
- m_options.m_root_valobj_name.c_str();
+ m_valobj->GetName().AsCString() :
+ m_options.m_root_valobj_name.c_str();
return root_valobj_name ? root_valobj_name : if_fail;
}
@@ -211,11 +212,19 @@ bool
ValueObjectPrinter::IsNil ()
{
if (m_is_nil == eLazyBoolCalculate)
- m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo;
+ m_is_nil = m_valobj->IsNilReference() ? eLazyBoolYes : eLazyBoolNo;
return m_is_nil == eLazyBoolYes;
}
bool
+ValueObjectPrinter::IsUninitialized ()
+{
+ if (m_is_uninit == eLazyBoolCalculate)
+ m_is_uninit = m_valobj->IsUninitializedReference() ? eLazyBoolYes : eLazyBoolNo;
+ return m_is_uninit == eLazyBoolYes;
+}
+
+bool
ValueObjectPrinter::IsPtr ()
{
if (m_is_ptr == eLazyBoolCalculate)
@@ -426,6 +435,8 @@ ValueObjectPrinter::GetValueSummaryError (std::string& value,
{
if (IsNil())
summary.assign("nil");
+ else if (IsUninitialized())
+ summary.assign("<uninitialized>");
else if (m_options.m_omit_summary_depth == 0)
{
TypeSummaryImpl* entry = GetSummaryFormatter();
@@ -476,7 +487,7 @@ ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed,
// the value if this thing is nil
// (but show the value if the user passes a format explicitly)
TypeSummaryImpl* entry = GetSummaryFormatter();
- if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || m_options.m_format != eFormatDefault) || m_summary.empty()) && !m_options.m_hide_value)
+ if (!IsNil() && !IsUninitialized() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || m_options.m_format != eFormatDefault) || m_summary.empty()) && !m_options.m_hide_value)
{
if (m_options.m_hide_pointer_value && IsPointerValue(m_valobj->GetCompilerType())) {}
else
@@ -503,7 +514,7 @@ ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
if (ShouldPrintValueObject())
{
// let's avoid the overly verbose no description error for a nil thing
- if (m_options.m_use_objc && !IsNil())
+ if (m_options.m_use_objc && !IsNil() && !IsUninitialized())
{
if (!m_options.m_hide_value || !m_options.m_hide_name)
m_stream->Printf(" ");
@@ -571,6 +582,10 @@ ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description,
{
const bool is_ref = IsRef ();
const bool is_ptr = IsPtr ();
+ const bool is_uninit = IsUninitialized();
+
+ if (is_uninit)
+ return false;
TypeSummaryImpl* entry = GetSummaryFormatter();
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index e8d008c00a6..1cec6269029 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -863,3 +863,15 @@ ObjCLanguage::GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hi
return false;
}
+
+bool
+ObjCLanguage::IsNilReference (ValueObject& valobj)
+{
+ const uint32_t mask = eTypeIsObjC | eTypeIsPointer;
+ bool isObjCpointer = (((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask);
+ if (!isObjCpointer)
+ return false;
+ bool canReadValue = true;
+ bool isZero = valobj.GetValueAsUnsigned(0,&canReadValue) == 0;
+ return canReadValue && isZero;
+}
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index 0f96ff8601d..e30aa18c044 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -153,6 +153,9 @@ public:
GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint,
std::string& prefix, std::string& suffix) override;
+ bool
+ IsNilReference (ValueObject& valobj) override;
+
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp
index 3a53a6bec0e..2d75bdec0a8 100644
--- a/lldb/source/Target/Language.cpp
+++ b/lldb/source/Target/Language.cpp
@@ -358,6 +358,18 @@ Language::IsLogicalTrue (ValueObject& valobj,
return eLazyBoolCalculate;
}
+bool
+Language::IsNilReference (ValueObject& valobj)
+{
+ return false;
+}
+
+bool
+Language::IsUninitializedReference (ValueObject& valobj)
+{
+ return false;
+}
+
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
OpenPOWER on IntegriCloud