diff options
author | Enrico Granata <egranata@apple.com> | 2015-11-10 22:39:15 +0000 |
---|---|---|
committer | Enrico Granata <egranata@apple.com> | 2015-11-10 22:39:15 +0000 |
commit | 608d67c1520b9dd960f69a9137aab1ad78daae10 (patch) | |
tree | f0d99348e90f903d4824e614bd3bc7d9c8c67a2c | |
parent | 467ab052916ca820eb0332ec499446640b7e0d48 (diff) | |
download | bcm5719-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.h | 7 | ||||
-rw-r--r-- | lldb/include/lldb/DataFormatters/ValueObjectPrinter.h | 340 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Language.h | 11 | ||||
-rw-r--r-- | lldb/source/Core/ValueObject.cpp | 24 | ||||
-rw-r--r-- | lldb/source/DataFormatters/ValueObjectPrinter.cpp | 29 | ||||
-rw-r--r-- | lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp | 12 | ||||
-rw-r--r-- | lldb/source/Plugins/Language/ObjC/ObjCLanguage.h | 3 | ||||
-rw-r--r-- | lldb/source/Target/Language.cpp | 12 |
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 //---------------------------------------------------------------------- |