Home | History | Annotate | Download | only in DataFormatters
      1 //===-- TypeSummary.cpp ----------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/lldb-python.h"
     11 
     12 // C Includes
     13 
     14 // C++ Includes
     15 
     16 // Other libraries and framework includes
     17 
     18 // Project includes
     19 #include "lldb/lldb-public.h"
     20 #include "lldb/lldb-enumerations.h"
     21 
     22 #include "lldb/Core/Debugger.h"
     23 #include "lldb/Core/StreamString.h"
     24 #include "lldb/Core/Timer.h"
     25 #include "lldb/DataFormatters/TypeSummary.h"
     26 #include "lldb/Interpreter/CommandInterpreter.h"
     27 #include "lldb/Symbol/ClangASTType.h"
     28 #include "lldb/Target/StackFrame.h"
     29 #include "lldb/Target/Target.h"
     30 
     31 #include "lldb/Host/Host.h"
     32 
     33 using namespace lldb;
     34 using namespace lldb_private;
     35 
     36 TypeSummaryImpl::TypeSummaryImpl (const TypeSummaryImpl::Flags& flags) :
     37 m_flags(flags)
     38 {
     39 }
     40 
     41 
     42 StringSummaryFormat::StringSummaryFormat (const TypeSummaryImpl::Flags& flags,
     43                                           const char *format_cstr) :
     44 TypeSummaryImpl(flags),
     45 m_format()
     46 {
     47     if (format_cstr)
     48         m_format.assign(format_cstr);
     49 }
     50 
     51 bool
     52 StringSummaryFormat::FormatObject (ValueObject *valobj,
     53                                    std::string& retval)
     54 {
     55     if (!valobj)
     56     {
     57         retval.assign("NULL ValueObject");
     58         return false;
     59     }
     60 
     61     StreamString s;
     62     ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
     63     SymbolContext sc;
     64     StackFrame *frame = exe_ctx.GetFramePtr();
     65     if (frame)
     66         sc = frame->GetSymbolContext(lldb::eSymbolContextEverything);
     67 
     68     if (IsOneliner())
     69     {
     70         ValueObject* object;
     71 
     72         ValueObjectSP synth_valobj = valobj->GetSyntheticValue();
     73         if (synth_valobj)
     74             object = synth_valobj.get();
     75         else
     76             object = valobj;
     77 
     78         const uint32_t num_children = object->GetNumChildren();
     79         if (num_children)
     80         {
     81             s.PutChar('(');
     82 
     83             for (uint32_t idx=0; idx<num_children; ++idx)
     84             {
     85                 lldb::ValueObjectSP child_sp(object->GetChildAtIndex(idx, true));
     86                 if (child_sp.get())
     87                 {
     88                     if (idx)
     89                         s.PutCString(", ");
     90                     if (!HideNames())
     91                     {
     92                         s.PutCString(child_sp.get()->GetName().AsCString());
     93                         s.PutCString(" = ");
     94                     }
     95                     child_sp.get()->DumpPrintableRepresentation(s,
     96                                                                 ValueObject::eValueObjectRepresentationStyleSummary,
     97                                                                 lldb::eFormatInvalid,
     98                                                                 ValueObject::ePrintableRepresentationSpecialCasesDisable);
     99                 }
    100             }
    101 
    102             s.PutChar(')');
    103 
    104             retval.assign(s.GetString());
    105             return true;
    106         }
    107         else
    108         {
    109             retval.assign("error: oneliner for no children");
    110             return false;
    111         }
    112 
    113     }
    114     else
    115     {
    116         if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, valobj))
    117         {
    118             retval.assign(s.GetString());
    119             return true;
    120         }
    121         else
    122         {
    123             retval.assign("error: summary string parsing error");
    124             return false;
    125         }
    126     }
    127 }
    128 
    129 std::string
    130 StringSummaryFormat::GetDescription ()
    131 {
    132     StreamString sstr;
    133 
    134     sstr.Printf ("`%s`%s%s%s%s%s%s%s",      m_format.c_str(),
    135                  Cascades() ? "" : " (not cascading)",
    136                  !DoesPrintChildren() ? "" : " (show children)",
    137                  !DoesPrintValue() ? " (hide value)" : "",
    138                  IsOneliner() ? " (one-line printout)" : "",
    139                  SkipsPointers() ? " (skip pointers)" : "",
    140                  SkipsReferences() ? " (skip references)" : "",
    141                  HideNames() ? " (hide member names)" : "");
    142     return sstr.GetString();
    143 }
    144 
    145 CXXFunctionSummaryFormat::CXXFunctionSummaryFormat (const TypeSummaryImpl::Flags& flags,
    146                                                     Callback impl,
    147                                                     const char* description) :
    148 TypeSummaryImpl(flags),
    149 m_impl(impl),
    150 m_description(description ? description : "")
    151 {
    152 }
    153 
    154 bool
    155 CXXFunctionSummaryFormat::FormatObject (ValueObject *valobj,
    156                                         std::string& dest)
    157 {
    158     dest.clear();
    159     StreamString stream;
    160     if (!m_impl || m_impl(*valobj,stream) == false)
    161         return false;
    162     dest.assign(stream.GetData());
    163     return true;
    164 }
    165 
    166 std::string
    167 CXXFunctionSummaryFormat::GetDescription ()
    168 {
    169     StreamString sstr;
    170     sstr.Printf ("`%s (%p) `%s%s%s%s%s%s%s",      m_description.c_str(),m_impl,
    171                  Cascades() ? "" : " (not cascading)",
    172                  !DoesPrintChildren() ? "" : " (show children)",
    173                  !DoesPrintValue() ? " (hide value)" : "",
    174                  IsOneliner() ? " (one-line printout)" : "",
    175                  SkipsPointers() ? " (skip pointers)" : "",
    176                  SkipsReferences() ? " (skip references)" : "",
    177                  HideNames() ? " (hide member names)" : "");
    178     return sstr.GetString();
    179 }
    180 
    181 #ifndef LLDB_DISABLE_PYTHON
    182 
    183 
    184 ScriptSummaryFormat::ScriptSummaryFormat (const TypeSummaryImpl::Flags& flags,
    185                                           const char * function_name,
    186                                           const char * python_script) :
    187 TypeSummaryImpl(flags),
    188 m_function_name(),
    189 m_python_script(),
    190 m_script_function_sp()
    191 {
    192     if (function_name)
    193         m_function_name.assign(function_name);
    194     if (python_script)
    195         m_python_script.assign(python_script);
    196 }
    197 
    198 bool
    199 ScriptSummaryFormat::FormatObject (ValueObject *valobj,
    200                                    std::string& retval)
    201 {
    202     Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
    203 
    204     if (!valobj)
    205         return false;
    206 
    207     Host::SetCrashDescriptionWithFormat("[Python summary] Name: %s - Function: %s",
    208                                         valobj->GetName().AsCString("unknown"),
    209                                         m_function_name.c_str());
    210 
    211     TargetSP target_sp(valobj->GetTargetSP());
    212 
    213     if (!target_sp)
    214     {
    215         retval.assign("error: no target");
    216         return false;
    217     }
    218 
    219     ScriptInterpreter *script_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
    220 
    221     if (!script_interpreter)
    222     {
    223         retval.assign("error: no ScriptInterpreter");
    224         return false;
    225     }
    226 
    227     return script_interpreter->GetScriptedSummary(m_function_name.c_str(),
    228                                                   valobj->GetSP(),
    229                                                   m_script_function_sp,
    230                                                   retval);
    231 
    232 }
    233 
    234 std::string
    235 ScriptSummaryFormat::GetDescription ()
    236 {
    237     StreamString sstr;
    238     sstr.Printf ("%s%s%s%s%s%s%s\n%s",       Cascades() ? "" : " (not cascading)",
    239                  !DoesPrintChildren() ? "" : " (show children)",
    240                  !DoesPrintValue() ? " (hide value)" : "",
    241                  IsOneliner() ? " (one-line printout)" : "",
    242                  SkipsPointers() ? " (skip pointers)" : "",
    243                  SkipsReferences() ? " (skip references)" : "",
    244                  HideNames() ? " (hide member names)" : "",
    245                  m_python_script.c_str());
    246     return sstr.GetString();
    247 
    248 }
    249 
    250 #endif // #ifndef LLDB_DISABLE_PYTHON
    251