10b57cec5SDimitry Andric //===-- TypeSummary.cpp ---------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/DataFormatters/TypeSummary.h"
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h"
150b57cec5SDimitry Andric #include "lldb/lldb-public.h"
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
180b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h"
190b57cec5SDimitry Andric #include "lldb/DataFormatters/ValueObjectPrinter.h"
200b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h"
210b57cec5SDimitry Andric #include "lldb/Symbol/CompilerType.h"
220b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h"
230b57cec5SDimitry Andric #include "lldb/Target/Target.h"
240b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h"
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric using namespace lldb;
270b57cec5SDimitry Andric using namespace lldb_private;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric TypeSummaryOptions::TypeSummaryOptions() = default;
300b57cec5SDimitry Andric 
GetLanguage() const310b57cec5SDimitry Andric lldb::LanguageType TypeSummaryOptions::GetLanguage() const { return m_lang; }
320b57cec5SDimitry Andric 
GetCapping() const330b57cec5SDimitry Andric lldb::TypeSummaryCapping TypeSummaryOptions::GetCapping() const {
340b57cec5SDimitry Andric   return m_capping;
350b57cec5SDimitry Andric }
360b57cec5SDimitry Andric 
SetLanguage(lldb::LanguageType lang)370b57cec5SDimitry Andric TypeSummaryOptions &TypeSummaryOptions::SetLanguage(lldb::LanguageType lang) {
380b57cec5SDimitry Andric   m_lang = lang;
390b57cec5SDimitry Andric   return *this;
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric TypeSummaryOptions &
SetCapping(lldb::TypeSummaryCapping cap)430b57cec5SDimitry Andric TypeSummaryOptions::SetCapping(lldb::TypeSummaryCapping cap) {
440b57cec5SDimitry Andric   m_capping = cap;
450b57cec5SDimitry Andric   return *this;
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric 
TypeSummaryImpl(Kind kind,const TypeSummaryImpl::Flags & flags)480b57cec5SDimitry Andric TypeSummaryImpl::TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags)
490b57cec5SDimitry Andric     : m_flags(flags), m_kind(kind) {}
500b57cec5SDimitry Andric 
StringSummaryFormat(const TypeSummaryImpl::Flags & flags,const char * format_cstr)510b57cec5SDimitry Andric StringSummaryFormat::StringSummaryFormat(const TypeSummaryImpl::Flags &flags,
520b57cec5SDimitry Andric                                          const char *format_cstr)
530b57cec5SDimitry Andric     : TypeSummaryImpl(Kind::eSummaryString, flags), m_format_str() {
540b57cec5SDimitry Andric   SetSummaryString(format_cstr);
550b57cec5SDimitry Andric }
560b57cec5SDimitry Andric 
SetSummaryString(const char * format_cstr)570b57cec5SDimitry Andric void StringSummaryFormat::SetSummaryString(const char *format_cstr) {
580b57cec5SDimitry Andric   m_format.Clear();
590b57cec5SDimitry Andric   if (format_cstr && format_cstr[0]) {
600b57cec5SDimitry Andric     m_format_str = format_cstr;
610b57cec5SDimitry Andric     m_error = FormatEntity::Parse(format_cstr, m_format);
620b57cec5SDimitry Andric   } else {
630b57cec5SDimitry Andric     m_format_str.clear();
640b57cec5SDimitry Andric     m_error.Clear();
650b57cec5SDimitry Andric   }
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
FormatObject(ValueObject * valobj,std::string & retval,const TypeSummaryOptions & options)680b57cec5SDimitry Andric bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
690b57cec5SDimitry Andric                                        const TypeSummaryOptions &options) {
700b57cec5SDimitry Andric   if (!valobj) {
710b57cec5SDimitry Andric     retval.assign("NULL ValueObject");
720b57cec5SDimitry Andric     return false;
730b57cec5SDimitry Andric   }
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   StreamString s;
760b57cec5SDimitry Andric   ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
770b57cec5SDimitry Andric   SymbolContext sc;
780b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
790b57cec5SDimitry Andric   if (frame)
800b57cec5SDimitry Andric     sc = frame->GetSymbolContext(lldb::eSymbolContextEverything);
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   if (IsOneLiner()) {
830b57cec5SDimitry Andric     ValueObjectPrinter printer(valobj, &s, DumpValueObjectOptions());
840b57cec5SDimitry Andric     printer.PrintChildrenOneLiner(HideNames(valobj));
850b57cec5SDimitry Andric     retval = std::string(s.GetString());
860b57cec5SDimitry Andric     return true;
870b57cec5SDimitry Andric   } else {
880b57cec5SDimitry Andric     if (FormatEntity::Format(m_format, s, &sc, &exe_ctx,
890b57cec5SDimitry Andric                              &sc.line_entry.range.GetBaseAddress(), valobj,
900b57cec5SDimitry Andric                              false, false)) {
910b57cec5SDimitry Andric       retval.assign(std::string(s.GetString()));
920b57cec5SDimitry Andric       return true;
930b57cec5SDimitry Andric     } else {
940b57cec5SDimitry Andric       retval.assign("error: summary string parsing error");
950b57cec5SDimitry Andric       return false;
960b57cec5SDimitry Andric     }
970b57cec5SDimitry Andric   }
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric 
GetDescription()1000b57cec5SDimitry Andric std::string StringSummaryFormat::GetDescription() {
1010b57cec5SDimitry Andric   StreamString sstr;
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   sstr.Printf("`%s`%s%s%s%s%s%s%s%s%s", m_format_str.c_str(),
1040b57cec5SDimitry Andric               m_error.Fail() ? " error: " : "",
1050b57cec5SDimitry Andric               m_error.Fail() ? m_error.AsCString() : "",
1060b57cec5SDimitry Andric               Cascades() ? "" : " (not cascading)",
1070b57cec5SDimitry Andric               !DoesPrintChildren(nullptr) ? "" : " (show children)",
1080b57cec5SDimitry Andric               !DoesPrintValue(nullptr) ? " (hide value)" : "",
1090b57cec5SDimitry Andric               IsOneLiner() ? " (one-line printout)" : "",
1100b57cec5SDimitry Andric               SkipsPointers() ? " (skip pointers)" : "",
1110b57cec5SDimitry Andric               SkipsReferences() ? " (skip references)" : "",
1120b57cec5SDimitry Andric               HideNames(nullptr) ? " (hide member names)" : "");
1130b57cec5SDimitry Andric   return std::string(sstr.GetString());
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric 
CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags & flags,Callback impl,const char * description)1160b57cec5SDimitry Andric CXXFunctionSummaryFormat::CXXFunctionSummaryFormat(
1170b57cec5SDimitry Andric     const TypeSummaryImpl::Flags &flags, Callback impl, const char *description)
1180b57cec5SDimitry Andric     : TypeSummaryImpl(Kind::eCallback, flags), m_impl(impl),
1190b57cec5SDimitry Andric       m_description(description ? description : "") {}
1200b57cec5SDimitry Andric 
FormatObject(ValueObject * valobj,std::string & dest,const TypeSummaryOptions & options)1210b57cec5SDimitry Andric bool CXXFunctionSummaryFormat::FormatObject(ValueObject *valobj,
1220b57cec5SDimitry Andric                                             std::string &dest,
1230b57cec5SDimitry Andric                                             const TypeSummaryOptions &options) {
1240b57cec5SDimitry Andric   dest.clear();
1250b57cec5SDimitry Andric   StreamString stream;
1260b57cec5SDimitry Andric   if (!m_impl || !m_impl(*valobj, stream, options))
1270b57cec5SDimitry Andric     return false;
1280b57cec5SDimitry Andric   dest = std::string(stream.GetString());
1290b57cec5SDimitry Andric   return true;
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
GetDescription()1320b57cec5SDimitry Andric std::string CXXFunctionSummaryFormat::GetDescription() {
1330b57cec5SDimitry Andric   StreamString sstr;
1340b57cec5SDimitry Andric   sstr.Printf("%s%s%s%s%s%s%s %s", Cascades() ? "" : " (not cascading)",
1350b57cec5SDimitry Andric               !DoesPrintChildren(nullptr) ? "" : " (show children)",
1360b57cec5SDimitry Andric               !DoesPrintValue(nullptr) ? " (hide value)" : "",
1370b57cec5SDimitry Andric               IsOneLiner() ? " (one-line printout)" : "",
1380b57cec5SDimitry Andric               SkipsPointers() ? " (skip pointers)" : "",
1390b57cec5SDimitry Andric               SkipsReferences() ? " (skip references)" : "",
1400b57cec5SDimitry Andric               HideNames(nullptr) ? " (hide member names)" : "",
1410b57cec5SDimitry Andric               m_description.c_str());
1420b57cec5SDimitry Andric   return std::string(sstr.GetString());
1430b57cec5SDimitry Andric }
1440b57cec5SDimitry Andric 
ScriptSummaryFormat(const TypeSummaryImpl::Flags & flags,const char * function_name,const char * python_script)1450b57cec5SDimitry Andric ScriptSummaryFormat::ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags,
1460b57cec5SDimitry Andric                                          const char *function_name,
1470b57cec5SDimitry Andric                                          const char *python_script)
1480b57cec5SDimitry Andric     : TypeSummaryImpl(Kind::eScript, flags), m_function_name(),
1490b57cec5SDimitry Andric       m_python_script(), m_script_function_sp() {
1500b57cec5SDimitry Andric   if (function_name)
1510b57cec5SDimitry Andric     m_function_name.assign(function_name);
1520b57cec5SDimitry Andric   if (python_script)
1530b57cec5SDimitry Andric     m_python_script.assign(python_script);
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric 
FormatObject(ValueObject * valobj,std::string & retval,const TypeSummaryOptions & options)1560b57cec5SDimitry Andric bool ScriptSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
1570b57cec5SDimitry Andric                                        const TypeSummaryOptions &options) {
1580b57cec5SDimitry Andric   if (!valobj)
1590b57cec5SDimitry Andric     return false;
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   TargetSP target_sp(valobj->GetTargetSP());
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   if (!target_sp) {
1640b57cec5SDimitry Andric     retval.assign("error: no target");
1650b57cec5SDimitry Andric     return false;
1660b57cec5SDimitry Andric   }
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric   ScriptInterpreter *script_interpreter =
1690b57cec5SDimitry Andric       target_sp->GetDebugger().GetScriptInterpreter();
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric   if (!script_interpreter) {
1720b57cec5SDimitry Andric     retval.assign("error: no ScriptInterpreter");
1730b57cec5SDimitry Andric     return false;
1740b57cec5SDimitry Andric   }
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   return script_interpreter->GetScriptedSummary(
1770b57cec5SDimitry Andric       m_function_name.c_str(), valobj->GetSP(), m_script_function_sp, options,
1780b57cec5SDimitry Andric       retval);
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric 
GetDescription()1810b57cec5SDimitry Andric std::string ScriptSummaryFormat::GetDescription() {
1820b57cec5SDimitry Andric   StreamString sstr;
1830b57cec5SDimitry Andric   sstr.Printf("%s%s%s%s%s%s%s\n  ", Cascades() ? "" : " (not cascading)",
1840b57cec5SDimitry Andric               !DoesPrintChildren(nullptr) ? "" : " (show children)",
1850b57cec5SDimitry Andric               !DoesPrintValue(nullptr) ? " (hide value)" : "",
1860b57cec5SDimitry Andric               IsOneLiner() ? " (one-line printout)" : "",
1870b57cec5SDimitry Andric               SkipsPointers() ? " (skip pointers)" : "",
1880b57cec5SDimitry Andric               SkipsReferences() ? " (skip references)" : "",
1890b57cec5SDimitry Andric               HideNames(nullptr) ? " (hide member names)" : "");
1900b57cec5SDimitry Andric   if (m_python_script.empty()) {
1910b57cec5SDimitry Andric     if (m_function_name.empty()) {
1920b57cec5SDimitry Andric       sstr.PutCString("no backing script");
1930b57cec5SDimitry Andric     } else {
1940b57cec5SDimitry Andric       sstr.PutCString(m_function_name);
1950b57cec5SDimitry Andric     }
1960b57cec5SDimitry Andric   } else {
1970b57cec5SDimitry Andric     sstr.PutCString(m_python_script);
1980b57cec5SDimitry Andric   }
1990b57cec5SDimitry Andric   return std::string(sstr.GetString());
2000b57cec5SDimitry Andric }
2010b57cec5SDimitry Andric