bool lldb_private::formatters::swift::SwiftOptionalSummaryProvider::DoesPrintChildren (ValueObject* target_valobj) const { if (!target_valobj) return false; ValueObject *some = ExtractSomeIfAny(target_valobj,target_valobj->GetDynamicValueType(),true); if (!some) return true; lldb_private::Flags some_flags(some->GetCompilerType().GetTypeInfo()); if (some_flags.AllSet(eTypeIsSwift | eTypeInstanceIsPointer)) return true; lldb::TypeSummaryImplSP summary_sp = some->GetSummaryFormat(); if (!summary_sp) { if (lldb_private::DataVisualization::ShouldPrintAsOneLiner(*some)) return false; else return (some->GetNumChildren() > 0); } else return (some->GetNumChildren() > 0) && (summary_sp->DoesPrintChildren(some)); }
bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string& retval) { if (!valobj) { retval.assign("NULL ValueObject"); return false; } StreamString s; ExecutionContext exe_ctx (valobj->GetExecutionContextRef()); SymbolContext sc; StackFrame *frame = exe_ctx.GetFramePtr(); if (frame) sc = frame->GetSymbolContext(lldb::eSymbolContextEverything); if (IsOneliner()) { ValueObject* object; ValueObjectSP synth_valobj = valobj->GetSyntheticValue(); if (synth_valobj) object = synth_valobj.get(); else object = valobj; const uint32_t num_children = object->GetNumChildren(); if (num_children) { s.PutChar('('); for (uint32_t idx=0; idx<num_children; ++idx) { lldb::ValueObjectSP child_sp(object->GetChildAtIndex(idx, true)); if (child_sp.get()) { if (idx) s.PutCString(", "); if (!HideNames()) { s.PutCString(child_sp.get()->GetName().AsCString()); s.PutCString(" = "); } child_sp.get()->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleSummary, lldb::eFormatInvalid, ValueObject::ePrintableRepresentationSpecialCasesDisable); } } s.PutChar(')'); retval.assign(s.GetString()); return true; } else { retval.assign("error: oneliner for no children"); return false; } } else { if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, valobj)) { retval.assign(s.GetString()); return true; } else { retval.assign("error: summary string parsing error"); return false; } } }
bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) { // if settings say no oneline whatsoever if (valobj.GetTargetSP().get() && !valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries()) return false; // then don't oneline // if this object has a summary, then ask the summary if (valobj.GetSummaryFormat().get() != nullptr) return valobj.GetSummaryFormat()->IsOneLiner(); // no children, no party if (valobj.GetNumChildren() == 0) return false; // ask the type if it has any opinion about this eLazyBoolCalculate == no // opinion; other values should be self explanatory CompilerType compiler_type(valobj.GetCompilerType()); if (compiler_type.IsValid()) { switch (compiler_type.ShouldPrintAsOneLiner(&valobj)) { case eLazyBoolNo: return false; case eLazyBoolYes: return true; case eLazyBoolCalculate: break; } } size_t total_children_name_len = 0; for (size_t idx = 0; idx < valobj.GetNumChildren(); idx++) { bool is_synth_val = false; ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true)); // something is wrong here - bail out if (!child_sp) return false; // also ask the child's type if it has any opinion CompilerType child_compiler_type(child_sp->GetCompilerType()); if (child_compiler_type.IsValid()) { switch (child_compiler_type.ShouldPrintAsOneLiner(child_sp.get())) { case eLazyBoolYes: // an opinion of yes is only binding for the child, so keep going case eLazyBoolCalculate: break; case eLazyBoolNo: // but if the child says no, then it's a veto on the whole thing return false; } } // if we decided to define synthetic children for a type, we probably care // enough to show them, but avoid nesting children in children if (child_sp->GetSyntheticChildren().get() != nullptr) { ValueObjectSP synth_sp(child_sp->GetSyntheticValue()); // wait.. wat? just get out of here.. if (!synth_sp) return false; // but if we only have them to provide a value, keep going if (!synth_sp->MightHaveChildren() && synth_sp->DoesProvideSyntheticValue()) is_synth_val = true; else return false; } total_children_name_len += child_sp->GetName().GetLength(); // 50 itself is a "randomly" chosen number - the idea is that // overly long structs should not get this treatment // FIXME: maybe make this a user-tweakable setting? if (total_children_name_len > 50) return false; // if a summary is there.. if (child_sp->GetSummaryFormat()) { // and it wants children, then bail out if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get())) return false; } // if this child has children.. if (child_sp->GetNumChildren()) { // ...and no summary... // (if it had a summary and the summary wanted children, we would have // bailed out anyway // so this only makes us bail out if this has no summary and we would // then print children) if (!child_sp->GetSummaryFormat() && !is_synth_val) // but again only do // that if not a // synthetic valued // child return false; // then bail out } } return true; }