summaryrefslogtreecommitdiffstats
path: root/lldb
diff options
context:
space:
mode:
authorEnrico Granata <egranata@apple.com>2012-03-22 19:55:55 +0000
committerEnrico Granata <egranata@apple.com>2012-03-22 19:55:55 +0000
commit4a3274af9622f1f95290747b345b4f12a02ab76e (patch)
tree9d05dd075450e0fe5fa4dd047ac374bc9d68cad3 /lldb
parentbdf975ea3fd6ea2a3e33553d63a819c7997757e7 (diff)
downloadbcm5719-llvm-4a3274af9622f1f95290747b345b4f12a02ab76e.tar.gz
bcm5719-llvm-4a3274af9622f1f95290747b345b4f12a02ab76e.zip
Removing cascading through inheritance chains for data formatters
This is the feature that allowed the user to have things like: class Base { ... }; class Derived : public Base { ... }; and have formatters defined for Base work automatically for Derived. This feature turned out to be too expensive since it requires completing types. This patch takes care of removing cascading (other than typedefs chain cascading), updating the test suite accordingly, and adding required Cocoa class names to keep the AppKit formatters working llvm-svn: 153272
Diffstat (limited to 'lldb')
-rw-r--r--lldb/include/lldb/Core/FormatNavigator.h258
-rw-r--r--lldb/include/lldb/lldb-private-enumerations.h9
-rw-r--r--lldb/source/Commands/CommandObjectType.cpp8
-rw-r--r--lldb/source/Core/FormatManager.cpp39
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py39
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-categories/main.cpp5
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py14
-rwxr-xr-xlldb/www/varformats.html23
8 files changed, 105 insertions, 290 deletions
diff --git a/lldb/include/lldb/Core/FormatNavigator.h b/lldb/include/lldb/Core/FormatNavigator.h
index 42f7aad4b5f..f65eba416fb 100644
--- a/lldb/include/lldb/Core/FormatNavigator.h
+++ b/lldb/include/lldb/Core/FormatNavigator.h
@@ -458,132 +458,6 @@ protected:
return false;
}
- #define LLDB_MAX_REASONABLE_OBJC_CLASS_DEPTH 100
-
- bool Get_ObjC(const lldb::ProcessSP &process_sp,
- ObjCLanguageRuntime::ObjCISA isa,
- std::set<ObjCLanguageRuntime::ObjCISA> &found_values,
- MapValueType& entry,
- uint32_t& reason)
- {
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
- if (log)
- log->Printf("going to an Objective-C dynamic scanning");
- if (!process_sp)
- return false;
- ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
- if (runtime == NULL)
- {
- if (log)
- log->Printf("no valid ObjC runtime, bailing out");
- return false;
- }
- if (runtime->IsValidISA(isa) == false)
- {
- if (log)
- log->Printf("invalid ISA, bailing out");
- return false;
- }
-
- ConstString name = runtime->GetActualTypeName(isa);
- if (log)
- log->Printf("looking for formatter for %s", name.GetCString());
- if (Get(name, entry))
- {
- if (log)
- log->Printf("direct match found, returning");
- return true;
- }
- if (log)
- log->Printf("no direct match");
- ObjCLanguageRuntime::ObjCISA parent = runtime->GetParentClass(isa);
- if (runtime->IsValidISA(parent) == false)
- {
- if (log)
- log->Printf("invalid parent ISA, bailing out");
- return false;
- }
-
- // Put the isa value in our map. Then check the new_value, if it was already there, we've got a
- // loop in the inheritance hierarchy, and should bag out.
- std::pair<std::set<ObjCLanguageRuntime::ObjCISA>::iterator, bool> new_value = found_values.insert (isa);
- if (new_value.second == false)
- {
- //Our value already existed in the map.
- if (log)
- log->Printf ("ISA: 0x%llx already found in inheritance chain.", isa);
- return false;
- }
-
- if (found_values.size() > LLDB_MAX_REASONABLE_OBJC_CLASS_DEPTH)
- {
- // ObjC hierarchies are usually pretty shallow, if we've gone this far, we are probably chasing
- // uninitialized memory.
- if (log)
- log->Printf("Parent-child depth of %d, we are probably off in the weeds, bailing out.",
- LLDB_MAX_REASONABLE_OBJC_CLASS_DEPTH);
- return false;
- }
-
- if (Get_ObjC(process_sp, parent, found_values, entry, reason))
- {
- reason |= lldb_private::eFormatterChoiceCriterionNavigatedBaseClasses;
- return true;
- }
- return false;
- }
-
- bool
- Get_CXXClass (ValueObject& valobj,
- const clang::Type* typePtr,
- MapValueType& entry,
- lldb::DynamicValueType use_dynamic,
- uint32_t& reason)
- {
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
- if (log)
- log->Printf("working with C++");
- clang::CXXRecordDecl* record = typePtr->getAsCXXRecordDecl();
- if (record)
- {
- if (!record->hasDefinition())
- ClangASTContext::GetCompleteType(valobj.GetClangAST(), valobj.GetClangType());
- if (record->hasDefinition())
- {
- clang::CXXRecordDecl::base_class_iterator pos,end;
- if (record->getNumBases() > 0)
- {
- if (log)
- log->Printf("look into bases");
- end = record->bases_end();
- for (pos = record->bases_begin(); pos != end; pos++)
- {
- if ((Get(valobj, pos->getType(), entry, use_dynamic, reason)) && entry->Cascades())
- {
- reason |= lldb_private::eFormatterChoiceCriterionNavigatedBaseClasses;
- return true;
- }
- }
- }
- if (record->getNumVBases() > 0)
- {
- if (log)
- log->Printf("look into VBases");
- end = record->vbases_end();
- for (pos = record->vbases_begin(); pos != end; pos++)
- {
- if ((Get(valobj, pos->getType(), entry, use_dynamic, reason)) && entry->Cascades())
- {
- reason |= lldb_private::eFormatterChoiceCriterionNavigatedBaseClasses;
- return true;
- }
- }
- }
- }
- }
- return false;
- }
-
bool
Get_BitfieldMatch (ValueObject& valobj,
ConstString typeName,
@@ -612,68 +486,36 @@ protected:
}
}
- bool
- Get_ObjCDynamic(lldb::ProcessSP process_sp,
- ValueObject& valobj,
- MapValueType& entry,
- uint32_t& reason)
+ bool Get_ObjC (ValueObject& valobj,
+ MapValueType& entry)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
- if (!process_sp)
- return false;
- if (log)
- log->Printf("this is an ObjC 'id', let's do dynamic search");
+ lldb::ProcessSP process_sp = valobj.GetProcessSP();
ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
if (runtime == NULL)
{
if (log)
log->Printf("no valid ObjC runtime, skipping dynamic");
+ return false;
}
- else
+ ObjCLanguageRuntime::ObjCISA isa = runtime->GetISA(valobj);
+ if (runtime->IsValidISA(isa) == false)
{
- std::set<ObjCLanguageRuntime::ObjCISA> found_values;
- if (Get_ObjC(process_sp, runtime->GetISA(valobj), found_values, entry, reason))
- {
- reason |= lldb_private::eFormatterChoiceCriterionDynamicObjCHierarchy;
- return true;
- }
+ if (log)
+ log->Printf("invalid ISA, skipping dynamic");
+ return false;
}
- return false;
- }
-
- bool
- Get_ObjCStatic(const clang::ObjCObjectType *objc_class_type,
- ValueObject& valobj,
- clang::QualType type,
- MapValueType& entry,
- lldb::DynamicValueType use_dynamic,
- uint32_t& reason)
- {
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+ ConstString name = runtime->GetActualTypeName(isa);
if (log)
- log->Printf("working with ObjC");
- clang::ASTContext *ast = valobj.GetClangAST();
- if (ClangASTContext::GetCompleteType(ast, valobj.GetClangType()) && !objc_class_type->isObjCId())
+ log->Printf("dynamic type inferred is %s - looking for direct dynamic match", name.GetCString());
+ if (Get(name, entry))
{
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- if (class_interface_decl)
- {
- if (log)
- log->Printf("got an ObjCInterfaceDecl");
- clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
- {
- if (log)
- log->Printf("got a parent class for this ObjC class");
- clang::QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
- if (Get(valobj, ivar_qual_type, entry, use_dynamic, reason) && entry->Cascades())
- {
- reason |= lldb_private::eFormatterChoiceCriterionNavigatedBaseClasses;
- return true;
- }
- }
- }
+ if (log)
+ log->Printf("direct dynamic match found, returning");
+ return true;
}
+ if (log)
+ log->Printf("no dynamic match");
return false;
}
@@ -690,7 +532,7 @@ protected:
log->Printf("type is NULL, returning");
return false;
}
- // clang::QualType type = q_type.getUnqualifiedType();
+
type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict();
const clang::Type* typePtr = type.getTypePtrOrNull();
if (!typePtr)
@@ -721,7 +563,8 @@ protected:
}
if (log)
log->Printf("no direct match");
- // look for a "base type", whatever that means
+
+ // strip pointers and references and see if that helps
if (typePtr->isReferenceType())
{
if (log)
@@ -733,23 +576,6 @@ protected:
}
}
- lldb::ProcessSP process_sp = valobj.GetProcessSP();
-
- if (use_dynamic != lldb::eNoDynamicValues &&
- ClangASTType::GetMinimumLanguage(valobj.GetClangAST(), valobj.GetClangType()) == lldb::eLanguageTypeObjC)
- {
- if (Get_ObjCDynamic(process_sp, valobj, entry, reason))
- return true;
- }
- else if (use_dynamic != lldb::eNoDynamicValues && log)
- {
- log->Printf("typename: %s, typePtr = %p, id = %p",
- typeName.AsCString(), typePtr, valobj.GetClangAST()->ObjCBuiltinIdTy.getTypePtr());
- }
- else if (log)
- {
- log->Printf("no dynamic");
- }
if (typePtr->isPointerType())
{
if (log)
@@ -761,49 +587,29 @@ protected:
return true;
}
}
+
if (typePtr->isObjCObjectPointerType())
{
- if (use_dynamic != lldb::eNoDynamicValues &&
- typeName == m_id_cs)
+ if (use_dynamic != lldb::eNoDynamicValues)
{
- if (Get_ObjCDynamic(process_sp, valobj, entry, reason))
+ if (log)
+ log->Printf("allowed to figure out dynamic ObjC type");
+ if (Get_ObjC(valobj,entry))
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionDynamicObjCDiscovery;
return true;
+ }
}
if (log)
- log->Printf("stripping ObjC pointer");
-
- // For some reason, C++ can quite easily obtain the type hierarchy for a ValueObject
- // even if the VO represent a pointer-to-class, as long as the typePtr is right
- // Objective-C on the other hand cannot really complete an @interface when
- // the VO refers to a pointer-to-@interface
-
- Error error;
- ValueObject* target = valobj.Dereference(error).get();
- if (error.Fail() || !target)
- return false;
- if (Get(*target, typePtr->getPointeeType(), entry, use_dynamic, reason) && !entry->SkipsPointers())
+ log->Printf("dynamic disabled or failed - stripping ObjC pointer");
+ clang::QualType pointee = typePtr->getPointeeType();
+ if (Get(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers())
{
reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
return true;
}
}
- const clang::ObjCObjectType *objc_class_type = typePtr->getAs<clang::ObjCObjectType>();
- if (objc_class_type)
- {
- if (Get_ObjCStatic(objc_class_type,
- valobj,
- type,
- entry,
- use_dynamic,
- reason))
- return true;
- }
- // for C++ classes, navigate up the hierarchy
- if (typePtr->isRecordType())
- {
- if (Get_CXXClass(valobj, typePtr, entry, use_dynamic, reason))
- return true;
- }
+
// try to strip typedef chains
const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>();
if (type_tdef)
diff --git a/lldb/include/lldb/lldb-private-enumerations.h b/lldb/include/lldb/lldb-private-enumerations.h
index e8107724ea4..8b5b03f2fd3 100644
--- a/lldb/include/lldb/lldb-private-enumerations.h
+++ b/lldb/include/lldb/lldb-private-enumerations.h
@@ -231,11 +231,10 @@ typedef enum FormatterChoiceCriterion
eFormatterChoiceCriterionDirectChoice = 0x00000000,
eFormatterChoiceCriterionStrippedPointerReference = 0x00000001,
eFormatterChoiceCriterionNavigatedTypedefs = 0x00000002,
- eFormatterChoiceCriterionNavigatedBaseClasses = 0x00000004,
- eFormatterChoiceCriterionRegularExpressionSummary = 0x00000008,
- eFormatterChoiceCriterionRegularExpressionFilter = 0x00000008,
- eFormatterChoiceCriterionDynamicObjCHierarchy = 0x00000010,
- eFormatterChoiceCriterionStrippedBitField = 0x00000020
+ eFormatterChoiceCriterionRegularExpressionSummary = 0x00000004,
+ eFormatterChoiceCriterionRegularExpressionFilter = 0x00000004,
+ eFormatterChoiceCriterionDynamicObjCDiscovery = 0x00000008,
+ eFormatterChoiceCriterionStrippedBitField = 0x00000010
} FormatterChoiceCriterion;
//----------------------------------------------------------------------
diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp
index 2297138410b..10056b7353b 100644
--- a/lldb/source/Commands/CommandObjectType.cpp
+++ b/lldb/source/Commands/CommandObjectType.cpp
@@ -527,7 +527,7 @@ public:
OptionDefinition
CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."},
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
};
@@ -1370,7 +1370,7 @@ OptionDefinition
CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."},
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
{ LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."},
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
@@ -3558,7 +3558,7 @@ CommandObjectTypeSynthAdd::Execute (Args& command, CommandReturnObject &result)
OptionDefinition
CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."},
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
@@ -3846,7 +3846,7 @@ public:
OptionDefinition
CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."},
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
diff --git a/lldb/source/Core/FormatManager.cpp b/lldb/source/Core/FormatManager.cpp
index b2f3e3f7fbb..958ac18c9b6 100644
--- a/lldb/source/Core/FormatManager.cpp
+++ b/lldb/source/Core/FormatManager.cpp
@@ -881,50 +881,77 @@ FormatManager::LoadObjCFormatters()
.SetHideItemNames(false);
AddScriptSummary(appkit_category_sp, "CFArray.CFArray_SummaryProvider", ConstString("NSArray"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFArray.CFArray_SummaryProvider", ConstString("__NSArrayI"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFArray.CFArray_SummaryProvider", ConstString("__NSArrayM"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFArray.CFArray_SummaryProvider", ConstString("__NSCFArray"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFArray.CFArray_SummaryProvider", ConstString("CFArrayRef"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFArray.CFArray_SummaryProvider", ConstString("CFMutableArrayRef"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFBag.CFBag_SummaryProvider", ConstString("CFBagRef"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFBag.CFBag_SummaryProvider", ConstString("__CFBag"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFBag.CFBag_SummaryProvider", ConstString("const struct __CFBag"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFBag.CFBag_SummaryProvider", ConstString("CFMutableBagRef"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("CFBinaryHeapRef"), appkit_flags);
-
+ AddScriptSummary(appkit_category_sp, "CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("__CFBinaryHeap"), appkit_flags);
+
AddScriptSummary(appkit_category_sp, "CFDictionary.CFDictionary_SummaryProvider", ConstString("NSDictionary"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFDictionary.CFDictionary_SummaryProvider2", ConstString("CFDictionaryRef"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFDictionary.CFDictionary_SummaryProvider2", ConstString("CFMutableDictionaryRef"), appkit_flags);
-
+ AddScriptSummary(appkit_category_sp, "CFDictionary.CFDictionary_SummaryProvider", ConstString("__NSCFDictionary"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFDictionary.CFDictionary_SummaryProvider", ConstString("__NSDictionaryI"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFDictionary.CFDictionary_SummaryProvider", ConstString("__NSDictionaryM"), appkit_flags);
+
AddScriptSummary(appkit_category_sp, "CFString.CFString_SummaryProvider", ConstString("NSString"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFString.CFString_SummaryProvider", ConstString("CFStringRef"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFString.CFString_SummaryProvider", ConstString("CFMutableStringRef"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFString.CFAttributedString_SummaryProvider", ConstString("NSAttributedString"), appkit_flags);
-
+ AddScriptSummary(appkit_category_sp, "CFString.CFString_SummaryProvider", ConstString("__NSCFConstantString"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFString.CFString_SummaryProvider", ConstString("__NSCFString"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFString.CFString_SummaryProvider", ConstString("NSCFConstantString"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFString.CFString_SummaryProvider", ConstString("NSCFString"), appkit_flags);
+
AddScriptSummary(appkit_category_sp, "NSBundle.NSBundle_SummaryProvider", ConstString("NSBundle"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSData.NSData_SummaryProvider", ConstString("NSData"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSData.NSData_SummaryProvider2", ConstString("CFDataRef"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSData.NSData_SummaryProvider2", ConstString("CFMutableDataRef"), appkit_flags);
-
+ AddScriptSummary(appkit_category_sp, "NSData.NSData_SummaryProvider", ConstString("NSConcreteData"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSData.NSData_SummaryProvider", ConstString("NSConcreteMutableData"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSData.NSData_SummaryProvider", ConstString("__NSCFData"), appkit_flags);
+
AddScriptSummary(appkit_category_sp, "NSException.NSException_SummaryProvider", ConstString("NSException"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSMachPort.NSMachPort_SummaryProvider", ConstString("NSMachPort"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSNotification.NSNotification_SummaryProvider", ConstString("NSNotification"), appkit_flags);
-
+ AddScriptSummary(appkit_category_sp, "NSNotification.NSNotification_SummaryProvider", ConstString("NSConcreteNotification"), appkit_flags);
+
AddScriptSummary(appkit_category_sp, "NSNumber.NSNumber_SummaryProvider", ConstString("NSNumber"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSNumber.NSNumber_SummaryProvider", ConstString("__NSCFBoolean"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSNumber.NSNumber_SummaryProvider", ConstString("__NSCFNumber"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSNumber.NSNumber_SummaryProvider", ConstString("NSCFBoolean"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSNumber.NSNumber_SummaryProvider", ConstString("NSCFNumber"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSSet.NSSet_SummaryProvider", ConstString("NSSet"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSSet.NSSet_SummaryProvider2", ConstString("CFSetRef"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSSet.NSSet_SummaryProvider2", ConstString("CFMutableSetRef"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSSet.NSSet_SummaryProvider", ConstString("__NSCFSet"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSSet.NSSet_SummaryProvider", ConstString("__NSSetI"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSSet.NSSet_SummaryProvider", ConstString("__NSSetM"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSSet.NSSet_SummaryProvider", ConstString("NSCountedSet"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSURL.NSURL_SummaryProvider", ConstString("NSURL"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSURL.NSURL_SummaryProvider", ConstString("CFURLRef"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSDate.NSDate_SummaryProvider", ConstString("NSDate"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSDate.NSDate_SummaryProvider", ConstString("__NSDate"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSDate.NSDate_SummaryProvider", ConstString("__NSTaggedDate"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSDate.NSDate_SummaryProvider", ConstString("NSCalendarDate"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSDate.NSTimeZone_SummaryProvider", ConstString("NSTimeZone"), appkit_flags);
AddScriptSummary(appkit_category_sp, "NSDate.NSTimeZone_SummaryProvider", ConstString("CFTimeZoneRef"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "NSDate.NSTimeZone_SummaryProvider", ConstString("__NSTimeZone"), appkit_flags);
// CFAbsoluteTime is actually a double rather than a pointer to an object
// we do not care about the numeric value, since it is probably meaningless to users
@@ -939,6 +966,8 @@ FormatManager::LoadObjCFormatters()
AddScriptSummary(appkit_category_sp, "CFBitVector.CFBitVector_SummaryProvider", ConstString("CFBitVectorRef"), appkit_flags);
AddScriptSummary(appkit_category_sp, "CFBitVector.CFBitVector_SummaryProvider", ConstString("CFMutableBitVectorRef"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFBitVector.CFBitVector_SummaryProvider", ConstString("__CFBitVector"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "CFBitVector.CFBitVector_SummaryProvider", ConstString("__CFMutableBitVector"), appkit_flags);
TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py b/lldb/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
index 4fd8d3babbc..c7955807422 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
+++ b/lldb/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
@@ -255,36 +255,35 @@ class CategoriesDataFormatterTestCase(TestBase):
self.runCmd("type summary add Shape -w BaseCategory --summary-string \"AShape\"")
self.runCmd("type category enable BaseCategory")
- self.expect("frame variable c1 r1 c_ptr r_ptr",
- substrs = ['AShape',
- 'AShape',
- 'AShape',
- 'AShape'])
-
+ self.expect("print (Shape*)&c1",
+ substrs = ['AShape'])
+ self.expect("print (Shape*)&r1",
+ substrs = ['AShape'])
+ self.expect("print (Shape*)c_ptr",
+ substrs = ['AShape'])
+ self.expect("print (Shape*)r_ptr",
+ substrs = ['AShape'])
+
self.runCmd("type summary add Circle -w CircleCategory --summary-string \"ACircle\"")
self.runCmd("type summary add Rectangle -w RectangleCategory --summary-string \"ARectangle\"")
self.runCmd("type category enable CircleCategory")
- self.expect("frame variable c1 r1 c_ptr r_ptr",
- substrs = ['ACircle',
- 'AShape',
- 'ACircle',
- 'AShape'])
+ self.expect("frame variable c1",
+ substrs = ['ACircle'])
+ self.expect("frame variable c_ptr",
+ substrs = ['ACircle'])
self.runCmd("type summary add \"Rectangle *\" -w RectangleStarCategory --summary-string \"ARectangleStar\"")
self.runCmd("type category enable RectangleStarCategory")
self.expect("frame variable c1 r1 c_ptr r_ptr",
substrs = ['ACircle',
- 'AShape',
- 'ACircle',
'ARectangleStar'])
self.runCmd("type category enable RectangleCategory")
self.expect("frame variable c1 r1 c_ptr r_ptr",
substrs = ['ACircle',
- 'ARectangle',
'ACircle',
'ARectangle'])
@@ -293,14 +292,13 @@ class CategoriesDataFormatterTestCase(TestBase):
self.expect("frame variable c1 r1 c_ptr r_ptr",
substrs = ['ACircle',
- 'AShape',
+ '(Rectangle) r1 = {', 'w = 5', 'h = 6',
'ACircle',
'ARectangleStar'])
# check that list commands work
self.expect("type category list",
- substrs = ['RectangleStarCategory',
- 'is enabled'])
+ substrs = ['RectangleStarCategory is enabled'])
self.expect("type summary list",
substrs = ['ARectangleStar'])
@@ -310,13 +308,10 @@ class CategoriesDataFormatterTestCase(TestBase):
# check that list commands work
self.expect("type category list",
- substrs = ['CircleCategory',
- 'not enabled'])
+ substrs = ['CircleCategory is not enabled'])
- self.expect("frame variable c1 r1 c_ptr r_ptr",
+ self.expect("frame variable c1 r_ptr",
substrs = ['AShape',
- 'AShape',
- 'AShape',
'ARectangleStar'])
# check that filters work into categories
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-categories/main.cpp b/lldb/test/functionalities/data-formatter/data-formatter-categories/main.cpp
index 59f2c24b506..b51dd45a7f6 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-categories/main.cpp
+++ b/lldb/test/functionalities/data-formatter/data-formatter-categories/main.cpp
@@ -12,7 +12,10 @@
#include <stdint.h>
struct Shape
-{};
+{
+ bool dummy;
+ Shape() : dummy(true) {}
+};
struct Rectangle : public Shape {
int w;
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 2a3ec439a82..44bbc4aa8c5 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
+++ b/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
@@ -128,20 +128,6 @@ class ObjCDataFormatterTestCase(TestBase):
self.runCmd("type summary add --summary-string \"a test\" MyClass")
- self.expect("frame variable object2",
- substrs = ['a test']);
-
- self.expect("frame variable *object2",
- substrs = ['a test']);
-
- self.expect("frame variable object",
- substrs = ['a test']);
-
- self.expect("frame variable *object",
- substrs = ['a test']);
-
- self.runCmd("type summary add --summary-string \"a test\" MyClass -C no")
-
self.expect("frame variable *object2",
substrs = ['*object2 = {',
'MyClass = a test',
diff --git a/lldb/www/varformats.html b/lldb/www/varformats.html
index 58d5d5ac3be..a1b0dfe2f6d 100755
--- a/lldb/www/varformats.html
+++ b/lldb/www/varformats.html
@@ -1255,18 +1255,9 @@ def function (valobj,dict):<br/>
<li>If this object is a reference, and there is a
formatter for the referred type that does not skip
references, use it</li>
- <li>If this object is an Objective-C class with a parent
- class, look at the parent class (and parent of parent,
- ...). This phase can be based upon the actual type of
- the object as inferred by the value of its <code>isa</code>
- pointer, or upon the debugging information inferred by the
- debugger. The user can use the dynamic typing settings to
- elect one or the other behavior.</li>
- <li>If this object is a C++ class with base classes,
- look at base classes (and bases of bases, ...)</li>
- <li>If this object is a C++ class with virtual base
- classes, look at the virtual base classes (and bases
- of bases, ...)</li>
+ <li>If this object is an Objective-C class and dynamic types are enabled,
+ look for a formatter for the dynamic type of the object. If dynamic types are disabled,
+ or the search failed, look for a formatter for the declared type of the object</li>
<li>If this object's type is a typedef, go through
typedef hierarchy (LLDB might not be able to do this if
the compiler has not emitted enough information. If the
@@ -1274,7 +1265,8 @@ def function (valobj,dict):<br/>
missing, type cascading will not work. The
<a href="http://clang.llvm.org/">clang compiler</a>,
part of the LLVM project, emits the correct debugging
- information for LLDB to cascade)</li>
+ information for LLDB to cascade). If at any level of the hierarchy
+ there is a valid formatter that can cascade, use it.</li>
<li>If everything has failed, repeat the above search,
looking for regular expressions instead of exact
matches</li>
@@ -1284,6 +1276,11 @@ def function (valobj,dict):<br/>
in other categories). If nothing was found in the current category, the next
enabled category is scanned according to the same algorithm. If there are no
more enabled categories, the search has failed.</p>
+ <p><font color=red>Warning</font>: previous versions of LLDB defined cascading to mean
+ not only going through typedef chains, but also through inheritance chains.
+ This feature has been removed since it significantly degrades performance.
+ You need to set up your formatters for every type in inheritance chains to which
+ you want the formatter to apply.</p>
</div>
</div>
</div>
OpenPOWER on IntegriCloud