1//===-- TypeSummary.cpp ----------------------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "lldb/DataFormatters/TypeSummary.h" 10 11 12 13 14#include "lldb/lldb-enumerations.h" 15#include "lldb/lldb-public.h" 16 17#include "lldb/Core/Debugger.h" 18#include "lldb/Core/ValueObject.h" 19#include "lldb/DataFormatters/ValueObjectPrinter.h" 20#include "lldb/Interpreter/CommandInterpreter.h" 21#include "lldb/Symbol/CompilerType.h" 22#include "lldb/Target/StackFrame.h" 23#include "lldb/Target/Target.h" 24#include "lldb/Utility/StreamString.h" 25 26using namespace lldb; 27using namespace lldb_private; 28 29TypeSummaryOptions::TypeSummaryOptions() 30 : m_lang(eLanguageTypeUnknown), m_capping(eTypeSummaryCapped) {} 31 32lldb::LanguageType TypeSummaryOptions::GetLanguage() const { return m_lang; } 33 34lldb::TypeSummaryCapping TypeSummaryOptions::GetCapping() const { 35 return m_capping; 36} 37 38TypeSummaryOptions &TypeSummaryOptions::SetLanguage(lldb::LanguageType lang) { 39 m_lang = lang; 40 return *this; 41} 42 43TypeSummaryOptions & 44TypeSummaryOptions::SetCapping(lldb::TypeSummaryCapping cap) { 45 m_capping = cap; 46 return *this; 47} 48 49TypeSummaryImpl::TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags) 50 : m_flags(flags), m_kind(kind) {} 51 52StringSummaryFormat::StringSummaryFormat(const TypeSummaryImpl::Flags &flags, 53 const char *format_cstr) 54 : TypeSummaryImpl(Kind::eSummaryString, flags), m_format_str() { 55 SetSummaryString(format_cstr); 56} 57 58void StringSummaryFormat::SetSummaryString(const char *format_cstr) { 59 m_format.Clear(); 60 if (format_cstr && format_cstr[0]) { 61 m_format_str = format_cstr; 62 m_error = FormatEntity::Parse(format_cstr, m_format); 63 } else { 64 m_format_str.clear(); 65 m_error.Clear(); 66 } 67} 68 69bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval, 70 const TypeSummaryOptions &options) { 71 if (!valobj) { 72 retval.assign("NULL ValueObject"); 73 return false; 74 } 75 76 StreamString s; 77 ExecutionContext exe_ctx(valobj->GetExecutionContextRef()); 78 SymbolContext sc; 79 StackFrame *frame = exe_ctx.GetFramePtr(); 80 if (frame) 81 sc = frame->GetSymbolContext(lldb::eSymbolContextEverything); 82 83 if (IsOneLiner()) { 84 ValueObjectPrinter printer(valobj, &s, DumpValueObjectOptions()); 85 printer.PrintChildrenOneLiner(HideNames(valobj)); 86 retval = s.GetString(); 87 return true; 88 } else { 89 if (FormatEntity::Format(m_format, s, &sc, &exe_ctx, 90 &sc.line_entry.range.GetBaseAddress(), valobj, 91 false, false)) { 92 retval.assign(s.GetString()); 93 return true; 94 } else { 95 retval.assign("error: summary string parsing error"); 96 return false; 97 } 98 } 99} 100 101std::string StringSummaryFormat::GetDescription() { 102 StreamString sstr; 103 104 sstr.Printf("`%s`%s%s%s%s%s%s%s%s%s", m_format_str.c_str(), 105 m_error.Fail() ? " error: " : "", 106 m_error.Fail() ? m_error.AsCString() : "", 107 Cascades() ? "" : " (not cascading)", 108 !DoesPrintChildren(nullptr) ? "" : " (show children)", 109 !DoesPrintValue(nullptr) ? " (hide value)" : "", 110 IsOneLiner() ? " (one-line printout)" : "", 111 SkipsPointers() ? " (skip pointers)" : "", 112 SkipsReferences() ? " (skip references)" : "", 113 HideNames(nullptr) ? " (hide member names)" : ""); 114 return sstr.GetString(); 115} 116 117CXXFunctionSummaryFormat::CXXFunctionSummaryFormat( 118 const TypeSummaryImpl::Flags &flags, Callback impl, const char *description) 119 : TypeSummaryImpl(Kind::eCallback, flags), m_impl(impl), 120 m_description(description ? description : "") {} 121 122bool CXXFunctionSummaryFormat::FormatObject(ValueObject *valobj, 123 std::string &dest, 124 const TypeSummaryOptions &options) { 125 dest.clear(); 126 StreamString stream; 127 if (!m_impl || !m_impl(*valobj, stream, options)) 128 return false; 129 dest = stream.GetString(); 130 return true; 131} 132 133std::string CXXFunctionSummaryFormat::GetDescription() { 134 StreamString sstr; 135 sstr.Printf("%s%s%s%s%s%s%s %s", Cascades() ? "" : " (not cascading)", 136 !DoesPrintChildren(nullptr) ? "" : " (show children)", 137 !DoesPrintValue(nullptr) ? " (hide value)" : "", 138 IsOneLiner() ? " (one-line printout)" : "", 139 SkipsPointers() ? " (skip pointers)" : "", 140 SkipsReferences() ? " (skip references)" : "", 141 HideNames(nullptr) ? " (hide member names)" : "", 142 m_description.c_str()); 143 return sstr.GetString(); 144} 145 146ScriptSummaryFormat::ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags, 147 const char *function_name, 148 const char *python_script) 149 : TypeSummaryImpl(Kind::eScript, flags), m_function_name(), 150 m_python_script(), m_script_function_sp() { 151 if (function_name) 152 m_function_name.assign(function_name); 153 if (python_script) 154 m_python_script.assign(python_script); 155} 156 157bool ScriptSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval, 158 const TypeSummaryOptions &options) { 159 if (!valobj) 160 return false; 161 162 TargetSP target_sp(valobj->GetTargetSP()); 163 164 if (!target_sp) { 165 retval.assign("error: no target"); 166 return false; 167 } 168 169 ScriptInterpreter *script_interpreter = 170 target_sp->GetDebugger().GetScriptInterpreter(); 171 172 if (!script_interpreter) { 173 retval.assign("error: no ScriptInterpreter"); 174 return false; 175 } 176 177 return script_interpreter->GetScriptedSummary( 178 m_function_name.c_str(), valobj->GetSP(), m_script_function_sp, options, 179 retval); 180} 181 182std::string ScriptSummaryFormat::GetDescription() { 183 StreamString sstr; 184 sstr.Printf("%s%s%s%s%s%s%s\n ", Cascades() ? "" : " (not cascading)", 185 !DoesPrintChildren(nullptr) ? "" : " (show children)", 186 !DoesPrintValue(nullptr) ? " (hide value)" : "", 187 IsOneLiner() ? " (one-line printout)" : "", 188 SkipsPointers() ? " (skip pointers)" : "", 189 SkipsReferences() ? " (skip references)" : "", 190 HideNames(nullptr) ? " (hide member names)" : ""); 191 if (m_python_script.empty()) { 192 if (m_function_name.empty()) { 193 sstr.PutCString("no backing script"); 194 } else { 195 sstr.PutCString(m_function_name); 196 } 197 } else { 198 sstr.PutCString(m_python_script); 199 } 200 return sstr.GetString(); 201} 202