130fdc8d8SChris Lattner //===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
1221dfcd9dSEnrico Granata #include "lldb/API/SBDebugger.h"
1321dfcd9dSEnrico Granata 
144a33d318SGreg Clayton #include "lldb/Core/Debugger.h"
154a33d318SGreg Clayton 
164a33d318SGreg Clayton #include <map>
174a33d318SGreg Clayton 
184becb37eSEnrico Granata #include "clang/AST/DeclCXX.h"
194becb37eSEnrico Granata #include "clang/AST/Type.h"
204becb37eSEnrico Granata 
2130fdc8d8SChris Lattner #include "lldb/lldb-private.h"
2230fdc8d8SChris Lattner #include "lldb/Core/ConnectionFileDescriptor.h"
2330fdc8d8SChris Lattner #include "lldb/Core/InputReader.h"
241f746071SGreg Clayton #include "lldb/Core/Module.h"
25e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h"
267349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h"
2730fdc8d8SChris Lattner #include "lldb/Core/State.h"
285b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h"
29228063cdSJim Ingham #include "lldb/Core/StreamCallback.h"
301b654882SGreg Clayton #include "lldb/Core/StreamString.h"
3130fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
324becb37eSEnrico Granata #include "lldb/Core/ValueObject.h"
336d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
345548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
355548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h"
3621dfcd9dSEnrico Granata #include "lldb/Host/DynamicLibrary.h"
37a3406614SGreg Clayton #include "lldb/Host/Terminal.h"
386611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
3967cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h"
4067cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h"
411f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h"
421f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
431f746071SGreg Clayton #include "lldb/Symbol/Function.h"
441f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
456d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h"
4630fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
4730fdc8d8SChris Lattner #include "lldb/Target/Process.h"
481b654882SGreg Clayton #include "lldb/Target/RegisterContext.h"
491b654882SGreg Clayton #include "lldb/Target/StopInfo.h"
5084a53dfbSEnrico Granata #include "lldb/Target/Target.h"
5130fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
525a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
5330fdc8d8SChris Lattner 
5430fdc8d8SChris Lattner using namespace lldb;
5530fdc8d8SChris Lattner using namespace lldb_private;
5630fdc8d8SChris Lattner 
5730fdc8d8SChris Lattner 
581b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0;
59ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
60ebc1bb27SCaroline Tice 
611b654882SGreg Clayton #pragma mark Static Functions
621b654882SGreg Clayton 
631b654882SGreg Clayton static Mutex &
641b654882SGreg Clayton GetDebuggerListMutex ()
651b654882SGreg Clayton {
661b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
671b654882SGreg Clayton     return g_mutex;
681b654882SGreg Clayton }
691b654882SGreg Clayton 
701b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
711b654882SGreg Clayton 
721b654882SGreg Clayton static DebuggerList &
731b654882SGreg Clayton GetDebuggerList()
741b654882SGreg Clayton {
751b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
761b654882SGreg Clayton     // global init contructors
771b654882SGreg Clayton     static DebuggerList g_list;
781b654882SGreg Clayton     return g_list;
791b654882SGreg Clayton }
80e372b98dSGreg Clayton 
81e372b98dSGreg Clayton OptionEnumValueElement
8267cc0636SGreg Clayton g_show_disassembly_enum_values[] =
83e372b98dSGreg Clayton {
8467cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
8567cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
8667cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
87e372b98dSGreg Clayton     { 0, NULL, NULL }
88e372b98dSGreg Clayton };
89e372b98dSGreg Clayton 
9067cc0636SGreg Clayton OptionEnumValueElement
9167cc0636SGreg Clayton g_language_enumerators[] =
9267cc0636SGreg Clayton {
9367cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
9467cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
9567cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
96a12993c9SGreg Clayton     { 0, NULL, NULL }
9767cc0636SGreg Clayton };
98e372b98dSGreg Clayton 
9967cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
10067cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
10167cc0636SGreg Clayton 
102*0769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
10367cc0636SGreg Clayton     "{, ${frame.pc}}"\
10467cc0636SGreg Clayton     MODULE_WITH_FUNC\
10567cc0636SGreg Clayton     FILE_AND_LINE\
106*0769b2b1SMichael Sartain     "{, name = '${thread.name}'}"\
107*0769b2b1SMichael Sartain     "{, queue = '${thread.queue}'}"\
10867cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
10967cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
11067cc0636SGreg Clayton     "\\n"
11167cc0636SGreg Clayton 
11267cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
11367cc0636SGreg Clayton     MODULE_WITH_FUNC\
11467cc0636SGreg Clayton     FILE_AND_LINE\
11567cc0636SGreg Clayton     "\\n"
11667cc0636SGreg Clayton 
11767cc0636SGreg Clayton 
11867cc0636SGreg Clayton 
119754a9369SGreg Clayton static PropertyDefinition
120754a9369SGreg Clayton g_properties[] =
12167cc0636SGreg Clayton {
12267cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
12367cc0636SGreg Clayton {   "frame-format",             OptionValue::eTypeString , true, 0    , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
12467cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1254c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
12667cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
12767cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
12867cc0636SGreg Clayton {   "stop-disassembly-display", OptionValue::eTypeEnum   , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
12967cc0636SGreg Clayton {   "stop-line-count-after",    OptionValue::eTypeSInt64 , true, 3    , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
13067cc0636SGreg Clayton {   "stop-line-count-before",   OptionValue::eTypeSInt64 , true, 3    , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
13167cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
13267cc0636SGreg Clayton {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
13367cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
134c3ce7f27SMichael Sartain {   "use-color",                OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
135e8cd0c98SGreg Clayton 
13667cc0636SGreg Clayton     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
13767cc0636SGreg Clayton };
13867cc0636SGreg Clayton 
13967cc0636SGreg Clayton enum
14067cc0636SGreg Clayton {
14167cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
14267cc0636SGreg Clayton     ePropertyFrameFormat,
14367cc0636SGreg Clayton     ePropertyNotiftVoid,
14467cc0636SGreg Clayton     ePropertyPrompt,
14567cc0636SGreg Clayton     ePropertyScriptLanguage,
14667cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
14767cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
14867cc0636SGreg Clayton     ePropertyStopLineCountAfter,
14967cc0636SGreg Clayton     ePropertyStopLineCountBefore,
15067cc0636SGreg Clayton     ePropertyTerminalWidth,
15167cc0636SGreg Clayton     ePropertyThreadFormat,
152c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
153c3ce7f27SMichael Sartain     ePropertyUseColor,
15467cc0636SGreg Clayton };
15567cc0636SGreg Clayton 
15667cc0636SGreg Clayton //
15767cc0636SGreg Clayton //const char *
15867cc0636SGreg Clayton //Debugger::GetFrameFormat() const
15967cc0636SGreg Clayton //{
16067cc0636SGreg Clayton //    return m_properties_sp->GetFrameFormat();
16167cc0636SGreg Clayton //}
16267cc0636SGreg Clayton //const char *
16367cc0636SGreg Clayton //Debugger::GetThreadFormat() const
16467cc0636SGreg Clayton //{
16567cc0636SGreg Clayton //    return m_properties_sp->GetThreadFormat();
16667cc0636SGreg Clayton //}
16767cc0636SGreg Clayton //
1684c05410fSGreg Clayton 
1694c05410fSGreg Clayton 
1704c05410fSGreg Clayton Error
1714c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1724c05410fSGreg Clayton                             VarSetOperationType op,
1734c05410fSGreg Clayton                             const char *property_path,
1744c05410fSGreg Clayton                             const char *value)
1754c05410fSGreg Clayton {
17684a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
17784a53dfbSEnrico Granata     TargetSP target_sp;
178397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
17984a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
18084a53dfbSEnrico Granata     {
18184a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
18284a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
18384a53dfbSEnrico Granata     }
1844c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
1854c05410fSGreg Clayton     if (error.Success())
1864c05410fSGreg Clayton     {
18784a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
1884c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
1894c05410fSGreg Clayton         {
1904c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
191c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
192c3ce7f27SMichael Sartain             if (str.length())
193c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
1944c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
1954c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
1964c05410fSGreg Clayton         }
197c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
198c3ce7f27SMichael Sartain         {
199c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
200c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
201c3ce7f27SMichael Sartain         }
202397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
20384a53dfbSEnrico Granata         {
204397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
20584a53dfbSEnrico Granata             {
20684a53dfbSEnrico Granata                 std::list<Error> errors;
2079730339bSEnrico Granata                 StreamString feedback_stream;
2089730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
20984a53dfbSEnrico Granata                 {
21084a53dfbSEnrico Granata                     for (auto error : errors)
21184a53dfbSEnrico Granata                     {
2129730339bSEnrico Granata                         GetErrorStream().Printf("%s\n",error.AsCString());
21384a53dfbSEnrico Granata                     }
2149730339bSEnrico Granata                     if (feedback_stream.GetSize())
2159730339bSEnrico Granata                         GetErrorStream().Printf("%s",feedback_stream.GetData());
21684a53dfbSEnrico Granata                 }
21784a53dfbSEnrico Granata             }
21884a53dfbSEnrico Granata         }
2194c05410fSGreg Clayton     }
2204c05410fSGreg Clayton     return error;
2214c05410fSGreg Clayton }
2224c05410fSGreg Clayton 
22367cc0636SGreg Clayton bool
22467cc0636SGreg Clayton Debugger::GetAutoConfirm () const
22567cc0636SGreg Clayton {
22667cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
227754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
22867cc0636SGreg Clayton }
22967cc0636SGreg Clayton 
23067cc0636SGreg Clayton const char *
23167cc0636SGreg Clayton Debugger::GetFrameFormat() const
23267cc0636SGreg Clayton {
23367cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
234754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
23567cc0636SGreg Clayton }
23667cc0636SGreg Clayton 
23767cc0636SGreg Clayton bool
23867cc0636SGreg Clayton Debugger::GetNotifyVoid () const
23967cc0636SGreg Clayton {
24067cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
241754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
24267cc0636SGreg Clayton }
24367cc0636SGreg Clayton 
24467cc0636SGreg Clayton const char *
24567cc0636SGreg Clayton Debugger::GetPrompt() const
24667cc0636SGreg Clayton {
24767cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
248754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
24967cc0636SGreg Clayton }
25067cc0636SGreg Clayton 
25167cc0636SGreg Clayton void
25267cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
25367cc0636SGreg Clayton {
25467cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
25567cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
25667cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
257c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
258c3ce7f27SMichael Sartain     if (str.length())
259c3ce7f27SMichael Sartain         new_prompt = str.c_str();
26067cc0636SGreg Clayton     EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
26167cc0636SGreg Clayton     GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
26267cc0636SGreg Clayton }
26367cc0636SGreg Clayton 
26467cc0636SGreg Clayton const char *
26567cc0636SGreg Clayton Debugger::GetThreadFormat() const
26667cc0636SGreg Clayton {
26767cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
268754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
26967cc0636SGreg Clayton }
27067cc0636SGreg Clayton 
27167cc0636SGreg Clayton lldb::ScriptLanguage
27267cc0636SGreg Clayton Debugger::GetScriptLanguage() const
27367cc0636SGreg Clayton {
27467cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
275754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
27667cc0636SGreg Clayton }
27767cc0636SGreg Clayton 
27867cc0636SGreg Clayton bool
27967cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
28067cc0636SGreg Clayton {
28167cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
28267cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
28367cc0636SGreg Clayton }
28467cc0636SGreg Clayton 
28567cc0636SGreg Clayton uint32_t
28667cc0636SGreg Clayton Debugger::GetTerminalWidth () const
28767cc0636SGreg Clayton {
28867cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
289754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
29067cc0636SGreg Clayton }
29167cc0636SGreg Clayton 
29267cc0636SGreg Clayton bool
29367cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
29467cc0636SGreg Clayton {
29567cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
29667cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
29767cc0636SGreg Clayton }
29867cc0636SGreg Clayton 
29967cc0636SGreg Clayton bool
30067cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
30167cc0636SGreg Clayton {
30267cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
303754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
30467cc0636SGreg Clayton }
30567cc0636SGreg Clayton 
30667cc0636SGreg Clayton bool
30767cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
30867cc0636SGreg Clayton {
30967cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
31067cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
31167cc0636SGreg Clayton }
31267cc0636SGreg Clayton 
313c3ce7f27SMichael Sartain bool
314c3ce7f27SMichael Sartain Debugger::GetUseColor () const
315c3ce7f27SMichael Sartain {
316c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
317c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
318c3ce7f27SMichael Sartain }
319c3ce7f27SMichael Sartain 
320c3ce7f27SMichael Sartain bool
321c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
322c3ce7f27SMichael Sartain {
323c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
324c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
325c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
326c3ce7f27SMichael Sartain     return ret;
327c3ce7f27SMichael Sartain }
328c3ce7f27SMichael Sartain 
32967cc0636SGreg Clayton uint32_t
33067cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
33167cc0636SGreg Clayton {
33267cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
333754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
33467cc0636SGreg Clayton }
33567cc0636SGreg Clayton 
33667cc0636SGreg Clayton Debugger::StopDisassemblyType
33767cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
33867cc0636SGreg Clayton {
33967cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
340754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
34167cc0636SGreg Clayton }
34267cc0636SGreg Clayton 
34367cc0636SGreg Clayton uint32_t
34467cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
34567cc0636SGreg Clayton {
34667cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
347754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
34867cc0636SGreg Clayton }
349e372b98dSGreg Clayton 
3501b654882SGreg Clayton #pragma mark Debugger
3511b654882SGreg Clayton 
35267cc0636SGreg Clayton //const DebuggerPropertiesSP &
35367cc0636SGreg Clayton //Debugger::GetSettings() const
35467cc0636SGreg Clayton //{
35567cc0636SGreg Clayton //    return m_properties_sp;
35667cc0636SGreg Clayton //}
35767cc0636SGreg Clayton //
35899d0faf2SGreg Clayton 
3592f88aadfSCaroline Tice int
3602f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
3612f88aadfSCaroline Tice {
3622f88aadfSCaroline Tice     return g_shared_debugger_refcount;
3632f88aadfSCaroline Tice }
3642f88aadfSCaroline Tice 
36530fdc8d8SChris Lattner void
36630fdc8d8SChris Lattner Debugger::Initialize ()
36730fdc8d8SChris Lattner {
368c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
369dbe54508SGreg Clayton         lldb_private::Initialize();
37099d0faf2SGreg Clayton }
37130fdc8d8SChris Lattner 
37230fdc8d8SChris Lattner void
37330fdc8d8SChris Lattner Debugger::Terminate ()
37430fdc8d8SChris Lattner {
3756611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
3766611103cSGreg Clayton     {
37730fdc8d8SChris Lattner         g_shared_debugger_refcount--;
37830fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
37930fdc8d8SChris Lattner         {
380dbe54508SGreg Clayton             lldb_private::WillTerminate();
381dbe54508SGreg Clayton             lldb_private::Terminate();
3826760a517SCaroline Tice 
38399d0faf2SGreg Clayton             // Clear our master list of debugger objects
38499d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
38599d0faf2SGreg Clayton             GetDebuggerList().clear();
38630fdc8d8SChris Lattner         }
3876760a517SCaroline Tice     }
3886760a517SCaroline Tice }
38930fdc8d8SChris Lattner 
39020bd37f7SCaroline Tice void
39120bd37f7SCaroline Tice Debugger::SettingsInitialize ()
39220bd37f7SCaroline Tice {
3936920b52bSGreg Clayton     Target::SettingsInitialize ();
39420bd37f7SCaroline Tice }
39520bd37f7SCaroline Tice 
39620bd37f7SCaroline Tice void
39720bd37f7SCaroline Tice Debugger::SettingsTerminate ()
39820bd37f7SCaroline Tice {
3996920b52bSGreg Clayton     Target::SettingsTerminate ();
40020bd37f7SCaroline Tice }
40120bd37f7SCaroline Tice 
40221dfcd9dSEnrico Granata bool
403e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
40421dfcd9dSEnrico Granata {
40521dfcd9dSEnrico Granata     lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec));
406e743c782SEnrico Granata     if (!dynlib_sp || dynlib_sp->IsValid() == false)
407e743c782SEnrico Granata     {
408e743c782SEnrico Granata         if (spec.Exists())
409e743c782SEnrico Granata             error.SetErrorString("this file does not represent a loadable dylib");
410e743c782SEnrico Granata         else
411e743c782SEnrico Granata             error.SetErrorString("no such file");
412e743c782SEnrico Granata         return false;
413e743c782SEnrico Granata     }
41421dfcd9dSEnrico Granata     lldb::DebuggerSP debugger_sp(shared_from_this());
41521dfcd9dSEnrico Granata     lldb::SBDebugger debugger_sb(debugger_sp);
4163cf443ddSMichael Sartain     // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) function.
41721dfcd9dSEnrico Granata     // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays
41821dfcd9dSEnrico Granata     LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
41921dfcd9dSEnrico Granata     if (!init_func)
420e743c782SEnrico Granata     {
421e743c782SEnrico Granata         error.SetErrorString("cannot find the initialization function lldb::PluginInitialize(lldb::SBDebugger)");
42221dfcd9dSEnrico Granata         return false;
423e743c782SEnrico Granata     }
42421dfcd9dSEnrico Granata     if (init_func(debugger_sb))
42521dfcd9dSEnrico Granata     {
42621dfcd9dSEnrico Granata         m_loaded_plugins.push_back(dynlib_sp);
42721dfcd9dSEnrico Granata         return true;
42821dfcd9dSEnrico Granata     }
429e743c782SEnrico Granata     error.SetErrorString("dylib refused to be loaded");
43021dfcd9dSEnrico Granata     return false;
43121dfcd9dSEnrico Granata }
43221dfcd9dSEnrico Granata 
43321dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
43421dfcd9dSEnrico Granata LoadPluginCallback
43521dfcd9dSEnrico Granata (
43621dfcd9dSEnrico Granata  void *baton,
43721dfcd9dSEnrico Granata  FileSpec::FileType file_type,
43821dfcd9dSEnrico Granata  const FileSpec &file_spec
43921dfcd9dSEnrico Granata  )
44021dfcd9dSEnrico Granata {
44121dfcd9dSEnrico Granata     Error error;
44221dfcd9dSEnrico Granata 
44321dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
4443cf443ddSMichael Sartain     static ConstString g_solibext("so");
44521dfcd9dSEnrico Granata 
44621dfcd9dSEnrico Granata     if (!baton)
44721dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
44821dfcd9dSEnrico Granata 
44921dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
45021dfcd9dSEnrico Granata 
45121dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
45221dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
45321dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
45421dfcd9dSEnrico Granata     // file type information.
45521dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
45621dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
45721dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
45821dfcd9dSEnrico Granata     {
45921dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
46021dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
46121dfcd9dSEnrico Granata 
4623cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
4633cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
4643cf443ddSMichael Sartain         {
46521dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
4663cf443ddSMichael Sartain         }
46721dfcd9dSEnrico Granata 
468e743c782SEnrico Granata         Error plugin_load_error;
469e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
47021dfcd9dSEnrico Granata 
47121dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
47221dfcd9dSEnrico Granata     }
47321dfcd9dSEnrico Granata 
47421dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
47521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
47621dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
47721dfcd9dSEnrico Granata     {
47821dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
47921dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
48021dfcd9dSEnrico Granata         // might be enurating a file system that doesn't have correct file type
48121dfcd9dSEnrico Granata         // information.
48221dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
48321dfcd9dSEnrico Granata     }
48421dfcd9dSEnrico Granata 
48521dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
48621dfcd9dSEnrico Granata }
48721dfcd9dSEnrico Granata 
48821dfcd9dSEnrico Granata void
48921dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
49021dfcd9dSEnrico Granata {
49121dfcd9dSEnrico Granata     FileSpec dir_spec;
49221dfcd9dSEnrico Granata     const bool find_directories = true;
49321dfcd9dSEnrico Granata     const bool find_files = true;
49421dfcd9dSEnrico Granata     const bool find_other = true;
49521dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
49621dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
49721dfcd9dSEnrico Granata     {
49821dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
49921dfcd9dSEnrico Granata         {
50021dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
50121dfcd9dSEnrico Granata                                           find_directories,
50221dfcd9dSEnrico Granata                                           find_files,
50321dfcd9dSEnrico Granata                                           find_other,
50421dfcd9dSEnrico Granata                                           LoadPluginCallback,
50521dfcd9dSEnrico Granata                                           this);
50621dfcd9dSEnrico Granata         }
50721dfcd9dSEnrico Granata     }
50821dfcd9dSEnrico Granata 
50921dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
51021dfcd9dSEnrico Granata     {
51121dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
51221dfcd9dSEnrico Granata         {
51321dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
51421dfcd9dSEnrico Granata                                           find_directories,
51521dfcd9dSEnrico Granata                                           find_files,
51621dfcd9dSEnrico Granata                                           find_other,
51721dfcd9dSEnrico Granata                                           LoadPluginCallback,
51821dfcd9dSEnrico Granata                                           this);
51921dfcd9dSEnrico Granata         }
52021dfcd9dSEnrico Granata     }
521e8cd0c98SGreg Clayton 
522e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
52321dfcd9dSEnrico Granata }
52421dfcd9dSEnrico Granata 
5256611103cSGreg Clayton DebuggerSP
526228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5276611103cSGreg Clayton {
528228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
529c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
5306611103cSGreg Clayton     {
5316611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5326611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5336611103cSGreg Clayton     }
53421dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5356611103cSGreg Clayton     return debugger_sp;
5366611103cSGreg Clayton }
5376611103cSGreg Clayton 
538e02657b1SCaroline Tice void
5394d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
540e02657b1SCaroline Tice {
541e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
542e02657b1SCaroline Tice         return;
543e02657b1SCaroline Tice 
5448314c525SJim Ingham     debugger_sp->Clear();
5458314c525SJim Ingham 
546c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
547c15f55e2SGreg Clayton     {
548e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
549e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
550e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
551e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
552e02657b1SCaroline Tice         {
553e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
554e02657b1SCaroline Tice             {
555e02657b1SCaroline Tice                 debugger_list.erase (pos);
556e02657b1SCaroline Tice                 return;
557e02657b1SCaroline Tice             }
558e02657b1SCaroline Tice         }
559e02657b1SCaroline Tice     }
560c15f55e2SGreg Clayton }
561e02657b1SCaroline Tice 
5624d122c40SGreg Clayton DebuggerSP
5633df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5643df9a8dfSCaroline Tice {
5654d122c40SGreg Clayton     DebuggerSP debugger_sp;
5666920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
5676920b52bSGreg Clayton     {
5686920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5696920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5706920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5716920b52bSGreg Clayton 
5726920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5736920b52bSGreg Clayton         {
5746920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
5756920b52bSGreg Clayton             {
5766920b52bSGreg Clayton                 debugger_sp = *pos;
5776920b52bSGreg Clayton                 break;
5786920b52bSGreg Clayton             }
5796920b52bSGreg Clayton         }
5806920b52bSGreg Clayton     }
5813df9a8dfSCaroline Tice     return debugger_sp;
5823df9a8dfSCaroline Tice }
5836611103cSGreg Clayton 
5846611103cSGreg Clayton TargetSP
5856611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
5866611103cSGreg Clayton {
5874d122c40SGreg Clayton     TargetSP target_sp;
588c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
589c15f55e2SGreg Clayton     {
5906611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5916611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5926611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5936611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5946611103cSGreg Clayton         {
5956611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
5966611103cSGreg Clayton             if (target_sp)
5976611103cSGreg Clayton                 break;
5986611103cSGreg Clayton         }
599c15f55e2SGreg Clayton     }
6006611103cSGreg Clayton     return target_sp;
6016611103cSGreg Clayton }
6026611103cSGreg Clayton 
603e4e45924SGreg Clayton TargetSP
604e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
605e4e45924SGreg Clayton {
606e4e45924SGreg Clayton     TargetSP target_sp;
607c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
608c15f55e2SGreg Clayton     {
609e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
610e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
611e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
612e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
613e4e45924SGreg Clayton         {
614e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
615e4e45924SGreg Clayton             if (target_sp)
616e4e45924SGreg Clayton                 break;
617e4e45924SGreg Clayton         }
618c15f55e2SGreg Clayton     }
619e4e45924SGreg Clayton     return target_sp;
620e4e45924SGreg Clayton }
621e4e45924SGreg Clayton 
622228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
623ebc1bb27SCaroline Tice     UserID (g_unique_id++),
62467cc0636SGreg Clayton     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
625d46c87a1SGreg Clayton     m_input_comm("debugger.input"),
62630fdc8d8SChris Lattner     m_input_file (),
62730fdc8d8SChris Lattner     m_output_file (),
62830fdc8d8SChris Lattner     m_error_file (),
629c5917d9aSJim Ingham     m_terminal_state (),
6304bddaeb5SJim Ingham     m_target_list (*this),
631ded470d3SGreg Clayton     m_platform_list (),
63230fdc8d8SChris Lattner     m_listener ("lldb.Debugger"),
6339585fbfcSGreg Clayton     m_source_manager_ap(),
634e37d605eSJim Ingham     m_source_file_cache(),
6356611103cSGreg Clayton     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
636d5a0a01bSCaroline Tice     m_input_reader_stack (),
63767cc0636SGreg Clayton     m_input_reader_data (),
63867cc0636SGreg Clayton     m_instance_name()
63930fdc8d8SChris Lattner {
64067cc0636SGreg Clayton     char instance_cstr[256];
64167cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
64267cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
643228063cdSJim Ingham     if (log_callback)
644228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6456611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
646ded470d3SGreg Clayton     // Always add our default platform to the platform list
647ded470d3SGreg Clayton     PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
648ded470d3SGreg Clayton     assert (default_platform_sp.get());
649ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
65067cc0636SGreg Clayton 
651754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
65267cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
65367cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
65467cc0636SGreg Clayton                                      true,
65567cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
656754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
657754a9369SGreg Clayton     {
658754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
659754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
660754a9369SGreg Clayton                                          true,
661754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
662754a9369SGreg Clayton     }
66367cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
66467cc0636SGreg Clayton     term_width->SetMinimumValue(10);
66567cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
666c3ce7f27SMichael Sartain 
667c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
668c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
669c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
670c3ce7f27SMichael Sartain         SetUseColor (false);
67130fdc8d8SChris Lattner }
67230fdc8d8SChris Lattner 
67330fdc8d8SChris Lattner Debugger::~Debugger ()
67430fdc8d8SChris Lattner {
6758314c525SJim Ingham     Clear();
6768314c525SJim Ingham }
6778314c525SJim Ingham 
6788314c525SJim Ingham void
6798314c525SJim Ingham Debugger::Clear()
6808314c525SJim Ingham {
6813d6086f6SCaroline Tice     CleanUpInputReaders();
6821ed54f50SGreg Clayton     m_listener.Clear();
6836611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
6846611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
6856611103cSGreg Clayton     {
686ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
687ccbc08e6SGreg Clayton         if (target_sp)
688ccbc08e6SGreg Clayton         {
689ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
6906611103cSGreg Clayton             if (process_sp)
6911fd07059SJim Ingham                 process_sp->Finalize();
692ccbc08e6SGreg Clayton             target_sp->Destroy();
6936611103cSGreg Clayton         }
69430fdc8d8SChris Lattner     }
6954bddaeb5SJim Ingham     BroadcasterManager::Clear ();
69630fdc8d8SChris Lattner 
6970d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
6980d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
699c5917d9aSJim Ingham     m_terminal_state.Clear();
7000d69a3a4SGreg Clayton     GetInputFile().Close ();
7010d69a3a4SGreg Clayton     // Now that we have closed m_input_file, we can now tell our input communication
7020d69a3a4SGreg Clayton     // class to close down. Its read thread should quickly exit after we close
7030d69a3a4SGreg Clayton     // the input file handle above.
7040d69a3a4SGreg Clayton     m_input_comm.Clear ();
7058314c525SJim Ingham }
70630fdc8d8SChris Lattner 
70730fdc8d8SChris Lattner bool
708fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
709fc3f027dSGreg Clayton {
710fc3f027dSGreg Clayton     return m_input_comm.GetCloseOnEOF();
711fc3f027dSGreg Clayton }
712fc3f027dSGreg Clayton 
713fc3f027dSGreg Clayton void
714fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
715fc3f027dSGreg Clayton {
716fc3f027dSGreg Clayton     m_input_comm.SetCloseOnEOF(b);
717fc3f027dSGreg Clayton }
718fc3f027dSGreg Clayton 
719fc3f027dSGreg Clayton bool
72030fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
72130fdc8d8SChris Lattner {
7226611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
72330fdc8d8SChris Lattner }
72430fdc8d8SChris Lattner 
72530fdc8d8SChris Lattner void
72630fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
72730fdc8d8SChris Lattner {
7286611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
72930fdc8d8SChris Lattner }
73030fdc8d8SChris Lattner 
73130fdc8d8SChris Lattner 
73230fdc8d8SChris Lattner void
73330fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
73430fdc8d8SChris Lattner {
73551b1e2d2SGreg Clayton     File &in_file = GetInputFile();
73651b1e2d2SGreg Clayton     in_file.SetStream (fh, tranfer_ownership);
73751b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
73851b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
73930fdc8d8SChris Lattner 
74030fdc8d8SChris Lattner     // Disconnect from any old connection if we had one
74130fdc8d8SChris Lattner     m_input_comm.Disconnect ();
74232720b51SGreg Clayton     // Pass false as the second argument to ConnectionFileDescriptor below because
74332720b51SGreg Clayton     // our "in_file" above will already take ownership if requested and we don't
74432720b51SGreg Clayton     // want to objects trying to own and close a file descriptor.
74532720b51SGreg Clayton     m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false));
74630fdc8d8SChris Lattner     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
74730fdc8d8SChris Lattner 
748c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
749c5917d9aSJim Ingham     SaveInputTerminalState ();
750c5917d9aSJim Ingham 
75130fdc8d8SChris Lattner     Error error;
75230fdc8d8SChris Lattner     if (m_input_comm.StartReadThread (&error) == false)
75330fdc8d8SChris Lattner     {
75451b1e2d2SGreg Clayton         File &err_file = GetErrorFile();
75551b1e2d2SGreg Clayton 
75651b1e2d2SGreg Clayton         err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
75730fdc8d8SChris Lattner         exit(1);
75830fdc8d8SChris Lattner     }
75930fdc8d8SChris Lattner }
76030fdc8d8SChris Lattner 
76130fdc8d8SChris Lattner void
76230fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
76330fdc8d8SChris Lattner {
76451b1e2d2SGreg Clayton     File &out_file = GetOutputFile();
76551b1e2d2SGreg Clayton     out_file.SetStream (fh, tranfer_ownership);
76651b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
76751b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7682f88aadfSCaroline Tice 
769b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
770b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
771b588726eSEnrico Granata     const bool can_create = false;
772b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
773b588726eSEnrico Granata     if (script_interpreter)
774b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
77530fdc8d8SChris Lattner }
77630fdc8d8SChris Lattner 
77730fdc8d8SChris Lattner void
77830fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
77930fdc8d8SChris Lattner {
78051b1e2d2SGreg Clayton     File &err_file = GetErrorFile();
78151b1e2d2SGreg Clayton     err_file.SetStream (fh, tranfer_ownership);
78251b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
78351b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
78430fdc8d8SChris Lattner }
78530fdc8d8SChris Lattner 
786c5917d9aSJim Ingham void
787c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
788c5917d9aSJim Ingham {
789c5917d9aSJim Ingham     File &in_file = GetInputFile();
790c5917d9aSJim Ingham     if (in_file.GetDescriptor() != File::kInvalidDescriptor)
791c5917d9aSJim Ingham         m_terminal_state.Save(in_file.GetDescriptor(), true);
792c5917d9aSJim Ingham }
793c5917d9aSJim Ingham 
794c5917d9aSJim Ingham void
795c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
796c5917d9aSJim Ingham {
797c5917d9aSJim Ingham     m_terminal_state.Restore();
798c5917d9aSJim Ingham }
799c5917d9aSJim Ingham 
80030fdc8d8SChris Lattner ExecutionContext
8012976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
80230fdc8d8SChris Lattner {
80330fdc8d8SChris Lattner     ExecutionContext exe_ctx;
804c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
805c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
80630fdc8d8SChris Lattner 
80730fdc8d8SChris Lattner     if (target_sp)
80830fdc8d8SChris Lattner     {
809c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
810c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
811c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
81230fdc8d8SChris Lattner         {
813c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
814c14ee32dSGreg Clayton             if (thread_sp)
81530fdc8d8SChris Lattner             {
816c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
817c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
818c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
819c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
82030fdc8d8SChris Lattner             }
82130fdc8d8SChris Lattner         }
82230fdc8d8SChris Lattner     }
82330fdc8d8SChris Lattner     return exe_ctx;
82430fdc8d8SChris Lattner 
82530fdc8d8SChris Lattner }
82630fdc8d8SChris Lattner 
827b44880caSCaroline Tice InputReaderSP
828b44880caSCaroline Tice Debugger::GetCurrentInputReader ()
829b44880caSCaroline Tice {
830b44880caSCaroline Tice     InputReaderSP reader_sp;
831b44880caSCaroline Tice 
832d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
833b44880caSCaroline Tice     {
834b44880caSCaroline Tice         // Clear any finished readers from the stack
835b44880caSCaroline Tice         while (CheckIfTopInputReaderIsDone()) ;
836b44880caSCaroline Tice 
837d5a0a01bSCaroline Tice         if (!m_input_reader_stack.IsEmpty())
838d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
839b44880caSCaroline Tice     }
840b44880caSCaroline Tice 
841b44880caSCaroline Tice     return reader_sp;
842b44880caSCaroline Tice }
843b44880caSCaroline Tice 
84430fdc8d8SChris Lattner void
84530fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
84630fdc8d8SChris Lattner {
847efed6131SCaroline Tice     if (bytes_len > 0)
84830fdc8d8SChris Lattner         ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
849efed6131SCaroline Tice     else
850efed6131SCaroline Tice         ((Debugger *)baton)->DispatchInputEndOfFile ();
85130fdc8d8SChris Lattner }
85230fdc8d8SChris Lattner 
85330fdc8d8SChris Lattner 
85430fdc8d8SChris Lattner void
85530fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len)
85630fdc8d8SChris Lattner {
857efed6131SCaroline Tice     if (bytes == NULL || bytes_len == 0)
858efed6131SCaroline Tice         return;
85930fdc8d8SChris Lattner 
86030fdc8d8SChris Lattner     WriteToDefaultReader (bytes, bytes_len);
86130fdc8d8SChris Lattner }
86230fdc8d8SChris Lattner 
86330fdc8d8SChris Lattner void
864efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
865efed6131SCaroline Tice {
866efed6131SCaroline Tice     m_input_reader_data.clear();
867efed6131SCaroline Tice 
868b44880caSCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader ());
869efed6131SCaroline Tice     if (reader_sp)
870b44880caSCaroline Tice     {
871efed6131SCaroline Tice         reader_sp->Notify (eInputReaderInterrupt);
872efed6131SCaroline Tice 
873b44880caSCaroline Tice         // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
874efed6131SCaroline Tice         while (CheckIfTopInputReaderIsDone ()) ;
875efed6131SCaroline Tice     }
876efed6131SCaroline Tice }
877efed6131SCaroline Tice 
878efed6131SCaroline Tice void
879efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
880efed6131SCaroline Tice {
881efed6131SCaroline Tice     m_input_reader_data.clear();
882efed6131SCaroline Tice 
883b44880caSCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader ());
884efed6131SCaroline Tice     if (reader_sp)
885b44880caSCaroline Tice     {
886efed6131SCaroline Tice         reader_sp->Notify (eInputReaderEndOfFile);
887efed6131SCaroline Tice 
888b44880caSCaroline Tice         // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
889efed6131SCaroline Tice         while (CheckIfTopInputReaderIsDone ()) ;
890efed6131SCaroline Tice     }
891efed6131SCaroline Tice }
892efed6131SCaroline Tice 
893efed6131SCaroline Tice void
8943d6086f6SCaroline Tice Debugger::CleanUpInputReaders ()
8953d6086f6SCaroline Tice {
8963d6086f6SCaroline Tice     m_input_reader_data.clear();
8973d6086f6SCaroline Tice 
898b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
899d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
9003d6086f6SCaroline Tice     {
901b44880caSCaroline Tice         InputReaderSP reader_sp (GetCurrentInputReader ());
9023d6086f6SCaroline Tice         if (reader_sp)
9033d6086f6SCaroline Tice         {
9043d6086f6SCaroline Tice             reader_sp->Notify (eInputReaderEndOfFile);
9053d6086f6SCaroline Tice             reader_sp->SetIsDone (true);
9063d6086f6SCaroline Tice         }
9073d6086f6SCaroline Tice     }
9083d6086f6SCaroline Tice }
9093d6086f6SCaroline Tice 
9103d6086f6SCaroline Tice void
911969ed3d1SCaroline Tice Debugger::NotifyTopInputReader (InputReaderAction notification)
912969ed3d1SCaroline Tice {
913969ed3d1SCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader());
914969ed3d1SCaroline Tice     if (reader_sp)
915969ed3d1SCaroline Tice 	{
916969ed3d1SCaroline Tice         reader_sp->Notify (notification);
917969ed3d1SCaroline Tice 
918969ed3d1SCaroline Tice         // Flush out any input readers that are done.
919969ed3d1SCaroline Tice         while (CheckIfTopInputReaderIsDone ())
920969ed3d1SCaroline Tice             /* Do nothing. */;
921969ed3d1SCaroline Tice     }
922969ed3d1SCaroline Tice }
923969ed3d1SCaroline Tice 
9249088b068SCaroline Tice bool
9254d122c40SGreg Clayton Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp)
9269088b068SCaroline Tice {
9279088b068SCaroline Tice     InputReaderSP top_reader_sp (GetCurrentInputReader());
9289088b068SCaroline Tice 
929d61c10bcSCaroline Tice     return (reader_sp.get() == top_reader_sp.get());
9309088b068SCaroline Tice }
9319088b068SCaroline Tice 
9329088b068SCaroline Tice 
933969ed3d1SCaroline Tice void
93430fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
93530fdc8d8SChris Lattner {
93630fdc8d8SChris Lattner     if (bytes && bytes_len)
93730fdc8d8SChris Lattner         m_input_reader_data.append (bytes, bytes_len);
93830fdc8d8SChris Lattner 
93930fdc8d8SChris Lattner     if (m_input_reader_data.empty())
94030fdc8d8SChris Lattner         return;
94130fdc8d8SChris Lattner 
942d5a0a01bSCaroline Tice     while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
94330fdc8d8SChris Lattner     {
94430fdc8d8SChris Lattner         // Get the input reader from the top of the stack
945b44880caSCaroline Tice         InputReaderSP reader_sp (GetCurrentInputReader ());
94630fdc8d8SChris Lattner         if (!reader_sp)
94730fdc8d8SChris Lattner             break;
94830fdc8d8SChris Lattner 
949471b31ceSGreg Clayton         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
95030fdc8d8SChris Lattner                                                           m_input_reader_data.size());
95130fdc8d8SChris Lattner         if (bytes_handled)
95230fdc8d8SChris Lattner         {
95330fdc8d8SChris Lattner             m_input_reader_data.erase (0, bytes_handled);
95430fdc8d8SChris Lattner         }
95530fdc8d8SChris Lattner         else
95630fdc8d8SChris Lattner         {
95730fdc8d8SChris Lattner             // No bytes were handled, we might not have reached our
95830fdc8d8SChris Lattner             // granularity, just return and wait for more data
95930fdc8d8SChris Lattner             break;
96030fdc8d8SChris Lattner         }
96130fdc8d8SChris Lattner     }
96230fdc8d8SChris Lattner 
963b44880caSCaroline Tice     // Flush out any input readers that are done.
96430fdc8d8SChris Lattner     while (CheckIfTopInputReaderIsDone ())
96530fdc8d8SChris Lattner         /* Do nothing. */;
96630fdc8d8SChris Lattner 
96730fdc8d8SChris Lattner }
96830fdc8d8SChris Lattner 
96930fdc8d8SChris Lattner void
97030fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp)
97130fdc8d8SChris Lattner {
97230fdc8d8SChris Lattner     if (!reader_sp)
97330fdc8d8SChris Lattner         return;
974b44880caSCaroline Tice 
97530fdc8d8SChris Lattner     // Deactivate the old top reader
976b44880caSCaroline Tice     InputReaderSP top_reader_sp (GetCurrentInputReader ());
977b44880caSCaroline Tice 
97830fdc8d8SChris Lattner     if (top_reader_sp)
97930fdc8d8SChris Lattner         top_reader_sp->Notify (eInputReaderDeactivate);
980b44880caSCaroline Tice 
981d5a0a01bSCaroline Tice     m_input_reader_stack.Push (reader_sp);
98230fdc8d8SChris Lattner     reader_sp->Notify (eInputReaderActivate);
98330fdc8d8SChris Lattner     ActivateInputReader (reader_sp);
98430fdc8d8SChris Lattner }
98530fdc8d8SChris Lattner 
98630fdc8d8SChris Lattner bool
9874d122c40SGreg Clayton Debugger::PopInputReader (const InputReaderSP& pop_reader_sp)
98830fdc8d8SChris Lattner {
98930fdc8d8SChris Lattner     bool result = false;
99030fdc8d8SChris Lattner 
99130fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
99230fdc8d8SChris Lattner     // read on the stack referesh its prompt and if there is one...
993d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
99430fdc8d8SChris Lattner     {
995b44880caSCaroline Tice         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
996d5a0a01bSCaroline Tice         InputReaderSP reader_sp(m_input_reader_stack.Top());
99730fdc8d8SChris Lattner 
99830fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
99930fdc8d8SChris Lattner         {
1000d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
100130fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDeactivate);
100230fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDone);
100330fdc8d8SChris Lattner             result = true;
100430fdc8d8SChris Lattner 
1005d5a0a01bSCaroline Tice             if (!m_input_reader_stack.IsEmpty())
100630fdc8d8SChris Lattner             {
1007d5a0a01bSCaroline Tice                 reader_sp = m_input_reader_stack.Top();
100830fdc8d8SChris Lattner                 if (reader_sp)
100930fdc8d8SChris Lattner                 {
101030fdc8d8SChris Lattner                     ActivateInputReader (reader_sp);
101130fdc8d8SChris Lattner                     reader_sp->Notify (eInputReaderReactivate);
101230fdc8d8SChris Lattner                 }
101330fdc8d8SChris Lattner             }
101430fdc8d8SChris Lattner         }
101530fdc8d8SChris Lattner     }
101630fdc8d8SChris Lattner     return result;
101730fdc8d8SChris Lattner }
101830fdc8d8SChris Lattner 
101930fdc8d8SChris Lattner bool
102030fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone ()
102130fdc8d8SChris Lattner {
102230fdc8d8SChris Lattner     bool result = false;
1023d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
102430fdc8d8SChris Lattner     {
1025b44880caSCaroline Tice         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
1026d5a0a01bSCaroline Tice         InputReaderSP reader_sp(m_input_reader_stack.Top());
102730fdc8d8SChris Lattner 
102830fdc8d8SChris Lattner         if (reader_sp && reader_sp->IsDone())
102930fdc8d8SChris Lattner         {
103030fdc8d8SChris Lattner             result = true;
103130fdc8d8SChris Lattner             PopInputReader (reader_sp);
103230fdc8d8SChris Lattner         }
103330fdc8d8SChris Lattner     }
103430fdc8d8SChris Lattner     return result;
103530fdc8d8SChris Lattner }
103630fdc8d8SChris Lattner 
103730fdc8d8SChris Lattner void
103830fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
103930fdc8d8SChris Lattner {
104051b1e2d2SGreg Clayton     int input_fd = m_input_file.GetFile().GetDescriptor();
104130fdc8d8SChris Lattner 
104251b1e2d2SGreg Clayton     if (input_fd >= 0)
104330fdc8d8SChris Lattner     {
104451b1e2d2SGreg Clayton         Terminal tty(input_fd);
1045a3406614SGreg Clayton 
1046a3406614SGreg Clayton         tty.SetEcho(reader_sp->GetEcho());
104730fdc8d8SChris Lattner 
104830fdc8d8SChris Lattner         switch (reader_sp->GetGranularity())
104930fdc8d8SChris Lattner         {
105030fdc8d8SChris Lattner         case eInputReaderGranularityByte:
105130fdc8d8SChris Lattner         case eInputReaderGranularityWord:
1052a3406614SGreg Clayton             tty.SetCanonical (false);
105330fdc8d8SChris Lattner             break;
105430fdc8d8SChris Lattner 
105530fdc8d8SChris Lattner         case eInputReaderGranularityLine:
105630fdc8d8SChris Lattner         case eInputReaderGranularityAll:
1057a3406614SGreg Clayton             tty.SetCanonical (true);
105830fdc8d8SChris Lattner             break;
105930fdc8d8SChris Lattner 
106030fdc8d8SChris Lattner         default:
106130fdc8d8SChris Lattner             break;
106230fdc8d8SChris Lattner         }
106330fdc8d8SChris Lattner     }
106430fdc8d8SChris Lattner }
10656611103cSGreg Clayton 
10665b52f0c7SJim Ingham StreamSP
10675b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
10685b52f0c7SJim Ingham {
10695b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10705b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
10715b52f0c7SJim Ingham }
10725b52f0c7SJim Ingham 
10735b52f0c7SJim Ingham StreamSP
10745b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
10755b52f0c7SJim Ingham {
10765b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10775b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
10785b52f0c7SJim Ingham }
10795b52f0c7SJim Ingham 
1080c7bece56SGreg Clayton size_t
1081061858ceSEnrico Granata Debugger::GetNumDebuggers()
1082061858ceSEnrico Granata {
1083c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1084c15f55e2SGreg Clayton     {
1085061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1086061858ceSEnrico Granata         return GetDebuggerList().size();
1087061858ceSEnrico Granata     }
1088c15f55e2SGreg Clayton     return 0;
1089c15f55e2SGreg Clayton }
1090061858ceSEnrico Granata 
1091061858ceSEnrico Granata lldb::DebuggerSP
1092c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1093061858ceSEnrico Granata {
1094061858ceSEnrico Granata     DebuggerSP debugger_sp;
1095061858ceSEnrico Granata 
1096c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1097c15f55e2SGreg Clayton     {
1098061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1099061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1100061858ceSEnrico Granata 
1101061858ceSEnrico Granata         if (index < debugger_list.size())
1102061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1103c15f55e2SGreg Clayton     }
1104061858ceSEnrico Granata 
1105061858ceSEnrico Granata     return debugger_sp;
1106061858ceSEnrico Granata }
1107061858ceSEnrico Granata 
1108ebc1bb27SCaroline Tice DebuggerSP
1109ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1110ebc1bb27SCaroline Tice {
11114d122c40SGreg Clayton     DebuggerSP debugger_sp;
1112ebc1bb27SCaroline Tice 
1113c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1114c15f55e2SGreg Clayton     {
1115ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1116ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1117ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1118ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1119ebc1bb27SCaroline Tice         {
1120ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1121ebc1bb27SCaroline Tice             {
1122ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1123ebc1bb27SCaroline Tice                 break;
1124ebc1bb27SCaroline Tice             }
1125ebc1bb27SCaroline Tice         }
1126c15f55e2SGreg Clayton     }
1127ebc1bb27SCaroline Tice     return debugger_sp;
1128ebc1bb27SCaroline Tice }
11293df9a8dfSCaroline Tice 
11301b654882SGreg Clayton static void
11311b654882SGreg Clayton TestPromptFormats (StackFrame *frame)
11321b654882SGreg Clayton {
11331b654882SGreg Clayton     if (frame == NULL)
11341b654882SGreg Clayton         return;
11351b654882SGreg Clayton 
11361b654882SGreg Clayton     StreamString s;
11371b654882SGreg Clayton     const char *prompt_format =
11381b654882SGreg Clayton     "{addr = '${addr}'\n}"
11391b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11401b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11411b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11421b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11431b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11441b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11451b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11461b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11471b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
11481b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
11491b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
11501b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
11511b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
11521b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
11531b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
11541b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
11551b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
11561b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
11571b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
11581b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
11591b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
11601b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
11611b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
11621b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
11631b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
11641b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
11651b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
11661b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1167ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
11681b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
11691b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
11701b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
11711b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
11721b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
11731b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
11741b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
11751b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
11761b654882SGreg Clayton ;
11771b654882SGreg Clayton 
11781b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
11791b654882SGreg Clayton     ExecutionContext exe_ctx;
11800603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1181c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
11821b654882SGreg Clayton     {
11831b654882SGreg Clayton         printf("%s\n", s.GetData());
11841b654882SGreg Clayton     }
11851b654882SGreg Clayton     else
11861b654882SGreg Clayton     {
11871b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
11881b654882SGreg Clayton     }
11891b654882SGreg Clayton }
11901b654882SGreg Clayton 
11919fc1944eSEnrico Granata static bool
11929fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin,
11939fc1944eSEnrico Granata                       const char* var_name_end,
11949fc1944eSEnrico Granata                       const char** var_name_final,
11959fc1944eSEnrico Granata                       const char** percent_position,
11964d122c40SGreg Clayton                       Format* custom_format,
11979fc1944eSEnrico Granata                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
11989fc1944eSEnrico Granata {
11995160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12009fc1944eSEnrico Granata     *percent_position = ::strchr(var_name_begin,'%');
12019fc1944eSEnrico Granata     if (!*percent_position || *percent_position > var_name_end)
1202e992a089SEnrico Granata     {
1203e992a089SEnrico Granata         if (log)
1204d228483dSEnrico Granata             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
12059fc1944eSEnrico Granata         *var_name_final = var_name_end;
1206e992a089SEnrico Granata     }
12079fc1944eSEnrico Granata     else
12089fc1944eSEnrico Granata     {
12099fc1944eSEnrico Granata         *var_name_final = *percent_position;
121036aa5ae6SEnrico Granata         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1211e992a089SEnrico Granata         if (log)
121268ae4117SEnrico Granata             log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
121336aa5ae6SEnrico Granata         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
12149fc1944eSEnrico Granata                                                   true,
12159fc1944eSEnrico Granata                                                   *custom_format) )
12169fc1944eSEnrico Granata         {
1217e992a089SEnrico Granata             if (log)
121868ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
121936aa5ae6SEnrico Granata 
122036aa5ae6SEnrico Granata             switch (format_name.front())
122136aa5ae6SEnrico Granata             {
122236aa5ae6SEnrico Granata                 case '@':             // if this is an @ sign, print ObjC description
122386cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
122436aa5ae6SEnrico Granata                     break;
122536aa5ae6SEnrico Granata                 case 'V': // if this is a V, print the value using the default format
122686cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
122736aa5ae6SEnrico Granata                     break;
122836aa5ae6SEnrico Granata                 case 'L': // if this is an L, print the location of the value
122986cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
123036aa5ae6SEnrico Granata                     break;
123136aa5ae6SEnrico Granata                 case 'S': // if this is an S, print the summary after all
123286cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
123336aa5ae6SEnrico Granata                     break;
123436aa5ae6SEnrico Granata                 case '#': // if this is a '#', print the number of children
123586cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
123636aa5ae6SEnrico Granata                     break;
123736aa5ae6SEnrico Granata                 case 'T': // if this is a 'T', print the type
123886cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
123936aa5ae6SEnrico Granata                     break;
12402c75f11eSEnrico Granata                 case 'N': // if this is a 'N', print the name
12412c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
12422c75f11eSEnrico Granata                     break;
12432c75f11eSEnrico Granata                 case '>': // if this is a '>', print the name
12442c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
12452c75f11eSEnrico Granata                     break;
124636aa5ae6SEnrico Granata                 default:
12475c42d8a8SJim Ingham                     if (log)
124836aa5ae6SEnrico Granata                         log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
124936aa5ae6SEnrico Granata                     break;
125036aa5ae6SEnrico Granata             }
12519fc1944eSEnrico Granata         }
12529fc1944eSEnrico Granata         // a good custom format tells us to print the value using it
12539fc1944eSEnrico Granata         else
1254e992a089SEnrico Granata         {
1255e992a089SEnrico Granata             if (log)
125668ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] will display value for this VO");
125786cc9829SEnrico Granata             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1258e992a089SEnrico Granata         }
12599fc1944eSEnrico Granata     }
1260e992a089SEnrico Granata     if (log)
126168ae4117SEnrico Granata         log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1262e992a089SEnrico Granata                     *custom_format,
1263e992a089SEnrico Granata                     *val_obj_display);
12649fc1944eSEnrico Granata     return true;
12659fc1944eSEnrico Granata }
12669fc1944eSEnrico Granata 
12679fc1944eSEnrico Granata static bool
12689fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin,
12699fc1944eSEnrico Granata                     const char* var_name_end,
12709fc1944eSEnrico Granata                     const char* var_name_final,
12719fc1944eSEnrico Granata                     const char** open_bracket_position,
12729fc1944eSEnrico Granata                     const char** separator_position,
12739fc1944eSEnrico Granata                     const char** close_bracket_position,
12749fc1944eSEnrico Granata                     const char** var_name_final_if_array_range,
12759fc1944eSEnrico Granata                     int64_t* index_lower,
12769fc1944eSEnrico Granata                     int64_t* index_higher)
12779fc1944eSEnrico Granata {
12785160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12799fc1944eSEnrico Granata     *open_bracket_position = ::strchr(var_name_begin,'[');
12809fc1944eSEnrico Granata     if (*open_bracket_position && *open_bracket_position < var_name_final)
12819fc1944eSEnrico Granata     {
12829fc1944eSEnrico Granata         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
12839fc1944eSEnrico Granata         *close_bracket_position = ::strchr(*open_bracket_position,']');
12849fc1944eSEnrico Granata         // as usual, we assume that [] will come before %
12859fc1944eSEnrico Granata         //printf("trying to expand a []\n");
12869fc1944eSEnrico Granata         *var_name_final_if_array_range = *open_bracket_position;
12879fc1944eSEnrico Granata         if (*close_bracket_position - *open_bracket_position == 1)
12889fc1944eSEnrico Granata         {
1289e992a089SEnrico Granata             if (log)
1290d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
12919fc1944eSEnrico Granata             *index_lower = 0;
12929fc1944eSEnrico Granata         }
12939fc1944eSEnrico Granata         else if (*separator_position == NULL || *separator_position > var_name_end)
12949fc1944eSEnrico Granata         {
12959fc1944eSEnrico Granata             char *end = NULL;
12969fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12979fc1944eSEnrico Granata             *index_higher = *index_lower;
1298e992a089SEnrico Granata             if (log)
1299d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
13009fc1944eSEnrico Granata         }
13019fc1944eSEnrico Granata         else if (*close_bracket_position && *close_bracket_position < var_name_end)
13029fc1944eSEnrico Granata         {
13039fc1944eSEnrico Granata             char *end = NULL;
13049fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
13059fc1944eSEnrico Granata             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1306e992a089SEnrico Granata             if (log)
1307d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
13089fc1944eSEnrico Granata         }
13099fc1944eSEnrico Granata         else
1310e992a089SEnrico Granata         {
1311e992a089SEnrico Granata             if (log)
1312d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
13139fc1944eSEnrico Granata             return false;
1314e992a089SEnrico Granata         }
13159fc1944eSEnrico Granata         if (*index_lower > *index_higher && *index_higher > 0)
13169fc1944eSEnrico Granata         {
1317e992a089SEnrico Granata             if (log)
1318d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] swapping indices");
1319c7bece56SGreg Clayton             int64_t temp = *index_lower;
13209fc1944eSEnrico Granata             *index_lower = *index_higher;
13219fc1944eSEnrico Granata             *index_higher = temp;
13229fc1944eSEnrico Granata         }
13239fc1944eSEnrico Granata     }
1324e992a089SEnrico Granata     else if (log)
1325d228483dSEnrico Granata             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
13269fc1944eSEnrico Granata     return true;
13279fc1944eSEnrico Granata }
13289fc1944eSEnrico Granata 
1329*0769b2b1SMichael Sartain template <typename T>
1330*0769b2b1SMichael Sartain static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
1331*0769b2b1SMichael Sartain {
1332*0769b2b1SMichael Sartain     if (script_interpreter)
1333*0769b2b1SMichael Sartain     {
1334*0769b2b1SMichael Sartain         Error script_error;
1335*0769b2b1SMichael Sartain         std::string script_output;
1336*0769b2b1SMichael Sartain 
1337*0769b2b1SMichael Sartain         if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
1338*0769b2b1SMichael Sartain         {
1339*0769b2b1SMichael Sartain             s.Printf("%s", script_output.c_str());
1340*0769b2b1SMichael Sartain             return true;
1341*0769b2b1SMichael Sartain         }
1342*0769b2b1SMichael Sartain         else
1343*0769b2b1SMichael Sartain         {
1344*0769b2b1SMichael Sartain             s.Printf("<error: %s>",script_error.AsCString());
1345*0769b2b1SMichael Sartain         }
1346*0769b2b1SMichael Sartain     }
1347*0769b2b1SMichael Sartain     return false;
1348*0769b2b1SMichael Sartain }
1349*0769b2b1SMichael Sartain 
13509fc1944eSEnrico Granata static ValueObjectSP
1351c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj,
1352c7bece56SGreg Clayton                          size_t index,
13539fc1944eSEnrico Granata                          StackFrame* frame,
1354fc7a7f3bSEnrico Granata                          bool deref_pointer)
13559fc1944eSEnrico Granata {
13565160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1357fc7a7f3bSEnrico Granata     const char* ptr_deref_format = "[%d]";
1358599171adSEnrico Granata     std::string ptr_deref_buffer(10,0);
1359599171adSEnrico Granata     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1360e992a089SEnrico Granata     if (log)
1361599171adSEnrico Granata         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1362fc7a7f3bSEnrico Granata     const char* first_unparsed;
1363fc7a7f3bSEnrico Granata     ValueObject::GetValueForExpressionPathOptions options;
1364fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathEndResultType final_value_type;
1365fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathScanEndReason reason_to_stop;
136686cc9829SEnrico Granata     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1367599171adSEnrico Granata     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1368fc7a7f3bSEnrico Granata                                                           &first_unparsed,
1369fc7a7f3bSEnrico Granata                                                           &reason_to_stop,
1370fc7a7f3bSEnrico Granata                                                           &final_value_type,
1371fc7a7f3bSEnrico Granata                                                           options,
1372fc7a7f3bSEnrico Granata                                                           &what_next);
1373fc7a7f3bSEnrico Granata     if (!item)
1374fc7a7f3bSEnrico Granata     {
1375e992a089SEnrico Granata         if (log)
1376d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1377e992a089SEnrico Granata                " final_value_type %d",
1378fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
1379fc7a7f3bSEnrico Granata     }
13809fc1944eSEnrico Granata     else
13819fc1944eSEnrico Granata     {
1382e992a089SEnrico Granata         if (log)
1383d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1384e992a089SEnrico Granata                " final_value_type %d",
1385fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
13869fc1944eSEnrico Granata     }
13879fc1944eSEnrico Granata     return item;
13889fc1944eSEnrico Granata }
13899fc1944eSEnrico Granata 
1390*0769b2b1SMichael Sartain static inline bool
1391*0769b2b1SMichael Sartain IsToken(const char *var_name_begin, const char *var)
1392*0769b2b1SMichael Sartain {
1393*0769b2b1SMichael Sartain     return (::strncmp (var_name_begin, var, strlen(var)) == 0);
1394*0769b2b1SMichael Sartain }
1395*0769b2b1SMichael Sartain 
1396*0769b2b1SMichael Sartain static bool
1397*0769b2b1SMichael Sartain IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
1398*0769b2b1SMichael Sartain     const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
1399*0769b2b1SMichael Sartain {
1400*0769b2b1SMichael Sartain     int var_len = strlen(var);
1401*0769b2b1SMichael Sartain     if (::strncmp (var_name_begin, var, var_len) == 0)
1402*0769b2b1SMichael Sartain     {
1403*0769b2b1SMichael Sartain         var_name_begin += var_len;
1404*0769b2b1SMichael Sartain         if (*var_name_begin == '}')
1405*0769b2b1SMichael Sartain         {
1406*0769b2b1SMichael Sartain             format = default_format;
1407*0769b2b1SMichael Sartain             return true;
1408*0769b2b1SMichael Sartain         }
1409*0769b2b1SMichael Sartain         else if (*var_name_begin == '%')
1410*0769b2b1SMichael Sartain         {
1411*0769b2b1SMichael Sartain             // Allow format specifiers: x|X|u with optional width specifiers.
1412*0769b2b1SMichael Sartain             //   ${thread.id%x}    ; hex
1413*0769b2b1SMichael Sartain             //   ${thread.id%X}    ; uppercase hex
1414*0769b2b1SMichael Sartain             //   ${thread.id%u}    ; unsigned decimal
1415*0769b2b1SMichael Sartain             //   ${thread.id%8.8X} ; width.precision + specifier
1416*0769b2b1SMichael Sartain             //   ${thread.id%tid}  ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
1417*0769b2b1SMichael Sartain             int dot_count = 0;
1418*0769b2b1SMichael Sartain             const char *specifier = NULL;
1419*0769b2b1SMichael Sartain             int width_precision_length = 0;
1420*0769b2b1SMichael Sartain             const char *width_precision = ++var_name_begin;
1421*0769b2b1SMichael Sartain             while (isdigit(*var_name_begin) || *var_name_begin == '.')
1422*0769b2b1SMichael Sartain             {
1423*0769b2b1SMichael Sartain                 dot_count += (*var_name_begin == '.');
1424*0769b2b1SMichael Sartain                 if (dot_count > 1)
1425*0769b2b1SMichael Sartain                     break;
1426*0769b2b1SMichael Sartain                 var_name_begin++;
1427*0769b2b1SMichael Sartain                 width_precision_length++;
1428*0769b2b1SMichael Sartain             }
1429*0769b2b1SMichael Sartain 
1430*0769b2b1SMichael Sartain             if (IsToken (var_name_begin, "tid}"))
1431*0769b2b1SMichael Sartain             {
1432*0769b2b1SMichael Sartain                 Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
1433*0769b2b1SMichael Sartain                 if (target)
1434*0769b2b1SMichael Sartain                 {
1435*0769b2b1SMichael Sartain                     ArchSpec arch (target->GetArchitecture ());
1436*0769b2b1SMichael Sartain                     llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
1437*0769b2b1SMichael Sartain                     if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
1438*0769b2b1SMichael Sartain                         specifier = PRIu64;
1439*0769b2b1SMichael Sartain                 }
1440*0769b2b1SMichael Sartain                 if (!specifier)
1441*0769b2b1SMichael Sartain                 {
1442*0769b2b1SMichael Sartain                     format = default_format;
1443*0769b2b1SMichael Sartain                     return true;
1444*0769b2b1SMichael Sartain                 }
1445*0769b2b1SMichael Sartain             }
1446*0769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "x}"))
1447*0769b2b1SMichael Sartain                 specifier = PRIx64;
1448*0769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "X}"))
1449*0769b2b1SMichael Sartain                 specifier = PRIX64;
1450*0769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "u}"))
1451*0769b2b1SMichael Sartain                 specifier = PRIu64;
1452*0769b2b1SMichael Sartain 
1453*0769b2b1SMichael Sartain             if (specifier)
1454*0769b2b1SMichael Sartain             {
1455*0769b2b1SMichael Sartain                 format = "%";
1456*0769b2b1SMichael Sartain                 if (width_precision_length)
1457*0769b2b1SMichael Sartain                     format += std::string(width_precision, width_precision_length);
1458*0769b2b1SMichael Sartain                 format += specifier;
1459*0769b2b1SMichael Sartain                 return true;
1460*0769b2b1SMichael Sartain             }
1461*0769b2b1SMichael Sartain         }
1462*0769b2b1SMichael Sartain     }
1463*0769b2b1SMichael Sartain     return false;
1464*0769b2b1SMichael Sartain }
1465*0769b2b1SMichael Sartain 
1466c3ce7f27SMichael Sartain static bool
1467c3ce7f27SMichael Sartain FormatPromptRecurse
14681b654882SGreg Clayton (
14691b654882SGreg Clayton     const char *format,
14701b654882SGreg Clayton     const SymbolContext *sc,
14711b654882SGreg Clayton     const ExecutionContext *exe_ctx,
14721b654882SGreg Clayton     const Address *addr,
14731b654882SGreg Clayton     Stream &s,
14744becb37eSEnrico Granata     const char **end,
1475c482a192SEnrico Granata     ValueObject* valobj
14761b654882SGreg Clayton )
14771b654882SGreg Clayton {
1478c482a192SEnrico Granata     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
14791b654882SGreg Clayton     bool success = true;
14801b654882SGreg Clayton     const char *p;
14815160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1482c3ce7f27SMichael Sartain 
14831b654882SGreg Clayton     for (p = format; *p != '\0'; ++p)
14841b654882SGreg Clayton     {
1485c482a192SEnrico Granata         if (realvalobj)
14864becb37eSEnrico Granata         {
1487c482a192SEnrico Granata             valobj = realvalobj;
1488c482a192SEnrico Granata             realvalobj = NULL;
14894becb37eSEnrico Granata         }
14901b654882SGreg Clayton         size_t non_special_chars = ::strcspn (p, "${}\\");
14911b654882SGreg Clayton         if (non_special_chars > 0)
14921b654882SGreg Clayton         {
14931b654882SGreg Clayton             if (success)
14941b654882SGreg Clayton                 s.Write (p, non_special_chars);
14951b654882SGreg Clayton             p += non_special_chars;
14961b654882SGreg Clayton         }
14971b654882SGreg Clayton 
14981b654882SGreg Clayton         if (*p == '\0')
14991b654882SGreg Clayton         {
15001b654882SGreg Clayton             break;
15011b654882SGreg Clayton         }
15021b654882SGreg Clayton         else if (*p == '{')
15031b654882SGreg Clayton         {
15041b654882SGreg Clayton             // Start a new scope that must have everything it needs if it is to
15051b654882SGreg Clayton             // to make it into the final output stream "s". If you want to make
15061b654882SGreg Clayton             // a format that only prints out the function or symbol name if there
15071b654882SGreg Clayton             // is one in the symbol context you can use:
15081b654882SGreg Clayton             //      "{function =${function.name}}"
15091b654882SGreg Clayton             // The first '{' starts a new scope that end with the matching '}' at
15101b654882SGreg Clayton             // the end of the string. The contents "function =${function.name}"
15111b654882SGreg Clayton             // will then be evaluated and only be output if there is a function
15121b654882SGreg Clayton             // or symbol with a valid name.
15131b654882SGreg Clayton             StreamString sub_strm;
15141b654882SGreg Clayton 
15151b654882SGreg Clayton             ++p;  // Skip the '{'
15161b654882SGreg Clayton 
1517c3ce7f27SMichael Sartain             if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
15181b654882SGreg Clayton             {
15191b654882SGreg Clayton                 // The stream had all it needed
15201b654882SGreg Clayton                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
15211b654882SGreg Clayton             }
15221b654882SGreg Clayton             if (*p != '}')
15231b654882SGreg Clayton             {
15241b654882SGreg Clayton                 success = false;
15251b654882SGreg Clayton                 break;
15261b654882SGreg Clayton             }
15271b654882SGreg Clayton         }
15281b654882SGreg Clayton         else if (*p == '}')
15291b654882SGreg Clayton         {
15301b654882SGreg Clayton             // End of a enclosing scope
15311b654882SGreg Clayton             break;
15321b654882SGreg Clayton         }
15331b654882SGreg Clayton         else if (*p == '$')
15341b654882SGreg Clayton         {
15351b654882SGreg Clayton             // We have a prompt variable to print
15361b654882SGreg Clayton             ++p;
15371b654882SGreg Clayton             if (*p == '{')
15381b654882SGreg Clayton             {
15391b654882SGreg Clayton                 ++p;
15401b654882SGreg Clayton                 const char *var_name_begin = p;
15411b654882SGreg Clayton                 const char *var_name_end = ::strchr (p, '}');
15421b654882SGreg Clayton 
15431b654882SGreg Clayton                 if (var_name_end && var_name_begin < var_name_end)
15441b654882SGreg Clayton                 {
15451b654882SGreg Clayton                     // if we have already failed to parse, skip this variable
15461b654882SGreg Clayton                     if (success)
15471b654882SGreg Clayton                     {
15481b654882SGreg Clayton                         const char *cstr = NULL;
1549*0769b2b1SMichael Sartain                         std::string token_format;
15501b654882SGreg Clayton                         Address format_addr;
15511b654882SGreg Clayton                         bool calculate_format_addr_function_offset = false;
15521b654882SGreg Clayton                         // Set reg_kind and reg_num to invalid values
15531b654882SGreg Clayton                         RegisterKind reg_kind = kNumRegisterKinds;
15541b654882SGreg Clayton                         uint32_t reg_num = LLDB_INVALID_REGNUM;
15551b654882SGreg Clayton                         FileSpec format_file_spec;
1556e0d378b3SGreg Clayton                         const RegisterInfo *reg_info = NULL;
15571b654882SGreg Clayton                         RegisterContext *reg_ctx = NULL;
15589fc1944eSEnrico Granata                         bool do_deref_pointer = false;
155986cc9829SEnrico Granata                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
156086cc9829SEnrico Granata                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
15611b654882SGreg Clayton 
15621b654882SGreg Clayton                         // Each variable must set success to true below...
15631b654882SGreg Clayton                         bool var_success = false;
15641b654882SGreg Clayton                         switch (var_name_begin[0])
15651b654882SGreg Clayton                         {
15664becb37eSEnrico Granata                         case '*':
15676f3533fbSEnrico Granata                         case 'v':
15686f3533fbSEnrico Granata                         case 's':
15694becb37eSEnrico Granata                             {
1570c482a192SEnrico Granata                                 if (!valobj)
157134132754SGreg Clayton                                     break;
15726f3533fbSEnrico Granata 
1573c3e320a7SEnrico Granata                                 if (log)
1574d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1575c3e320a7SEnrico Granata 
15766f3533fbSEnrico Granata                                 // check for *var and *svar
15776f3533fbSEnrico Granata                                 if (*var_name_begin == '*')
15786f3533fbSEnrico Granata                                 {
15799fc1944eSEnrico Granata                                     do_deref_pointer = true;
15809fc1944eSEnrico Granata                                     var_name_begin++;
1581c3e320a7SEnrico Granata                                     if (log)
158268ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
158368ae4117SEnrico Granata                                 }
1584c3e320a7SEnrico Granata 
15856f3533fbSEnrico Granata                                 if (*var_name_begin == 's')
15864becb37eSEnrico Granata                                 {
1587c5bc412cSEnrico Granata                                     if (!valobj->IsSynthetic())
158886cc9829SEnrico Granata                                         valobj = valobj->GetSyntheticValue().get();
158986cc9829SEnrico Granata                                     if (!valobj)
159086cc9829SEnrico Granata                                         break;
15916f3533fbSEnrico Granata                                     var_name_begin++;
1592c3e320a7SEnrico Granata                                     if (log)
159368ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
159468ae4117SEnrico Granata                                 }
1595c3e320a7SEnrico Granata 
15966f3533fbSEnrico Granata                                 // should be a 'v' by now
15976f3533fbSEnrico Granata                                 if (*var_name_begin != 'v')
15986f3533fbSEnrico Granata                                     break;
15996f3533fbSEnrico Granata 
1600c3e320a7SEnrico Granata                                 if (log)
160168ae4117SEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
1602c3e320a7SEnrico Granata 
1603fc7a7f3bSEnrico Granata                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
160486cc9829SEnrico Granata                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1605fc7a7f3bSEnrico Granata                                 ValueObject::GetValueForExpressionPathOptions options;
16068c9d3560SEnrico Granata                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
160786cc9829SEnrico Granata                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
160834132754SGreg Clayton                                 ValueObject* target = NULL;
16094d122c40SGreg Clayton                                 Format custom_format = eFormatInvalid;
161034132754SGreg Clayton                                 const char* var_name_final = NULL;
16119fc1944eSEnrico Granata                                 const char* var_name_final_if_array_range = NULL;
161234132754SGreg Clayton                                 const char* close_bracket_position = NULL;
161334132754SGreg Clayton                                 int64_t index_lower = -1;
161434132754SGreg Clayton                                 int64_t index_higher = -1;
16159fc1944eSEnrico Granata                                 bool is_array_range = false;
1616fc7a7f3bSEnrico Granata                                 const char* first_unparsed;
161785933ed4SEnrico Granata                                 bool was_plain_var = false;
161885933ed4SEnrico Granata                                 bool was_var_format = false;
1619a777dc2aSEnrico Granata                                 bool was_var_indexed = false;
1620fc7a7f3bSEnrico Granata 
1621c482a192SEnrico Granata                                 if (!valobj) break;
1622c482a192SEnrico Granata                                 // simplest case ${var}, just print valobj's value
1623*0769b2b1SMichael Sartain                                 if (IsToken (var_name_begin, "var}"))
16240a3958e0SEnrico Granata                                 {
162585933ed4SEnrico Granata                                     was_plain_var = true;
1626c482a192SEnrico Granata                                     target = valobj;
162786cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
16280a3958e0SEnrico Granata                                 }
1629*0769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin,"var%"))
16309fc1944eSEnrico Granata                                 {
163185933ed4SEnrico Granata                                     was_var_format = true;
16329fc1944eSEnrico Granata                                     // this is a variable with some custom format applied to it
16339fc1944eSEnrico Granata                                     const char* percent_position;
1634c482a192SEnrico Granata                                     target = valobj;
163586cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
16369fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
16379fc1944eSEnrico Granata                                                           var_name_end,
16389fc1944eSEnrico Granata                                                           &var_name_final,
16399fc1944eSEnrico Granata                                                           &percent_position,
16409fc1944eSEnrico Granata                                                           &custom_format,
16419fc1944eSEnrico Granata                                                           &val_obj_display);
16420a3958e0SEnrico Granata                                 }
16439fc1944eSEnrico Granata                                     // this is ${var.something} or multiple .something nested
1644*0769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin, "var"))
16459fc1944eSEnrico Granata                                 {
1646*0769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "var["))
1647a777dc2aSEnrico Granata                                         was_var_indexed = true;
16489fc1944eSEnrico Granata                                     const char* percent_position;
16499fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
16509fc1944eSEnrico Granata                                                           var_name_end,
16519fc1944eSEnrico Granata                                                           &var_name_final,
16529fc1944eSEnrico Granata                                                           &percent_position,
16539fc1944eSEnrico Granata                                                           &custom_format,
16549fc1944eSEnrico Granata                                                           &val_obj_display);
16559fc1944eSEnrico Granata 
16569fc1944eSEnrico Granata                                     const char* open_bracket_position;
16579fc1944eSEnrico Granata                                     const char* separator_position;
16589fc1944eSEnrico Granata                                     ScanBracketedRange (var_name_begin,
16599fc1944eSEnrico Granata                                                         var_name_end,
16609fc1944eSEnrico Granata                                                         var_name_final,
16619fc1944eSEnrico Granata                                                         &open_bracket_position,
16629fc1944eSEnrico Granata                                                         &separator_position,
16639fc1944eSEnrico Granata                                                         &close_bracket_position,
16649fc1944eSEnrico Granata                                                         &var_name_final_if_array_range,
16659fc1944eSEnrico Granata                                                         &index_lower,
16669fc1944eSEnrico Granata                                                         &index_higher);
16679fc1944eSEnrico Granata 
16689fc1944eSEnrico Granata                                     Error error;
16699fc1944eSEnrico Granata 
1670599171adSEnrico Granata                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1671599171adSEnrico Granata                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1672fc7a7f3bSEnrico Granata 
1673e992a089SEnrico Granata                                     if (log)
1674599171adSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1675fc7a7f3bSEnrico Granata 
1676599171adSEnrico Granata                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1677fc7a7f3bSEnrico Granata                                                                              &first_unparsed,
1678fc7a7f3bSEnrico Granata                                                                              &reason_to_stop,
1679fc7a7f3bSEnrico Granata                                                                              &final_value_type,
1680fc7a7f3bSEnrico Granata                                                                              options,
1681fc7a7f3bSEnrico Granata                                                                              &what_next).get();
1682fc7a7f3bSEnrico Granata 
1683fc7a7f3bSEnrico Granata                                     if (!target)
16849fc1944eSEnrico Granata                                     {
1685e992a089SEnrico Granata                                         if (log)
1686d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1687e992a089SEnrico Granata                                                " final_value_type %d",
1688fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1689fc7a7f3bSEnrico Granata                                         break;
16900a3958e0SEnrico Granata                                     }
1691a7187d00SEnrico Granata                                     else
1692fc7a7f3bSEnrico Granata                                     {
1693e992a089SEnrico Granata                                         if (log)
1694d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1695e992a089SEnrico Granata                                                " final_value_type %d",
1696fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1697a7187d00SEnrico Granata                                     }
16980a3958e0SEnrico Granata                                 }
16990a3958e0SEnrico Granata                                 else
17000a3958e0SEnrico Granata                                     break;
17019fc1944eSEnrico Granata 
170286cc9829SEnrico Granata                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
170386cc9829SEnrico Granata                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1704fc7a7f3bSEnrico Granata 
170586cc9829SEnrico Granata                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1706fc7a7f3bSEnrico Granata 
1707a7187d00SEnrico Granata                                 if (do_deref_pointer && !is_array_range)
17080a3958e0SEnrico Granata                                 {
17099fc1944eSEnrico Granata                                     // I have not deref-ed yet, let's do it
17109fc1944eSEnrico Granata                                     // this happens when we are not going through GetValueForVariableExpressionPath
17119fc1944eSEnrico Granata                                     // to get to the target ValueObject
17129fc1944eSEnrico Granata                                     Error error;
17139fc1944eSEnrico Granata                                     target = target->Dereference(error).get();
1714dc940730SEnrico Granata                                     if (error.Fail())
1715dc940730SEnrico Granata                                     {
1716dc940730SEnrico Granata                                         if (log)
1717d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1718dc940730SEnrico Granata                                         break;
1719dc940730SEnrico Granata                                     }
17209fc1944eSEnrico Granata                                     do_deref_pointer = false;
17210a3958e0SEnrico Granata                                 }
17220a3958e0SEnrico Granata 
1723a777dc2aSEnrico Granata                                 // <rdar://problem/11338654>
1724a777dc2aSEnrico Granata                                 // we do not want to use the summary for a bitfield of type T:n
1725a777dc2aSEnrico Granata                                 // if we were originally dealing with just a T - that would get
1726a777dc2aSEnrico Granata                                 // us into an endless recursion
1727a777dc2aSEnrico Granata                                 if (target->IsBitfield() && was_var_indexed)
1728a777dc2aSEnrico Granata                                 {
1729a777dc2aSEnrico Granata                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1730a777dc2aSEnrico Granata                                     StreamString bitfield_name;
1731a777dc2aSEnrico Granata                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1732a777dc2aSEnrico Granata                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1733a777dc2aSEnrico Granata                                     if (!DataVisualization::GetSummaryForType(type_sp))
1734a777dc2aSEnrico Granata                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1735a777dc2aSEnrico Granata                                 }
1736a777dc2aSEnrico Granata 
173785933ed4SEnrico Granata                                 // TODO use flags for these
173857ee3067SGreg Clayton                                 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
173957ee3067SGreg Clayton                                 bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0;
174057ee3067SGreg Clayton                                 bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0;
174157ee3067SGreg Clayton                                 bool is_aggregate = target->GetClangType().IsAggregateType();
1742f4efecd9SEnrico Granata 
174386cc9829SEnrico Granata                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1744f4efecd9SEnrico Granata                                 {
174585933ed4SEnrico Granata                                     StreamString str_temp;
1746e992a089SEnrico Granata                                     if (log)
1747d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1748d64d0bc0SEnrico Granata 
17495088c486SGreg Clayton                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1750d64d0bc0SEnrico Granata                                     {
1751f4efecd9SEnrico Granata                                         // try to use the special cases
175285933ed4SEnrico Granata                                         var_success = target->DumpPrintableRepresentation(str_temp,
175385933ed4SEnrico Granata                                                                                           val_obj_display,
175485933ed4SEnrico Granata                                                                                           custom_format);
1755e992a089SEnrico Granata                                         if (log)
1756d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1757d64d0bc0SEnrico Granata 
1758d64d0bc0SEnrico Granata                                         // should not happen
17595088c486SGreg Clayton                                         if (var_success)
176085933ed4SEnrico Granata                                             s << str_temp.GetData();
1761d64d0bc0SEnrico Granata                                         var_success = true;
1762d64d0bc0SEnrico Granata                                         break;
1763d64d0bc0SEnrico Granata                                     }
1764d64d0bc0SEnrico Granata                                     else
1765d64d0bc0SEnrico Granata                                     {
176688da35f8SEnrico Granata                                         if (was_plain_var) // if ${var}
1767d64d0bc0SEnrico Granata                                         {
1768d64d0bc0SEnrico Granata                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1769d64d0bc0SEnrico Granata                                         }
177088da35f8SEnrico Granata                                         else if (is_pointer) // if pointer, value is the address stored
177188da35f8SEnrico Granata                                         {
177223f59509SGreg Clayton                                             target->DumpPrintableRepresentation (s,
177388da35f8SEnrico Granata                                                                                  val_obj_display,
177486cc9829SEnrico Granata                                                                                  custom_format,
177586cc9829SEnrico Granata                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
177688da35f8SEnrico Granata                                         }
1777d64d0bc0SEnrico Granata                                         var_success = true;
1778d64d0bc0SEnrico Granata                                         break;
1779d64d0bc0SEnrico Granata                                     }
1780d64d0bc0SEnrico Granata                                 }
1781d64d0bc0SEnrico Granata 
1782d64d0bc0SEnrico Granata                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1783d64d0bc0SEnrico Granata                                 // type @ location message
1784d64d0bc0SEnrico Granata                                 if (is_aggregate && was_plain_var)
1785d64d0bc0SEnrico Granata                                 {
1786d64d0bc0SEnrico Granata                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1787d64d0bc0SEnrico Granata                                     var_success = true;
178885933ed4SEnrico Granata                                     break;
178985933ed4SEnrico Granata                                 }
179085933ed4SEnrico Granata 
1791d64d0bc0SEnrico Granata                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
179286cc9829SEnrico Granata                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
179385933ed4SEnrico Granata                                 {
179485933ed4SEnrico Granata                                     s << "<invalid use of aggregate type>";
179585933ed4SEnrico Granata                                     var_success = true;
1796f4efecd9SEnrico Granata                                     break;
1797f4efecd9SEnrico Granata                                 }
1798f4efecd9SEnrico Granata 
17999fc1944eSEnrico Granata                                 if (!is_array_range)
1800e992a089SEnrico Granata                                 {
1801e992a089SEnrico Granata                                     if (log)
1802d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
18039fc1944eSEnrico Granata                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1804e992a089SEnrico Granata                                 }
18059fc1944eSEnrico Granata                                 else
18069fc1944eSEnrico Granata                                 {
1807e992a089SEnrico Granata                                     if (log)
1808d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
18099fc1944eSEnrico Granata                                     if (!is_array && !is_pointer)
18109fc1944eSEnrico Granata                                         break;
1811e992a089SEnrico Granata                                     if (log)
1812d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1813fc7a7f3bSEnrico Granata                                     const char* special_directions = NULL;
1814fc7a7f3bSEnrico Granata                                     StreamString special_directions_writer;
18150a3958e0SEnrico Granata                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
18160a3958e0SEnrico Granata                                     {
1817fc7a7f3bSEnrico Granata                                         ConstString additional_data;
1818fc7a7f3bSEnrico Granata                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1819fc7a7f3bSEnrico Granata                                         special_directions_writer.Printf("${%svar%s}",
1820fc7a7f3bSEnrico Granata                                                                          do_deref_pointer ? "*" : "",
1821fc7a7f3bSEnrico Granata                                                                          additional_data.GetCString());
1822fc7a7f3bSEnrico Granata                                         special_directions = special_directions_writer.GetData();
18230a3958e0SEnrico Granata                                     }
18240a3958e0SEnrico Granata 
18250a3958e0SEnrico Granata                                     // let us display items index_lower thru index_higher of this array
18260a3958e0SEnrico Granata                                     s.PutChar('[');
18270a3958e0SEnrico Granata                                     var_success = true;
18280a3958e0SEnrico Granata 
18299fc1944eSEnrico Granata                                     if (index_higher < 0)
1830c482a192SEnrico Granata                                         index_higher = valobj->GetNumChildren() - 1;
18310a3958e0SEnrico Granata 
1832cc4d0146SGreg Clayton                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
183322c55d18SEnrico Granata 
18340a3958e0SEnrico Granata                                     for (;index_lower<=index_higher;index_lower++)
18350a3958e0SEnrico Granata                                     {
1836fc7a7f3bSEnrico Granata                                         ValueObject* item = ExpandIndexedExpression (target,
18379fc1944eSEnrico Granata                                                                                      index_lower,
1838c14ee32dSGreg Clayton                                                                                      exe_ctx->GetFramePtr(),
1839fc7a7f3bSEnrico Granata                                                                                      false).get();
18400a3958e0SEnrico Granata 
1841fc7a7f3bSEnrico Granata                                         if (!item)
1842fc7a7f3bSEnrico Granata                                         {
1843e992a089SEnrico Granata                                             if (log)
1844d01b2953SDaniel Malea                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1845fc7a7f3bSEnrico Granata                                         }
1846fc7a7f3bSEnrico Granata                                         else
1847fc7a7f3bSEnrico Granata                                         {
1848e992a089SEnrico Granata                                             if (log)
1849d228483dSEnrico Granata                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1850fc7a7f3bSEnrico Granata                                         }
1851fc7a7f3bSEnrico Granata 
18520a3958e0SEnrico Granata                                         if (!special_directions)
18539fc1944eSEnrico Granata                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
18540a3958e0SEnrico Granata                                         else
1855c3ce7f27SMichael Sartain                                             var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item);
18560a3958e0SEnrico Granata 
185722c55d18SEnrico Granata                                         if (--max_num_children == 0)
185822c55d18SEnrico Granata                                         {
185922c55d18SEnrico Granata                                             s.PutCString(", ...");
186022c55d18SEnrico Granata                                             break;
186122c55d18SEnrico Granata                                         }
186222c55d18SEnrico Granata 
18630a3958e0SEnrico Granata                                         if (index_lower < index_higher)
18640a3958e0SEnrico Granata                                             s.PutChar(',');
18650a3958e0SEnrico Granata                                     }
18660a3958e0SEnrico Granata                                     s.PutChar(']');
18674becb37eSEnrico Granata                                 }
18684becb37eSEnrico Granata                             }
186934132754SGreg Clayton                             break;
18701b654882SGreg Clayton                         case 'a':
1871*0769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "addr}"))
18721b654882SGreg Clayton                             {
18731b654882SGreg Clayton                                 if (addr && addr->IsValid())
18741b654882SGreg Clayton                                 {
18751b654882SGreg Clayton                                     var_success = true;
18761b654882SGreg Clayton                                     format_addr = *addr;
18771b654882SGreg Clayton                                 }
18781b654882SGreg Clayton                             }
18791b654882SGreg Clayton                             break;
18801b654882SGreg Clayton 
18811b654882SGreg Clayton                         case 'p':
1882*0769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "process."))
18831b654882SGreg Clayton                             {
1884c14ee32dSGreg Clayton                                 if (exe_ctx)
1885c14ee32dSGreg Clayton                                 {
1886c14ee32dSGreg Clayton                                     Process *process = exe_ctx->GetProcessPtr();
1887c14ee32dSGreg Clayton                                     if (process)
18881b654882SGreg Clayton                                     {
18891b654882SGreg Clayton                                         var_name_begin += ::strlen ("process.");
1890*0769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
18911b654882SGreg Clayton                                         {
1892*0769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), process->GetID());
18931b654882SGreg Clayton                                             var_success = true;
18941b654882SGreg Clayton                                         }
1895*0769b2b1SMichael Sartain                                         else if ((IsToken (var_name_begin, "name}")) ||
1896*0769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.basename}")) ||
1897*0769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.fullpath}")))
18981b654882SGreg Clayton                                         {
1899c14ee32dSGreg Clayton                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1900aa149cbdSGreg Clayton                                             if (exe_module)
19011b654882SGreg Clayton                                             {
19021b654882SGreg Clayton                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
19031b654882SGreg Clayton                                                 {
1904aa149cbdSGreg Clayton                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
19051b654882SGreg Clayton                                                     var_success = format_file_spec;
19061b654882SGreg Clayton                                                 }
19071b654882SGreg Clayton                                                 else
19081b654882SGreg Clayton                                                 {
1909aa149cbdSGreg Clayton                                                     format_file_spec = exe_module->GetFileSpec();
19101b654882SGreg Clayton                                                     var_success = format_file_spec;
19111b654882SGreg Clayton                                                 }
19121b654882SGreg Clayton                                             }
19131b654882SGreg Clayton                                         }
1914*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
1915aad8e480SEnrico Granata                                         {
1916aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
1917aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
1918aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1919*0769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
1920aad8e480SEnrico Granata                                                 var_success = true;
1921aad8e480SEnrico Granata                                         }
19221b654882SGreg Clayton                                     }
19231b654882SGreg Clayton                                 }
1924c14ee32dSGreg Clayton                             }
19251b654882SGreg Clayton                             break;
19261b654882SGreg Clayton 
19271b654882SGreg Clayton                         case 't':
1928*0769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "thread."))
19291b654882SGreg Clayton                             {
1930c14ee32dSGreg Clayton                                 if (exe_ctx)
1931c14ee32dSGreg Clayton                                 {
1932c14ee32dSGreg Clayton                                     Thread *thread = exe_ctx->GetThreadPtr();
1933c14ee32dSGreg Clayton                                     if (thread)
19341b654882SGreg Clayton                                     {
19351b654882SGreg Clayton                                         var_name_begin += ::strlen ("thread.");
1936*0769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
19371b654882SGreg Clayton                                         {
1938*0769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetID());
19391b654882SGreg Clayton                                             var_success = true;
19401b654882SGreg Clayton                                         }
1941*0769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
1942160c9d81SGreg Clayton                                         {
1943*0769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetProtocolID());
1944160c9d81SGreg Clayton                                             var_success = true;
1945160c9d81SGreg Clayton                                         }
1946*0769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
19471b654882SGreg Clayton                                         {
1948*0769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
19491b654882SGreg Clayton                                             var_success = true;
19501b654882SGreg Clayton                                         }
1951*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "name}"))
19521b654882SGreg Clayton                                         {
1953c14ee32dSGreg Clayton                                             cstr = thread->GetName();
19541b654882SGreg Clayton                                             var_success = cstr && cstr[0];
19551b654882SGreg Clayton                                             if (var_success)
19561b654882SGreg Clayton                                                 s.PutCString(cstr);
19571b654882SGreg Clayton                                         }
1958*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "queue}"))
19591b654882SGreg Clayton                                         {
1960c14ee32dSGreg Clayton                                             cstr = thread->GetQueueName();
19611b654882SGreg Clayton                                             var_success = cstr && cstr[0];
19621b654882SGreg Clayton                                             if (var_success)
19631b654882SGreg Clayton                                                 s.PutCString(cstr);
19641b654882SGreg Clayton                                         }
1965*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "stop-reason}"))
19661b654882SGreg Clayton                                         {
1967c14ee32dSGreg Clayton                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
19685d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
19691b654882SGreg Clayton                                             {
1970b15bfc75SJim Ingham                                                 cstr = stop_info_sp->GetDescription();
19711b654882SGreg Clayton                                                 if (cstr && cstr[0])
19721b654882SGreg Clayton                                                 {
19731b654882SGreg Clayton                                                     s.PutCString(cstr);
19741b654882SGreg Clayton                                                     var_success = true;
19751b654882SGreg Clayton                                                 }
19761b654882SGreg Clayton                                             }
19771b654882SGreg Clayton                                         }
1978*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "return-value}"))
197973ca05a2SJim Ingham                                         {
198073ca05a2SJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
19815d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
198273ca05a2SJim Ingham                                             {
198373ca05a2SJim Ingham                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
198473ca05a2SJim Ingham                                                 if (return_valobj_sp)
198573ca05a2SJim Ingham                                                 {
19869fb5ab55SEnrico Granata                                                     ValueObject::DumpValueObject (s, return_valobj_sp.get());
198773ca05a2SJim Ingham                                                     var_success = true;
198873ca05a2SJim Ingham                                                 }
198973ca05a2SJim Ingham                                             }
199073ca05a2SJim Ingham                                         }
1991*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
1992aad8e480SEnrico Granata                                         {
1993aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
1994aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
1995aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1996*0769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
1997aad8e480SEnrico Granata                                                 var_success = true;
1998aad8e480SEnrico Granata                                         }
1999aad8e480SEnrico Granata                                     }
2000aad8e480SEnrico Granata                                 }
200173ca05a2SJim Ingham                             }
2002*0769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "target."))
20031b654882SGreg Clayton                             {
200467cc0636SGreg Clayton                                 // TODO: hookup properties
200567cc0636SGreg Clayton //                                if (!target_properties_sp)
200667cc0636SGreg Clayton //                                {
200767cc0636SGreg Clayton //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
200867cc0636SGreg Clayton //                                    if (target)
200967cc0636SGreg Clayton //                                        target_properties_sp = target->GetProperties();
201067cc0636SGreg Clayton //                                }
201167cc0636SGreg Clayton //
201267cc0636SGreg Clayton //                                if (target_properties_sp)
201367cc0636SGreg Clayton //                                {
201467cc0636SGreg Clayton //                                    var_name_begin += ::strlen ("target.");
201567cc0636SGreg Clayton //                                    const char *end_property = strchr(var_name_begin, '}');
201667cc0636SGreg Clayton //                                    if (end_property)
201767cc0636SGreg Clayton //                                    {
201867cc0636SGreg Clayton //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
201967cc0636SGreg Clayton //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
202067cc0636SGreg Clayton //                                        if (!property_value.empty())
202167cc0636SGreg Clayton //                                        {
202267cc0636SGreg Clayton //                                            s.PutCString (property_value.c_str());
202367cc0636SGreg Clayton //                                            var_success = true;
202467cc0636SGreg Clayton //                                        }
202567cc0636SGreg Clayton //                                    }
202667cc0636SGreg Clayton //                                }
20270603aa9dSGreg Clayton                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
20280603aa9dSGreg Clayton                                 if (target)
20291b654882SGreg Clayton                                 {
20301b654882SGreg Clayton                                     var_name_begin += ::strlen ("target.");
2031*0769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "arch}"))
20321b654882SGreg Clayton                                     {
20331b654882SGreg Clayton                                         ArchSpec arch (target->GetArchitecture ());
20341b654882SGreg Clayton                                         if (arch.IsValid())
20351b654882SGreg Clayton                                         {
203664195a2cSGreg Clayton                                             s.PutCString (arch.GetArchitectureName());
20371b654882SGreg Clayton                                             var_success = true;
20381b654882SGreg Clayton                                         }
20391b654882SGreg Clayton                                     }
2040*0769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "script:"))
2041aad8e480SEnrico Granata                                     {
2042aad8e480SEnrico Granata                                         var_name_begin += ::strlen("script:");
2043aad8e480SEnrico Granata                                         std::string script_name(var_name_begin,var_name_end);
2044aad8e480SEnrico Granata                                         ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2045*0769b2b1SMichael Sartain                                         if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
2046aad8e480SEnrico Granata                                             var_success = true;
2047aad8e480SEnrico Granata                                     }
20481b654882SGreg Clayton                                 }
20491b654882SGreg Clayton                             }
20501b654882SGreg Clayton                             break;
20511b654882SGreg Clayton 
20521b654882SGreg Clayton 
20531b654882SGreg Clayton                         case 'm':
2054*0769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "module."))
20551b654882SGreg Clayton                             {
20560603aa9dSGreg Clayton                                 if (sc && sc->module_sp.get())
20571b654882SGreg Clayton                                 {
20580603aa9dSGreg Clayton                                     Module *module = sc->module_sp.get();
20591b654882SGreg Clayton                                     var_name_begin += ::strlen ("module.");
20601b654882SGreg Clayton 
2061*0769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
20621b654882SGreg Clayton                                     {
20631b654882SGreg Clayton                                         if (module->GetFileSpec())
20641b654882SGreg Clayton                                         {
20651b654882SGreg Clayton                                             var_name_begin += ::strlen ("file.");
20661b654882SGreg Clayton 
2067*0769b2b1SMichael Sartain                                             if (IsToken (var_name_begin, "basename}"))
20681b654882SGreg Clayton                                             {
20691b654882SGreg Clayton                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
20701b654882SGreg Clayton                                                 var_success = format_file_spec;
20711b654882SGreg Clayton                                             }
2072*0769b2b1SMichael Sartain                                             else if (IsToken (var_name_begin, "fullpath}"))
20731b654882SGreg Clayton                                             {
20741b654882SGreg Clayton                                                 format_file_spec = module->GetFileSpec();
20751b654882SGreg Clayton                                                 var_success = format_file_spec;
20761b654882SGreg Clayton                                             }
20771b654882SGreg Clayton                                         }
20781b654882SGreg Clayton                                     }
20791b654882SGreg Clayton                                 }
20801b654882SGreg Clayton                             }
20811b654882SGreg Clayton                             break;
20821b654882SGreg Clayton 
20831b654882SGreg Clayton 
20841b654882SGreg Clayton                         case 'f':
2085*0769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "file."))
20861b654882SGreg Clayton                             {
20871b654882SGreg Clayton                                 if (sc && sc->comp_unit != NULL)
20881b654882SGreg Clayton                                 {
20891b654882SGreg Clayton                                     var_name_begin += ::strlen ("file.");
20901b654882SGreg Clayton 
2091*0769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "basename}"))
20921b654882SGreg Clayton                                     {
20931b654882SGreg Clayton                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
20941b654882SGreg Clayton                                         var_success = format_file_spec;
20951b654882SGreg Clayton                                     }
2096*0769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "fullpath}"))
20971b654882SGreg Clayton                                     {
20981b654882SGreg Clayton                                         format_file_spec = *sc->comp_unit;
20991b654882SGreg Clayton                                         var_success = format_file_spec;
21001b654882SGreg Clayton                                     }
21011b654882SGreg Clayton                                 }
21021b654882SGreg Clayton                             }
2103*0769b2b1SMichael Sartain                            else if (IsToken (var_name_begin, "frame."))
21041b654882SGreg Clayton                             {
2105c14ee32dSGreg Clayton                                 if (exe_ctx)
2106c14ee32dSGreg Clayton                                 {
2107c14ee32dSGreg Clayton                                     StackFrame *frame = exe_ctx->GetFramePtr();
2108c14ee32dSGreg Clayton                                     if (frame)
21091b654882SGreg Clayton                                     {
21101b654882SGreg Clayton                                         var_name_begin += ::strlen ("frame.");
2111*0769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "index}"))
21121b654882SGreg Clayton                                         {
2113c14ee32dSGreg Clayton                                             s.Printf("%u", frame->GetFrameIndex());
21141b654882SGreg Clayton                                             var_success = true;
21151b654882SGreg Clayton                                         }
2116*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "pc}"))
21171b654882SGreg Clayton                                         {
21181b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21191b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_PC;
21201b654882SGreg Clayton                                             var_success = true;
21211b654882SGreg Clayton                                         }
2122*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "sp}"))
21231b654882SGreg Clayton                                         {
21241b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21251b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_SP;
21261b654882SGreg Clayton                                             var_success = true;
21271b654882SGreg Clayton                                         }
2128*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fp}"))
21291b654882SGreg Clayton                                         {
21301b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21311b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FP;
21321b654882SGreg Clayton                                             var_success = true;
21331b654882SGreg Clayton                                         }
2134*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "flags}"))
21351b654882SGreg Clayton                                         {
21361b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21371b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
21381b654882SGreg Clayton                                             var_success = true;
21391b654882SGreg Clayton                                         }
2140*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "reg."))
21411b654882SGreg Clayton                                         {
2142c14ee32dSGreg Clayton                                             reg_ctx = frame->GetRegisterContext().get();
21431b654882SGreg Clayton                                             if (reg_ctx)
21441b654882SGreg Clayton                                             {
21451b654882SGreg Clayton                                                 var_name_begin += ::strlen ("reg.");
21461b654882SGreg Clayton                                                 if (var_name_begin < var_name_end)
21471b654882SGreg Clayton                                                 {
21481b654882SGreg Clayton                                                     std::string reg_name (var_name_begin, var_name_end);
21491b654882SGreg Clayton                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
21501b654882SGreg Clayton                                                     if (reg_info)
21511b654882SGreg Clayton                                                         var_success = true;
21521b654882SGreg Clayton                                                 }
21531b654882SGreg Clayton                                             }
21541b654882SGreg Clayton                                         }
2155*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2156aad8e480SEnrico Granata                                         {
2157aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2158aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2159aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
2160*0769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
2161aad8e480SEnrico Granata                                                 var_success = true;
2162aad8e480SEnrico Granata                                         }
2163aad8e480SEnrico Granata                                     }
2164aad8e480SEnrico Granata                                 }
21651b654882SGreg Clayton                             }
2166*0769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "function."))
21671b654882SGreg Clayton                             {
21681b654882SGreg Clayton                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
21691b654882SGreg Clayton                                 {
21701b654882SGreg Clayton                                     var_name_begin += ::strlen ("function.");
2171*0769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "id}"))
21721b654882SGreg Clayton                                     {
21731b654882SGreg Clayton                                         if (sc->function)
2174d01b2953SDaniel Malea                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
21751b654882SGreg Clayton                                         else
21761b654882SGreg Clayton                                             s.Printf("symbol[%u]", sc->symbol->GetID());
21771b654882SGreg Clayton 
21781b654882SGreg Clayton                                         var_success = true;
21791b654882SGreg Clayton                                     }
2180*0769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name}"))
21811b654882SGreg Clayton                                     {
21821b654882SGreg Clayton                                         if (sc->function)
21831b654882SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
21841b654882SGreg Clayton                                         else if (sc->symbol)
21851b654882SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
21861b654882SGreg Clayton                                         if (cstr)
21871b654882SGreg Clayton                                         {
21881b654882SGreg Clayton                                             s.PutCString(cstr);
21890d9c9934SGreg Clayton 
21900d9c9934SGreg Clayton                                             if (sc->block)
21910d9c9934SGreg Clayton                                             {
21920d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
21930d9c9934SGreg Clayton                                                 if (inline_block)
21940d9c9934SGreg Clayton                                                 {
21950d9c9934SGreg Clayton                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
21960d9c9934SGreg Clayton                                                     if (inline_info)
21970d9c9934SGreg Clayton                                                     {
21980d9c9934SGreg Clayton                                                         s.PutCString(" [inlined] ");
21990d9c9934SGreg Clayton                                                         inline_info->GetName().Dump(&s);
22000d9c9934SGreg Clayton                                                     }
22010d9c9934SGreg Clayton                                                 }
22020d9c9934SGreg Clayton                                             }
22031b654882SGreg Clayton                                             var_success = true;
22041b654882SGreg Clayton                                         }
22051b654882SGreg Clayton                                     }
2206*0769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name-with-args}"))
22076d3dbf51SGreg Clayton                                     {
22086d3dbf51SGreg Clayton                                         // Print the function name with arguments in it
22096d3dbf51SGreg Clayton 
22106d3dbf51SGreg Clayton                                         if (sc->function)
22116d3dbf51SGreg Clayton                                         {
22126d3dbf51SGreg Clayton                                             var_success = true;
22136d3dbf51SGreg Clayton                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
22146d3dbf51SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
22156d3dbf51SGreg Clayton                                             if (cstr)
22166d3dbf51SGreg Clayton                                             {
22176d3dbf51SGreg Clayton                                                 const InlineFunctionInfo *inline_info = NULL;
22186d3dbf51SGreg Clayton                                                 VariableListSP variable_list_sp;
22196d3dbf51SGreg Clayton                                                 bool get_function_vars = true;
22206d3dbf51SGreg Clayton                                                 if (sc->block)
22216d3dbf51SGreg Clayton                                                 {
22226d3dbf51SGreg Clayton                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
22236d3dbf51SGreg Clayton 
22246d3dbf51SGreg Clayton                                                     if (inline_block)
22256d3dbf51SGreg Clayton                                                     {
22266d3dbf51SGreg Clayton                                                         get_function_vars = false;
22276d3dbf51SGreg Clayton                                                         inline_info = sc->block->GetInlinedFunctionInfo();
22286d3dbf51SGreg Clayton                                                         if (inline_info)
22296d3dbf51SGreg Clayton                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
22306d3dbf51SGreg Clayton                                                     }
22316d3dbf51SGreg Clayton                                                 }
22326d3dbf51SGreg Clayton 
22336d3dbf51SGreg Clayton                                                 if (get_function_vars)
22346d3dbf51SGreg Clayton                                                 {
22356d3dbf51SGreg Clayton                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
22366d3dbf51SGreg Clayton                                                 }
22376d3dbf51SGreg Clayton 
22386d3dbf51SGreg Clayton                                                 if (inline_info)
22396d3dbf51SGreg Clayton                                                 {
22406d3dbf51SGreg Clayton                                                     s.PutCString (cstr);
22416d3dbf51SGreg Clayton                                                     s.PutCString (" [inlined] ");
22426d3dbf51SGreg Clayton                                                     cstr = inline_info->GetName().GetCString();
22436d3dbf51SGreg Clayton                                                 }
22446d3dbf51SGreg Clayton 
22456d3dbf51SGreg Clayton                                                 VariableList args;
22466d3dbf51SGreg Clayton                                                 if (variable_list_sp)
2247cc7f9bf5SEnrico Granata                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
22486d3dbf51SGreg Clayton                                                 if (args.GetSize() > 0)
22496d3dbf51SGreg Clayton                                                 {
22506d3dbf51SGreg Clayton                                                     const char *open_paren = strchr (cstr, '(');
22516d3dbf51SGreg Clayton                                                     const char *close_paren = NULL;
22526d3dbf51SGreg Clayton                                                     if (open_paren)
2253855958caSGreg Clayton                                                     {
2254*0769b2b1SMichael Sartain                                                         if (IsToken (open_paren, "(anonymous namespace)"))
2255855958caSGreg Clayton                                                         {
2256855958caSGreg Clayton                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2257855958caSGreg Clayton                                                             if (open_paren)
22586d3dbf51SGreg Clayton                                                                 close_paren = strchr (open_paren, ')');
2259855958caSGreg Clayton                                                         }
2260855958caSGreg Clayton                                                         else
2261855958caSGreg Clayton                                                             close_paren = strchr (open_paren, ')');
2262855958caSGreg Clayton                                                     }
22636d3dbf51SGreg Clayton 
22646d3dbf51SGreg Clayton                                                     if (open_paren)
22656d3dbf51SGreg Clayton                                                         s.Write(cstr, open_paren - cstr + 1);
22666d3dbf51SGreg Clayton                                                     else
22676d3dbf51SGreg Clayton                                                     {
22686d3dbf51SGreg Clayton                                                         s.PutCString (cstr);
22696d3dbf51SGreg Clayton                                                         s.PutChar ('(');
22706d3dbf51SGreg Clayton                                                     }
22715b6889b1SGreg Clayton                                                     const size_t num_args = args.GetSize();
22726d3dbf51SGreg Clayton                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
22736d3dbf51SGreg Clayton                                                     {
22746d3dbf51SGreg Clayton                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
22756d3dbf51SGreg Clayton                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
22766d3dbf51SGreg Clayton                                                         const char *var_name = var_value_sp->GetName().GetCString();
22776d3dbf51SGreg Clayton                                                         const char *var_value = var_value_sp->GetValueAsCString();
22786d3dbf51SGreg Clayton                                                         if (arg_idx > 0)
22796d3dbf51SGreg Clayton                                                             s.PutCString (", ");
22803b188b17SGreg Clayton                                                         if (var_value_sp->GetError().Success())
2281cc7f9bf5SEnrico Granata                                                         {
2282cc7f9bf5SEnrico Granata                                                             if (var_value)
22836d3dbf51SGreg Clayton                                                                 s.Printf ("%s=%s", var_name, var_value);
22843b188b17SGreg Clayton                                                             else
2285cc7f9bf5SEnrico Granata                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2286cc7f9bf5SEnrico Granata                                                         }
2287cc7f9bf5SEnrico Granata                                                         else
22883b188b17SGreg Clayton                                                             s.Printf ("%s=<unavailable>", var_name);
22896d3dbf51SGreg Clayton                                                     }
22906d3dbf51SGreg Clayton 
22916d3dbf51SGreg Clayton                                                     if (close_paren)
22926d3dbf51SGreg Clayton                                                         s.PutCString (close_paren);
22936d3dbf51SGreg Clayton                                                     else
22946d3dbf51SGreg Clayton                                                         s.PutChar(')');
22956d3dbf51SGreg Clayton 
22966d3dbf51SGreg Clayton                                                 }
22976d3dbf51SGreg Clayton                                                 else
22986d3dbf51SGreg Clayton                                                 {
22996d3dbf51SGreg Clayton                                                     s.PutCString(cstr);
23006d3dbf51SGreg Clayton                                                 }
23016d3dbf51SGreg Clayton                                             }
23026d3dbf51SGreg Clayton                                         }
23036d3dbf51SGreg Clayton                                         else if (sc->symbol)
23046d3dbf51SGreg Clayton                                         {
23056d3dbf51SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
23066d3dbf51SGreg Clayton                                             if (cstr)
23076d3dbf51SGreg Clayton                                             {
23086d3dbf51SGreg Clayton                                                 s.PutCString(cstr);
23096d3dbf51SGreg Clayton                                                 var_success = true;
23106d3dbf51SGreg Clayton                                             }
23116d3dbf51SGreg Clayton                                         }
23126d3dbf51SGreg Clayton                                     }
2313*0769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "addr-offset}"))
23141b654882SGreg Clayton                                     {
23151b654882SGreg Clayton                                         var_success = addr != NULL;
23161b654882SGreg Clayton                                         if (var_success)
23171b654882SGreg Clayton                                         {
23181b654882SGreg Clayton                                             format_addr = *addr;
23191b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23201b654882SGreg Clayton                                         }
23211b654882SGreg Clayton                                     }
2322*0769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "line-offset}"))
23231b654882SGreg Clayton                                     {
23241b654882SGreg Clayton                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
23251b654882SGreg Clayton                                         if (var_success)
23261b654882SGreg Clayton                                         {
23271b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
23281b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23291b654882SGreg Clayton                                         }
23301b654882SGreg Clayton                                     }
2331*0769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "pc-offset}"))
23321b654882SGreg Clayton                                     {
2333c14ee32dSGreg Clayton                                         StackFrame *frame = exe_ctx->GetFramePtr();
2334c14ee32dSGreg Clayton                                         var_success = frame != NULL;
23351b654882SGreg Clayton                                         if (var_success)
23361b654882SGreg Clayton                                         {
2337c14ee32dSGreg Clayton                                             format_addr = frame->GetFrameCodeAddress();
23381b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23391b654882SGreg Clayton                                         }
23401b654882SGreg Clayton                                     }
23411b654882SGreg Clayton                                 }
23421b654882SGreg Clayton                             }
23431b654882SGreg Clayton                             break;
23441b654882SGreg Clayton 
23451b654882SGreg Clayton                         case 'l':
2346*0769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "line."))
23471b654882SGreg Clayton                             {
23481b654882SGreg Clayton                                 if (sc && sc->line_entry.IsValid())
23491b654882SGreg Clayton                                 {
23501b654882SGreg Clayton                                     var_name_begin += ::strlen ("line.");
2351*0769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
23521b654882SGreg Clayton                                     {
23531b654882SGreg Clayton                                         var_name_begin += ::strlen ("file.");
23541b654882SGreg Clayton 
2355*0769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "basename}"))
23561b654882SGreg Clayton                                         {
23571b654882SGreg Clayton                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
23581b654882SGreg Clayton                                             var_success = format_file_spec;
23591b654882SGreg Clayton                                         }
2360*0769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fullpath}"))
23611b654882SGreg Clayton                                         {
23621b654882SGreg Clayton                                             format_file_spec = sc->line_entry.file;
23631b654882SGreg Clayton                                             var_success = format_file_spec;
23641b654882SGreg Clayton                                         }
23651b654882SGreg Clayton                                     }
2366*0769b2b1SMichael Sartain                                     else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
23671b654882SGreg Clayton                                     {
23681b654882SGreg Clayton                                         var_success = true;
2369*0769b2b1SMichael Sartain                                         s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
23701b654882SGreg Clayton                                     }
2371*0769b2b1SMichael Sartain                                     else if ((IsToken (var_name_begin, "start-addr}")) ||
2372*0769b2b1SMichael Sartain                                              (IsToken (var_name_begin, "end-addr}")))
23731b654882SGreg Clayton                                     {
23741b654882SGreg Clayton                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
23751b654882SGreg Clayton                                         if (var_success)
23761b654882SGreg Clayton                                         {
23771b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
23781b654882SGreg Clayton                                             if (var_name_begin[0] == 'e')
23791b654882SGreg Clayton                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
23801b654882SGreg Clayton                                         }
23811b654882SGreg Clayton                                     }
23821b654882SGreg Clayton                                 }
23831b654882SGreg Clayton                             }
23841b654882SGreg Clayton                             break;
23851b654882SGreg Clayton                         }
23861b654882SGreg Clayton 
23871b654882SGreg Clayton                         if (var_success)
23881b654882SGreg Clayton                         {
23891b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
23901b654882SGreg Clayton                             if (reg_num != LLDB_INVALID_REGNUM)
23911b654882SGreg Clayton                             {
2392c14ee32dSGreg Clayton                                 StackFrame *frame = exe_ctx->GetFramePtr();
23931b654882SGreg Clayton                                 // We have a register value to display...
23941b654882SGreg Clayton                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
23951b654882SGreg Clayton                                 {
2396c14ee32dSGreg Clayton                                     format_addr = frame->GetFrameCodeAddress();
23971b654882SGreg Clayton                                 }
23981b654882SGreg Clayton                                 else
23991b654882SGreg Clayton                                 {
24001b654882SGreg Clayton                                     if (reg_ctx == NULL)
2401c14ee32dSGreg Clayton                                         reg_ctx = frame->GetRegisterContext().get();
24021b654882SGreg Clayton 
24031b654882SGreg Clayton                                     if (reg_ctx)
24041b654882SGreg Clayton                                     {
24051b654882SGreg Clayton                                         if (reg_kind != kNumRegisterKinds)
24061b654882SGreg Clayton                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
24071b654882SGreg Clayton                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
24081b654882SGreg Clayton                                         var_success = reg_info != NULL;
24091b654882SGreg Clayton                                     }
24101b654882SGreg Clayton                                 }
24111b654882SGreg Clayton                             }
24121b654882SGreg Clayton 
24131b654882SGreg Clayton                             if (reg_info != NULL)
24141b654882SGreg Clayton                             {
24157349bd90SGreg Clayton                                 RegisterValue reg_value;
24167349bd90SGreg Clayton                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
24177349bd90SGreg Clayton                                 if (var_success)
24181b654882SGreg Clayton                                 {
24199a8fa916SGreg Clayton                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
24201b654882SGreg Clayton                                 }
24211b654882SGreg Clayton                             }
24221b654882SGreg Clayton 
24231b654882SGreg Clayton                             if (format_file_spec)
24241b654882SGreg Clayton                             {
24251b654882SGreg Clayton                                 s << format_file_spec;
24261b654882SGreg Clayton                             }
24271b654882SGreg Clayton 
24281b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
24291b654882SGreg Clayton                             if (format_addr.IsValid())
24301b654882SGreg Clayton                             {
24310603aa9dSGreg Clayton                                 var_success = false;
24320603aa9dSGreg Clayton 
24331b654882SGreg Clayton                                 if (calculate_format_addr_function_offset)
24341b654882SGreg Clayton                                 {
24351b654882SGreg Clayton                                     Address func_addr;
24360603aa9dSGreg Clayton 
24370603aa9dSGreg Clayton                                     if (sc)
24380603aa9dSGreg Clayton                                     {
24391b654882SGreg Clayton                                         if (sc->function)
24400d9c9934SGreg Clayton                                         {
24411b654882SGreg Clayton                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
24420d9c9934SGreg Clayton                                             if (sc->block)
24430d9c9934SGreg Clayton                                             {
24440d9c9934SGreg Clayton                                                 // Check to make sure we aren't in an inline
24450d9c9934SGreg Clayton                                                 // function. If we are, use the inline block
24460d9c9934SGreg Clayton                                                 // range that contains "format_addr" since
24470d9c9934SGreg Clayton                                                 // blocks can be discontiguous.
24480d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
24490d9c9934SGreg Clayton                                                 AddressRange inline_range;
24500d9c9934SGreg Clayton                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
24510d9c9934SGreg Clayton                                                     func_addr = inline_range.GetBaseAddress();
24520d9c9934SGreg Clayton                                             }
24530d9c9934SGreg Clayton                                         }
2454e7612134SGreg Clayton                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2455e7612134SGreg Clayton                                             func_addr = sc->symbol->GetAddress();
24560603aa9dSGreg Clayton                                     }
24571b654882SGreg Clayton 
24580603aa9dSGreg Clayton                                     if (func_addr.IsValid())
24591b654882SGreg Clayton                                     {
24601b654882SGreg Clayton                                         if (func_addr.GetSection() == format_addr.GetSection())
24611b654882SGreg Clayton                                         {
24621b654882SGreg Clayton                                             addr_t func_file_addr = func_addr.GetFileAddress();
24631b654882SGreg Clayton                                             addr_t addr_file_addr = format_addr.GetFileAddress();
24641b654882SGreg Clayton                                             if (addr_file_addr > func_file_addr)
2465d01b2953SDaniel Malea                                                 s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
24661b654882SGreg Clayton                                             else if (addr_file_addr < func_file_addr)
2467d01b2953SDaniel Malea                                                 s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
24680603aa9dSGreg Clayton                                             var_success = true;
24691b654882SGreg Clayton                                         }
24701b654882SGreg Clayton                                         else
24710603aa9dSGreg Clayton                                         {
24720603aa9dSGreg Clayton                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
24730603aa9dSGreg Clayton                                             if (target)
24740603aa9dSGreg Clayton                                             {
24750603aa9dSGreg Clayton                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
24760603aa9dSGreg Clayton                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
24770603aa9dSGreg Clayton                                                 if (addr_load_addr > func_load_addr)
2478d01b2953SDaniel Malea                                                     s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
24790603aa9dSGreg Clayton                                                 else if (addr_load_addr < func_load_addr)
2480d01b2953SDaniel Malea                                                     s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
24810603aa9dSGreg Clayton                                                 var_success = true;
24820603aa9dSGreg Clayton                                             }
24830603aa9dSGreg Clayton                                         }
24841b654882SGreg Clayton                                     }
24851b654882SGreg Clayton                                 }
24861b654882SGreg Clayton                                 else
24871b654882SGreg Clayton                                 {
24880603aa9dSGreg Clayton                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
24891b654882SGreg Clayton                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
24900603aa9dSGreg Clayton                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
24910603aa9dSGreg Clayton                                         vaddr = format_addr.GetLoadAddress (target);
24921b654882SGreg Clayton                                     if (vaddr == LLDB_INVALID_ADDRESS)
24931b654882SGreg Clayton                                         vaddr = format_addr.GetFileAddress ();
24941b654882SGreg Clayton 
24951b654882SGreg Clayton                                     if (vaddr != LLDB_INVALID_ADDRESS)
24960603aa9dSGreg Clayton                                     {
2497514487e8SGreg Clayton                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
249835f1a0d5SGreg Clayton                                         if (addr_width == 0)
249935f1a0d5SGreg Clayton                                             addr_width = 16;
2500d01b2953SDaniel Malea                                         s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
25010603aa9dSGreg Clayton                                         var_success = true;
25020603aa9dSGreg Clayton                                     }
25031b654882SGreg Clayton                                 }
25041b654882SGreg Clayton                             }
25051b654882SGreg Clayton                         }
25061b654882SGreg Clayton 
25071b654882SGreg Clayton                         if (var_success == false)
25081b654882SGreg Clayton                             success = false;
25091b654882SGreg Clayton                     }
25101b654882SGreg Clayton                     p = var_name_end;
25111b654882SGreg Clayton                 }
25121b654882SGreg Clayton                 else
25131b654882SGreg Clayton                     break;
25141b654882SGreg Clayton             }
25151b654882SGreg Clayton             else
25161b654882SGreg Clayton             {
25171b654882SGreg Clayton                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
25181b654882SGreg Clayton                 s.PutChar(*p);
25191b654882SGreg Clayton             }
25201b654882SGreg Clayton         }
25211b654882SGreg Clayton         else if (*p == '\\')
25221b654882SGreg Clayton         {
25231b654882SGreg Clayton             ++p; // skip the slash
25241b654882SGreg Clayton             switch (*p)
25251b654882SGreg Clayton             {
25261b654882SGreg Clayton             case 'a': s.PutChar ('\a'); break;
25271b654882SGreg Clayton             case 'b': s.PutChar ('\b'); break;
25281b654882SGreg Clayton             case 'f': s.PutChar ('\f'); break;
25291b654882SGreg Clayton             case 'n': s.PutChar ('\n'); break;
25301b654882SGreg Clayton             case 'r': s.PutChar ('\r'); break;
25311b654882SGreg Clayton             case 't': s.PutChar ('\t'); break;
25321b654882SGreg Clayton             case 'v': s.PutChar ('\v'); break;
25331b654882SGreg Clayton             case '\'': s.PutChar ('\''); break;
25341b654882SGreg Clayton             case '\\': s.PutChar ('\\'); break;
25351b654882SGreg Clayton             case '0':
25361b654882SGreg Clayton                 // 1 to 3 octal chars
25371b654882SGreg Clayton                 {
25380603aa9dSGreg Clayton                     // Make a string that can hold onto the initial zero char,
25390603aa9dSGreg Clayton                     // up to 3 octal digits, and a terminating NULL.
25400603aa9dSGreg Clayton                     char oct_str[5] = { 0, 0, 0, 0, 0 };
25410603aa9dSGreg Clayton 
25420603aa9dSGreg Clayton                     int i;
25430603aa9dSGreg Clayton                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
25440603aa9dSGreg Clayton                         oct_str[i] = p[i];
25450603aa9dSGreg Clayton 
25460603aa9dSGreg Clayton                     // We don't want to consume the last octal character since
25470603aa9dSGreg Clayton                     // the main for loop will do this for us, so we advance p by
25480603aa9dSGreg Clayton                     // one less than i (even if i is zero)
25490603aa9dSGreg Clayton                     p += i - 1;
25500603aa9dSGreg Clayton                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
25510603aa9dSGreg Clayton                     if (octal_value <= UINT8_MAX)
25521b654882SGreg Clayton                     {
2553c7bece56SGreg Clayton                         s.PutChar((char)octal_value);
25541b654882SGreg Clayton                     }
25551b654882SGreg Clayton                 }
25561b654882SGreg Clayton                 break;
25571b654882SGreg Clayton 
25581b654882SGreg Clayton             case 'x':
25591b654882SGreg Clayton                 // hex number in the format
25600603aa9dSGreg Clayton                 if (isxdigit(p[1]))
25611b654882SGreg Clayton                 {
25620603aa9dSGreg Clayton                     ++p;    // Skip the 'x'
25631b654882SGreg Clayton 
25640603aa9dSGreg Clayton                     // Make a string that can hold onto two hex chars plus a
25650603aa9dSGreg Clayton                     // NULL terminator
25661b654882SGreg Clayton                     char hex_str[3] = { 0,0,0 };
25671b654882SGreg Clayton                     hex_str[0] = *p;
25680603aa9dSGreg Clayton                     if (isxdigit(p[1]))
25690603aa9dSGreg Clayton                     {
25700603aa9dSGreg Clayton                         ++p; // Skip the first of the two hex chars
25711b654882SGreg Clayton                         hex_str[1] = *p;
25720603aa9dSGreg Clayton                     }
25730603aa9dSGreg Clayton 
25741b654882SGreg Clayton                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
25750603aa9dSGreg Clayton                     if (hex_value <= UINT8_MAX)
2576c7bece56SGreg Clayton                         s.PutChar ((char)hex_value);
25771b654882SGreg Clayton                 }
25781b654882SGreg Clayton                 else
25791b654882SGreg Clayton                 {
25800603aa9dSGreg Clayton                     s.PutChar('x');
25811b654882SGreg Clayton                 }
25821b654882SGreg Clayton                 break;
25831b654882SGreg Clayton 
25841b654882SGreg Clayton             default:
25850603aa9dSGreg Clayton                 // Just desensitize any other character by just printing what
25860603aa9dSGreg Clayton                 // came after the '\'
25870603aa9dSGreg Clayton                 s << *p;
25881b654882SGreg Clayton                 break;
25891b654882SGreg Clayton 
25901b654882SGreg Clayton             }
25911b654882SGreg Clayton 
25921b654882SGreg Clayton         }
25931b654882SGreg Clayton     }
25941b654882SGreg Clayton     if (end)
25951b654882SGreg Clayton         *end = p;
25961b654882SGreg Clayton     return success;
25971b654882SGreg Clayton }
25981b654882SGreg Clayton 
2599c3ce7f27SMichael Sartain bool
2600c3ce7f27SMichael Sartain Debugger::FormatPrompt
2601c3ce7f27SMichael Sartain (
2602c3ce7f27SMichael Sartain     const char *format,
2603c3ce7f27SMichael Sartain     const SymbolContext *sc,
2604c3ce7f27SMichael Sartain     const ExecutionContext *exe_ctx,
2605c3ce7f27SMichael Sartain     const Address *addr,
2606c3ce7f27SMichael Sartain     Stream &s,
2607c3ce7f27SMichael Sartain     ValueObject* valobj
2608c3ce7f27SMichael Sartain )
2609c3ce7f27SMichael Sartain {
2610c3ce7f27SMichael Sartain     bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2611c3ce7f27SMichael Sartain     std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2612c3ce7f27SMichael Sartain     if (format_str.length())
2613c3ce7f27SMichael Sartain         format = format_str.c_str();
2614c3ce7f27SMichael Sartain     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj);
2615c3ce7f27SMichael Sartain }
2616c3ce7f27SMichael Sartain 
2617228063cdSJim Ingham void
2618228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2619228063cdSJim Ingham {
26204f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
26214f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
26224f02b22dSJim Ingham     // callback.
2623228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2624228063cdSJim Ingham }
2625228063cdSJim Ingham 
2626228063cdSJim Ingham bool
2627228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2628228063cdSJim Ingham {
2629228063cdSJim Ingham     Log::Callbacks log_callbacks;
2630228063cdSJim Ingham 
2631228063cdSJim Ingham     StreamSP log_stream_sp;
26329a028519SSean Callanan     if (m_log_callback_stream_sp)
2633228063cdSJim Ingham     {
2634228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
2635228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
2636228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2637228063cdSJim Ingham     }
2638228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
2639228063cdSJim Ingham     {
2640228063cdSJim Ingham         log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false));
2641228063cdSJim Ingham     }
2642228063cdSJim Ingham     else
2643228063cdSJim Ingham     {
2644228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2645c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
2646c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
2647c1b2ccfdSGreg Clayton         if (!log_stream_sp)
2648228063cdSJim Ingham         {
2649228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
2650228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
2651228063cdSJim Ingham         }
2652228063cdSJim Ingham     }
2653228063cdSJim Ingham     assert (log_stream_sp.get());
2654228063cdSJim Ingham 
2655228063cdSJim Ingham     if (log_options == 0)
2656228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2657228063cdSJim Ingham 
265857abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2659228063cdSJim Ingham     {
2660228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2661228063cdSJim Ingham         return true;
2662228063cdSJim Ingham     }
2663228063cdSJim Ingham     else
2664228063cdSJim Ingham     {
2665228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2666228063cdSJim Ingham         if (log_channel_sp)
2667228063cdSJim Ingham         {
2668228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2669228063cdSJim Ingham             {
2670228063cdSJim Ingham                 return true;
2671228063cdSJim Ingham             }
2672228063cdSJim Ingham             else
2673228063cdSJim Ingham             {
2674228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2675228063cdSJim Ingham                 return false;
2676228063cdSJim Ingham             }
2677228063cdSJim Ingham         }
2678228063cdSJim Ingham         else
2679228063cdSJim Ingham         {
2680228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2681228063cdSJim Ingham             return false;
2682228063cdSJim Ingham         }
2683228063cdSJim Ingham     }
2684228063cdSJim Ingham     return false;
2685228063cdSJim Ingham }
2686228063cdSJim Ingham 
26879585fbfcSGreg Clayton SourceManager &
26889585fbfcSGreg Clayton Debugger::GetSourceManager ()
26899585fbfcSGreg Clayton {
26909585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
26919585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
26929585fbfcSGreg Clayton     return *m_source_manager_ap;
26939585fbfcSGreg Clayton }
26949585fbfcSGreg Clayton 
26959585fbfcSGreg Clayton 
2696