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 
124a33d318SGreg Clayton #include "lldb/Core/Debugger.h"
134a33d318SGreg Clayton 
144a33d318SGreg Clayton #include <map>
154a33d318SGreg Clayton 
164becb37eSEnrico Granata #include "clang/AST/DeclCXX.h"
174becb37eSEnrico Granata #include "clang/AST/Type.h"
18705b1809SJason Molenda #include "llvm/ADT/StringRef.h"
194becb37eSEnrico Granata 
2030fdc8d8SChris Lattner #include "lldb/lldb-private.h"
211f746071SGreg Clayton #include "lldb/Core/Module.h"
22e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h"
237349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h"
2430fdc8d8SChris Lattner #include "lldb/Core/State.h"
255b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h"
26228063cdSJim Ingham #include "lldb/Core/StreamCallback.h"
2744d93782SGreg Clayton #include "lldb/Core/StreamFile.h"
281b654882SGreg Clayton #include "lldb/Core/StreamString.h"
29705b1809SJason Molenda #include "lldb/Core/StructuredData.h"
3030fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
314becb37eSEnrico Granata #include "lldb/Core/ValueObject.h"
326d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
335548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
345548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h"
35894f7359SEnrico Granata #include "lldb/DataFormatters/TypeSummary.h"
3693a66fc1SZachary Turner #include "lldb/Host/ConnectionFileDescriptor.h"
3742ff0ad8SZachary Turner #include "lldb/Host/HostInfo.h"
38a3406614SGreg Clayton #include "lldb/Host/Terminal.h"
3939de3110SZachary Turner #include "lldb/Host/ThreadLauncher.h"
406611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
4167cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h"
4267cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h"
431f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h"
441f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
451f746071SGreg Clayton #include "lldb/Symbol/Function.h"
461f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
476d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h"
48aff1b357SJason Molenda #include "lldb/Target/CPPLanguageRuntime.h"
49aff1b357SJason Molenda #include "lldb/Target/ObjCLanguageRuntime.h"
5030fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
5130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
521b654882SGreg Clayton #include "lldb/Target/RegisterContext.h"
535fb8f797SGreg Clayton #include "lldb/Target/SectionLoadList.h"
541b654882SGreg Clayton #include "lldb/Target/StopInfo.h"
5584a53dfbSEnrico Granata #include "lldb/Target/Target.h"
5630fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
575a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
5830fdc8d8SChris Lattner 
5958a559c0SZachary Turner #include "llvm/Support/DynamicLibrary.h"
6058a559c0SZachary Turner 
6130fdc8d8SChris Lattner using namespace lldb;
6230fdc8d8SChris Lattner using namespace lldb_private;
6330fdc8d8SChris Lattner 
6430fdc8d8SChris Lattner 
651b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0;
66ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
677c2896a2SZachary Turner static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
68ebc1bb27SCaroline Tice 
691b654882SGreg Clayton #pragma mark Static Functions
701b654882SGreg Clayton 
711b654882SGreg Clayton static Mutex &
721b654882SGreg Clayton GetDebuggerListMutex ()
731b654882SGreg Clayton {
741b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
751b654882SGreg Clayton     return g_mutex;
761b654882SGreg Clayton }
771b654882SGreg Clayton 
781b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
791b654882SGreg Clayton 
801b654882SGreg Clayton static DebuggerList &
811b654882SGreg Clayton GetDebuggerList()
821b654882SGreg Clayton {
831b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
846a7f3338SBruce Mitchener     // global init constructors
851b654882SGreg Clayton     static DebuggerList g_list;
861b654882SGreg Clayton     return g_list;
871b654882SGreg Clayton }
88e372b98dSGreg Clayton 
89e372b98dSGreg Clayton OptionEnumValueElement
9067cc0636SGreg Clayton g_show_disassembly_enum_values[] =
91e372b98dSGreg Clayton {
9267cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
9367cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
9467cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
95e372b98dSGreg Clayton     { 0, NULL, NULL }
96e372b98dSGreg Clayton };
97e372b98dSGreg Clayton 
9867cc0636SGreg Clayton OptionEnumValueElement
9967cc0636SGreg Clayton g_language_enumerators[] =
10067cc0636SGreg Clayton {
10167cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
10267cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
10367cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
104a12993c9SGreg Clayton     { 0, NULL, NULL }
10567cc0636SGreg Clayton };
106e372b98dSGreg Clayton 
10767cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
10867cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
10967cc0636SGreg Clayton 
1100769b2b1SMichael Sartain #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
11167cc0636SGreg Clayton     "{, ${frame.pc}}"\
11267cc0636SGreg Clayton     MODULE_WITH_FUNC\
11367cc0636SGreg Clayton     FILE_AND_LINE\
1140769b2b1SMichael Sartain     "{, name = '${thread.name}'}"\
1150769b2b1SMichael Sartain     "{, queue = '${thread.queue}'}"\
116705b1809SJason Molenda     "{, activity = '${thread.info.activity.name}'}" \
117705b1809SJason Molenda     "{, ${thread.info.trace_messages} messages}" \
11867cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
11967cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
12030fadafeSJim Ingham     "{\\nCompleted expression: ${thread.completed-expression}}"\
12167cc0636SGreg Clayton     "\\n"
12267cc0636SGreg Clayton 
12367cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
12467cc0636SGreg Clayton     MODULE_WITH_FUNC\
12567cc0636SGreg Clayton     FILE_AND_LINE\
12667cc0636SGreg Clayton     "\\n"
12767cc0636SGreg Clayton 
128aff1b357SJason Molenda #define DEFAULT_DISASSEMBLY_FORMAT "${addr-file-or-load} <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>: "
12967cc0636SGreg Clayton 
13067cc0636SGreg Clayton 
131754a9369SGreg Clayton static PropertyDefinition
132754a9369SGreg Clayton g_properties[] =
13367cc0636SGreg Clayton {
13467cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
135aff1b357SJason Molenda {   "disassembly-format",       OptionValue::eTypeString , true, 0    , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." },
13667cc0636SGreg 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." },
13767cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1384c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
13967cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
14067cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
14167cc0636SGreg 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." },
14267cc0636SGreg 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." },
14367cc0636SGreg 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." },
14467cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
14567cc0636SGreg Clayton {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
14667cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
147c3ce7f27SMichael Sartain {   "use-color",                OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
14890a8db30SEnrico Granata {   "auto-one-line-summaries",     OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
149e8cd0c98SGreg Clayton 
15067cc0636SGreg Clayton     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
15167cc0636SGreg Clayton };
15267cc0636SGreg Clayton 
15367cc0636SGreg Clayton enum
15467cc0636SGreg Clayton {
15567cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
156aff1b357SJason Molenda     ePropertyDisassemblyFormat,
15767cc0636SGreg Clayton     ePropertyFrameFormat,
15867cc0636SGreg Clayton     ePropertyNotiftVoid,
15967cc0636SGreg Clayton     ePropertyPrompt,
16067cc0636SGreg Clayton     ePropertyScriptLanguage,
16167cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
16267cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
16367cc0636SGreg Clayton     ePropertyStopLineCountAfter,
16467cc0636SGreg Clayton     ePropertyStopLineCountBefore,
16567cc0636SGreg Clayton     ePropertyTerminalWidth,
16667cc0636SGreg Clayton     ePropertyThreadFormat,
167c3ce7f27SMichael Sartain     ePropertyUseExternalEditor,
168c3ce7f27SMichael Sartain     ePropertyUseColor,
16990a8db30SEnrico Granata     ePropertyAutoOneLineSummaries
17067cc0636SGreg Clayton };
17167cc0636SGreg Clayton 
1725fb8f797SGreg Clayton Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
1734c05410fSGreg Clayton 
1744c05410fSGreg Clayton Error
1754c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1764c05410fSGreg Clayton                             VarSetOperationType op,
1774c05410fSGreg Clayton                             const char *property_path,
1784c05410fSGreg Clayton                             const char *value)
1794c05410fSGreg Clayton {
18084a53dfbSEnrico Granata     bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
18184a53dfbSEnrico Granata     TargetSP target_sp;
182397ddd5fSEnrico Granata     LoadScriptFromSymFile load_script_old_value;
18384a53dfbSEnrico Granata     if (is_load_script && exe_ctx->GetTargetSP())
18484a53dfbSEnrico Granata     {
18584a53dfbSEnrico Granata         target_sp = exe_ctx->GetTargetSP();
18684a53dfbSEnrico Granata         load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
18784a53dfbSEnrico Granata     }
1884c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
1894c05410fSGreg Clayton     if (error.Success())
1904c05410fSGreg Clayton     {
19184a53dfbSEnrico Granata         // FIXME it would be nice to have "on-change" callbacks for properties
1924c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
1934c05410fSGreg Clayton         {
1944c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
195c3ce7f27SMichael Sartain             std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
196c3ce7f27SMichael Sartain             if (str.length())
197c3ce7f27SMichael Sartain                 new_prompt = str.c_str();
19844d93782SGreg Clayton             GetCommandInterpreter().UpdatePrompt(new_prompt);
1994c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
2004c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
2014c05410fSGreg Clayton         }
202c3ce7f27SMichael Sartain         else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
203c3ce7f27SMichael Sartain         {
204c3ce7f27SMichael Sartain 			// use-color changed. Ping the prompt so it can reset the ansi terminal codes.
205c3ce7f27SMichael Sartain             SetPrompt (GetPrompt());
206c3ce7f27SMichael Sartain         }
207397ddd5fSEnrico Granata         else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
20884a53dfbSEnrico Granata         {
209397ddd5fSEnrico Granata             if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
21084a53dfbSEnrico Granata             {
21184a53dfbSEnrico Granata                 std::list<Error> errors;
2129730339bSEnrico Granata                 StreamString feedback_stream;
2139730339bSEnrico Granata                 if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
21484a53dfbSEnrico Granata                 {
21544d93782SGreg Clayton                     StreamFileSP stream_sp (GetErrorFile());
21644d93782SGreg Clayton                     if (stream_sp)
21744d93782SGreg Clayton                     {
21884a53dfbSEnrico Granata                         for (auto error : errors)
21984a53dfbSEnrico Granata                         {
22044d93782SGreg Clayton                             stream_sp->Printf("%s\n",error.AsCString());
22184a53dfbSEnrico Granata                         }
2229730339bSEnrico Granata                         if (feedback_stream.GetSize())
22344d93782SGreg Clayton                             stream_sp->Printf("%s",feedback_stream.GetData());
22444d93782SGreg Clayton                     }
22584a53dfbSEnrico Granata                 }
22684a53dfbSEnrico Granata             }
22784a53dfbSEnrico Granata         }
2284c05410fSGreg Clayton     }
2294c05410fSGreg Clayton     return error;
2304c05410fSGreg Clayton }
2314c05410fSGreg Clayton 
23267cc0636SGreg Clayton bool
23367cc0636SGreg Clayton Debugger::GetAutoConfirm () const
23467cc0636SGreg Clayton {
23567cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
236754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
23767cc0636SGreg Clayton }
23867cc0636SGreg Clayton 
23967cc0636SGreg Clayton const char *
240aff1b357SJason Molenda Debugger::GetDisassemblyFormat() const
241aff1b357SJason Molenda {
242aff1b357SJason Molenda     const uint32_t idx = ePropertyDisassemblyFormat;
243aff1b357SJason Molenda     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
244aff1b357SJason Molenda }
245aff1b357SJason Molenda 
246aff1b357SJason Molenda const char *
24767cc0636SGreg Clayton Debugger::GetFrameFormat() const
24867cc0636SGreg Clayton {
24967cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
250754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
25167cc0636SGreg Clayton }
25267cc0636SGreg Clayton 
25367cc0636SGreg Clayton bool
25467cc0636SGreg Clayton Debugger::GetNotifyVoid () const
25567cc0636SGreg Clayton {
25667cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
257754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
25867cc0636SGreg Clayton }
25967cc0636SGreg Clayton 
26067cc0636SGreg Clayton const char *
26167cc0636SGreg Clayton Debugger::GetPrompt() const
26267cc0636SGreg Clayton {
26367cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
264754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
26567cc0636SGreg Clayton }
26667cc0636SGreg Clayton 
26767cc0636SGreg Clayton void
26867cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
26967cc0636SGreg Clayton {
27067cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
27167cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
27267cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
273c3ce7f27SMichael Sartain     std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
274c3ce7f27SMichael Sartain     if (str.length())
275c3ce7f27SMichael Sartain         new_prompt = str.c_str();
27644d93782SGreg Clayton     GetCommandInterpreter().UpdatePrompt(new_prompt);
27767cc0636SGreg Clayton }
27867cc0636SGreg Clayton 
27967cc0636SGreg Clayton const char *
28067cc0636SGreg Clayton Debugger::GetThreadFormat() const
28167cc0636SGreg Clayton {
28267cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
283754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
28467cc0636SGreg Clayton }
28567cc0636SGreg Clayton 
28667cc0636SGreg Clayton lldb::ScriptLanguage
28767cc0636SGreg Clayton Debugger::GetScriptLanguage() const
28867cc0636SGreg Clayton {
28967cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
290754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
29167cc0636SGreg Clayton }
29267cc0636SGreg Clayton 
29367cc0636SGreg Clayton bool
29467cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
29567cc0636SGreg Clayton {
29667cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
29767cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
29867cc0636SGreg Clayton }
29967cc0636SGreg Clayton 
30067cc0636SGreg Clayton uint32_t
30167cc0636SGreg Clayton Debugger::GetTerminalWidth () const
30267cc0636SGreg Clayton {
30367cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
304754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
30567cc0636SGreg Clayton }
30667cc0636SGreg Clayton 
30767cc0636SGreg Clayton bool
30867cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
30967cc0636SGreg Clayton {
31067cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
31167cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
31267cc0636SGreg Clayton }
31367cc0636SGreg Clayton 
31467cc0636SGreg Clayton bool
31567cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
31667cc0636SGreg Clayton {
31767cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
318754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
31967cc0636SGreg Clayton }
32067cc0636SGreg Clayton 
32167cc0636SGreg Clayton bool
32267cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
32367cc0636SGreg Clayton {
32467cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
32567cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
32667cc0636SGreg Clayton }
32767cc0636SGreg Clayton 
328c3ce7f27SMichael Sartain bool
329c3ce7f27SMichael Sartain Debugger::GetUseColor () const
330c3ce7f27SMichael Sartain {
331c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
332c3ce7f27SMichael Sartain     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
333c3ce7f27SMichael Sartain }
334c3ce7f27SMichael Sartain 
335c3ce7f27SMichael Sartain bool
336c3ce7f27SMichael Sartain Debugger::SetUseColor (bool b)
337c3ce7f27SMichael Sartain {
338c3ce7f27SMichael Sartain     const uint32_t idx = ePropertyUseColor;
339c3ce7f27SMichael Sartain     bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
340c3ce7f27SMichael Sartain     SetPrompt (GetPrompt());
341c3ce7f27SMichael Sartain     return ret;
342c3ce7f27SMichael Sartain }
343c3ce7f27SMichael Sartain 
34467cc0636SGreg Clayton uint32_t
34567cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
34667cc0636SGreg Clayton {
34767cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
348754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
34967cc0636SGreg Clayton }
35067cc0636SGreg Clayton 
35167cc0636SGreg Clayton Debugger::StopDisassemblyType
35267cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
35367cc0636SGreg Clayton {
35467cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
355754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
35667cc0636SGreg Clayton }
35767cc0636SGreg Clayton 
35867cc0636SGreg Clayton uint32_t
35967cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
36067cc0636SGreg Clayton {
36167cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
362754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
36367cc0636SGreg Clayton }
364e372b98dSGreg Clayton 
365553fad5cSEnrico Granata bool
36690a8db30SEnrico Granata Debugger::GetAutoOneLineSummaries () const
367553fad5cSEnrico Granata {
36890a8db30SEnrico Granata     const uint32_t idx = ePropertyAutoOneLineSummaries;
369553fad5cSEnrico Granata     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
370553fad5cSEnrico Granata 
371553fad5cSEnrico Granata }
372553fad5cSEnrico Granata 
3731b654882SGreg Clayton #pragma mark Debugger
3741b654882SGreg Clayton 
37567cc0636SGreg Clayton //const DebuggerPropertiesSP &
37667cc0636SGreg Clayton //Debugger::GetSettings() const
37767cc0636SGreg Clayton //{
37867cc0636SGreg Clayton //    return m_properties_sp;
37967cc0636SGreg Clayton //}
38067cc0636SGreg Clayton //
38199d0faf2SGreg Clayton 
3822f88aadfSCaroline Tice int
3832f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
3842f88aadfSCaroline Tice {
3852f88aadfSCaroline Tice     return g_shared_debugger_refcount;
3862f88aadfSCaroline Tice }
3872f88aadfSCaroline Tice 
38830fdc8d8SChris Lattner void
3895fb8f797SGreg Clayton Debugger::Initialize (LoadPluginCallbackType load_plugin_callback)
39030fdc8d8SChris Lattner {
3915fb8f797SGreg Clayton     g_load_plugin_callback = load_plugin_callback;
392c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
393dbe54508SGreg Clayton         lldb_private::Initialize();
39499d0faf2SGreg Clayton }
39530fdc8d8SChris Lattner 
39630fdc8d8SChris Lattner void
39730fdc8d8SChris Lattner Debugger::Terminate ()
39830fdc8d8SChris Lattner {
3996611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
4006611103cSGreg Clayton     {
40130fdc8d8SChris Lattner         g_shared_debugger_refcount--;
40230fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
40330fdc8d8SChris Lattner         {
404dbe54508SGreg Clayton             lldb_private::WillTerminate();
405dbe54508SGreg Clayton             lldb_private::Terminate();
4066760a517SCaroline Tice 
40799d0faf2SGreg Clayton             // Clear our master list of debugger objects
40899d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
40999d0faf2SGreg Clayton             GetDebuggerList().clear();
41030fdc8d8SChris Lattner         }
4116760a517SCaroline Tice     }
4126760a517SCaroline Tice }
41330fdc8d8SChris Lattner 
41420bd37f7SCaroline Tice void
41520bd37f7SCaroline Tice Debugger::SettingsInitialize ()
41620bd37f7SCaroline Tice {
4176920b52bSGreg Clayton     Target::SettingsInitialize ();
41820bd37f7SCaroline Tice }
41920bd37f7SCaroline Tice 
42020bd37f7SCaroline Tice void
42120bd37f7SCaroline Tice Debugger::SettingsTerminate ()
42220bd37f7SCaroline Tice {
4236920b52bSGreg Clayton     Target::SettingsTerminate ();
42420bd37f7SCaroline Tice }
42520bd37f7SCaroline Tice 
42621dfcd9dSEnrico Granata bool
427e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
42821dfcd9dSEnrico Granata {
4295fb8f797SGreg Clayton     if (g_load_plugin_callback)
430e743c782SEnrico Granata     {
43158a559c0SZachary Turner         llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
43258a559c0SZachary Turner         if (dynlib.isValid())
43321dfcd9dSEnrico Granata         {
43458a559c0SZachary Turner             m_loaded_plugins.push_back(dynlib);
43521dfcd9dSEnrico Granata             return true;
43621dfcd9dSEnrico Granata         }
4375fb8f797SGreg Clayton     }
4385fb8f797SGreg Clayton     else
4395fb8f797SGreg Clayton     {
4405fb8f797SGreg Clayton         // The g_load_plugin_callback is registered in SBDebugger::Initialize()
4415fb8f797SGreg Clayton         // and if the public API layer isn't available (code is linking against
4425fb8f797SGreg Clayton         // all of the internal LLDB static libraries), then we can't load plugins
4435fb8f797SGreg Clayton         error.SetErrorString("Public API layer is not available");
4445fb8f797SGreg Clayton     }
44521dfcd9dSEnrico Granata     return false;
44621dfcd9dSEnrico Granata }
44721dfcd9dSEnrico Granata 
44821dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
44921dfcd9dSEnrico Granata LoadPluginCallback
45021dfcd9dSEnrico Granata (
45121dfcd9dSEnrico Granata  void *baton,
45221dfcd9dSEnrico Granata  FileSpec::FileType file_type,
45321dfcd9dSEnrico Granata  const FileSpec &file_spec
45421dfcd9dSEnrico Granata  )
45521dfcd9dSEnrico Granata {
45621dfcd9dSEnrico Granata     Error error;
45721dfcd9dSEnrico Granata 
45821dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
4593cf443ddSMichael Sartain     static ConstString g_solibext("so");
46021dfcd9dSEnrico Granata 
46121dfcd9dSEnrico Granata     if (!baton)
46221dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
46321dfcd9dSEnrico Granata 
46421dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
46521dfcd9dSEnrico Granata 
46621dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
46721dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
46821dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
46921dfcd9dSEnrico Granata     // file type information.
47021dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
47121dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
47221dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
47321dfcd9dSEnrico Granata     {
47421dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
47521dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
47621dfcd9dSEnrico Granata 
4773cf443ddSMichael Sartain         if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
4783cf443ddSMichael Sartain             plugin_file_spec.GetFileNameExtension() != g_solibext)
4793cf443ddSMichael Sartain         {
48021dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
4813cf443ddSMichael Sartain         }
48221dfcd9dSEnrico Granata 
483e743c782SEnrico Granata         Error plugin_load_error;
484e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
48521dfcd9dSEnrico Granata 
48621dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
48721dfcd9dSEnrico Granata     }
48821dfcd9dSEnrico Granata 
48921dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
49021dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
49121dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
49221dfcd9dSEnrico Granata     {
49321dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
49421dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
4956a7f3338SBruce Mitchener         // might be enumerating a file system that doesn't have correct file type
49621dfcd9dSEnrico Granata         // information.
49721dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
49821dfcd9dSEnrico Granata     }
49921dfcd9dSEnrico Granata 
50021dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
50121dfcd9dSEnrico Granata }
50221dfcd9dSEnrico Granata 
50321dfcd9dSEnrico Granata void
50421dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
50521dfcd9dSEnrico Granata {
50621dfcd9dSEnrico Granata     FileSpec dir_spec;
50721dfcd9dSEnrico Granata     const bool find_directories = true;
50821dfcd9dSEnrico Granata     const bool find_files = true;
50921dfcd9dSEnrico Granata     const bool find_other = true;
51021dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
51142ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
51221dfcd9dSEnrico Granata     {
51321dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
51421dfcd9dSEnrico Granata         {
51521dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
51621dfcd9dSEnrico Granata                                           find_directories,
51721dfcd9dSEnrico Granata                                           find_files,
51821dfcd9dSEnrico Granata                                           find_other,
51921dfcd9dSEnrico Granata                                           LoadPluginCallback,
52021dfcd9dSEnrico Granata                                           this);
52121dfcd9dSEnrico Granata         }
52221dfcd9dSEnrico Granata     }
52321dfcd9dSEnrico Granata 
52442ff0ad8SZachary Turner     if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
52521dfcd9dSEnrico Granata     {
52621dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
52721dfcd9dSEnrico Granata         {
52821dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
52921dfcd9dSEnrico Granata                                           find_directories,
53021dfcd9dSEnrico Granata                                           find_files,
53121dfcd9dSEnrico Granata                                           find_other,
53221dfcd9dSEnrico Granata                                           LoadPluginCallback,
53321dfcd9dSEnrico Granata                                           this);
53421dfcd9dSEnrico Granata         }
53521dfcd9dSEnrico Granata     }
536e8cd0c98SGreg Clayton 
537e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
53821dfcd9dSEnrico Granata }
53921dfcd9dSEnrico Granata 
5406611103cSGreg Clayton DebuggerSP
541228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
5426611103cSGreg Clayton {
543228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
544c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
5456611103cSGreg Clayton     {
5466611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5476611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
5486611103cSGreg Clayton     }
54921dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
5506611103cSGreg Clayton     return debugger_sp;
5516611103cSGreg Clayton }
5526611103cSGreg Clayton 
553e02657b1SCaroline Tice void
5544d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
555e02657b1SCaroline Tice {
556e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
557e02657b1SCaroline Tice         return;
558e02657b1SCaroline Tice 
5598314c525SJim Ingham     debugger_sp->Clear();
5608314c525SJim Ingham 
561c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
562c15f55e2SGreg Clayton     {
563e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
564e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
565e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
566e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
567e02657b1SCaroline Tice         {
568e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
569e02657b1SCaroline Tice             {
570e02657b1SCaroline Tice                 debugger_list.erase (pos);
571e02657b1SCaroline Tice                 return;
572e02657b1SCaroline Tice             }
573e02657b1SCaroline Tice         }
574e02657b1SCaroline Tice     }
575c15f55e2SGreg Clayton }
576e02657b1SCaroline Tice 
5774d122c40SGreg Clayton DebuggerSP
5783df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5793df9a8dfSCaroline Tice {
5804d122c40SGreg Clayton     DebuggerSP debugger_sp;
5816920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
5826920b52bSGreg Clayton     {
5836920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5846920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5856920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5866920b52bSGreg Clayton 
5876920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5886920b52bSGreg Clayton         {
5896920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
5906920b52bSGreg Clayton             {
5916920b52bSGreg Clayton                 debugger_sp = *pos;
5926920b52bSGreg Clayton                 break;
5936920b52bSGreg Clayton             }
5946920b52bSGreg Clayton         }
5956920b52bSGreg Clayton     }
5963df9a8dfSCaroline Tice     return debugger_sp;
5973df9a8dfSCaroline Tice }
5986611103cSGreg Clayton 
5996611103cSGreg Clayton TargetSP
6006611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
6016611103cSGreg Clayton {
6024d122c40SGreg Clayton     TargetSP target_sp;
603c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
604c15f55e2SGreg Clayton     {
6056611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
6066611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
6076611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
6086611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
6096611103cSGreg Clayton         {
6106611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
6116611103cSGreg Clayton             if (target_sp)
6126611103cSGreg Clayton                 break;
6136611103cSGreg Clayton         }
614c15f55e2SGreg Clayton     }
6156611103cSGreg Clayton     return target_sp;
6166611103cSGreg Clayton }
6176611103cSGreg Clayton 
618e4e45924SGreg Clayton TargetSP
619e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
620e4e45924SGreg Clayton {
621e4e45924SGreg Clayton     TargetSP target_sp;
622c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
623c15f55e2SGreg Clayton     {
624e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
625e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
626e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
627e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
628e4e45924SGreg Clayton         {
629e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
630e4e45924SGreg Clayton             if (target_sp)
631e4e45924SGreg Clayton                 break;
632e4e45924SGreg Clayton         }
633c15f55e2SGreg Clayton     }
634e4e45924SGreg Clayton     return target_sp;
635e4e45924SGreg Clayton }
636e4e45924SGreg Clayton 
637e6481c7eSJason Molenda Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
638e6481c7eSJason Molenda     UserID(g_unique_id++),
639e6481c7eSJason Molenda     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
640e6481c7eSJason Molenda     m_input_file_sp(new StreamFile(stdin, false)),
641e6481c7eSJason Molenda     m_output_file_sp(new StreamFile(stdout, false)),
642e6481c7eSJason Molenda     m_error_file_sp(new StreamFile(stderr, false)),
643e6481c7eSJason Molenda     m_terminal_state(),
644e6481c7eSJason Molenda     m_target_list(*this),
645e6481c7eSJason Molenda     m_platform_list(),
646e6481c7eSJason Molenda     m_listener("lldb.Debugger"),
647e6481c7eSJason Molenda     m_source_manager_ap(),
648e6481c7eSJason Molenda     m_source_file_cache(),
649e6481c7eSJason Molenda     m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
650e6481c7eSJason Molenda     m_input_reader_stack(),
651e6481c7eSJason Molenda     m_instance_name(),
652e6481c7eSJason Molenda     m_loaded_plugins()
65330fdc8d8SChris Lattner {
65467cc0636SGreg Clayton     char instance_cstr[256];
65567cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
65667cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
657228063cdSJim Ingham     if (log_callback)
658228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
6596611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
660ded470d3SGreg Clayton     // Always add our default platform to the platform list
661615eb7e6SGreg Clayton     PlatformSP default_platform_sp (Platform::GetHostPlatform());
662ded470d3SGreg Clayton     assert (default_platform_sp.get());
663ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
66467cc0636SGreg Clayton 
665754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
66667cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
66767cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
66867cc0636SGreg Clayton                                      true,
66967cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
670754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
671754a9369SGreg Clayton     {
672754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
673754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
674754a9369SGreg Clayton                                          true,
675754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
676754a9369SGreg Clayton     }
67767cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
67867cc0636SGreg Clayton     term_width->SetMinimumValue(10);
67967cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
680c3ce7f27SMichael Sartain 
681c3ce7f27SMichael Sartain     // Turn off use-color if this is a dumb terminal.
682c3ce7f27SMichael Sartain     const char *term = getenv ("TERM");
683c3ce7f27SMichael Sartain     if (term && !strcmp (term, "dumb"))
684c3ce7f27SMichael Sartain         SetUseColor (false);
68530fdc8d8SChris Lattner }
68630fdc8d8SChris Lattner 
68730fdc8d8SChris Lattner Debugger::~Debugger ()
68830fdc8d8SChris Lattner {
6898314c525SJim Ingham     Clear();
6908314c525SJim Ingham }
6918314c525SJim Ingham 
6928314c525SJim Ingham void
6938314c525SJim Ingham Debugger::Clear()
6948314c525SJim Ingham {
69544d93782SGreg Clayton     ClearIOHandlers();
69644d93782SGreg Clayton     StopIOHandlerThread();
69744d93782SGreg Clayton     StopEventHandlerThread();
6981ed54f50SGreg Clayton     m_listener.Clear();
6996611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
7006611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
7016611103cSGreg Clayton     {
702ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
703ccbc08e6SGreg Clayton         if (target_sp)
704ccbc08e6SGreg Clayton         {
705ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
7066611103cSGreg Clayton             if (process_sp)
7071fd07059SJim Ingham                 process_sp->Finalize();
708ccbc08e6SGreg Clayton             target_sp->Destroy();
7096611103cSGreg Clayton         }
71030fdc8d8SChris Lattner     }
7114bddaeb5SJim Ingham     BroadcasterManager::Clear ();
71230fdc8d8SChris Lattner 
7130d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
7140d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
715c5917d9aSJim Ingham     m_terminal_state.Clear();
71644d93782SGreg Clayton     if (m_input_file_sp)
71744d93782SGreg Clayton         m_input_file_sp->GetFile().Close ();
7180c4129f2SGreg Clayton 
7190c4129f2SGreg Clayton     m_command_interpreter_ap->Clear();
7208314c525SJim Ingham }
72130fdc8d8SChris Lattner 
72230fdc8d8SChris Lattner bool
723fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
724fc3f027dSGreg Clayton {
72544d93782SGreg Clayton //    return m_input_comm.GetCloseOnEOF();
72644d93782SGreg Clayton     return false;
727fc3f027dSGreg Clayton }
728fc3f027dSGreg Clayton 
729fc3f027dSGreg Clayton void
730fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
731fc3f027dSGreg Clayton {
73244d93782SGreg Clayton //    m_input_comm.SetCloseOnEOF(b);
733fc3f027dSGreg Clayton }
734fc3f027dSGreg Clayton 
735fc3f027dSGreg Clayton bool
73630fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
73730fdc8d8SChris Lattner {
7386611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
73930fdc8d8SChris Lattner }
74030fdc8d8SChris Lattner 
74130fdc8d8SChris Lattner void
74230fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
74330fdc8d8SChris Lattner {
7446611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
74530fdc8d8SChris Lattner }
74630fdc8d8SChris Lattner 
74730fdc8d8SChris Lattner 
74830fdc8d8SChris Lattner void
74930fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
75030fdc8d8SChris Lattner {
75144d93782SGreg Clayton     if (m_input_file_sp)
75244d93782SGreg Clayton         m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
75344d93782SGreg Clayton     else
75444d93782SGreg Clayton         m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
75544d93782SGreg Clayton 
75644d93782SGreg Clayton     File &in_file = m_input_file_sp->GetFile();
75751b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
75851b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
75930fdc8d8SChris Lattner 
760c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
761c5917d9aSJim Ingham     SaveInputTerminalState ();
76230fdc8d8SChris Lattner }
76330fdc8d8SChris Lattner 
76430fdc8d8SChris Lattner void
76530fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
76630fdc8d8SChris Lattner {
76744d93782SGreg Clayton     if (m_output_file_sp)
76844d93782SGreg Clayton         m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
76944d93782SGreg Clayton     else
77044d93782SGreg Clayton         m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
77144d93782SGreg Clayton 
77244d93782SGreg Clayton     File &out_file = m_output_file_sp->GetFile();
77351b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
77451b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7752f88aadfSCaroline Tice 
776b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
777b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
778b588726eSEnrico Granata     const bool can_create = false;
779b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
780b588726eSEnrico Granata     if (script_interpreter)
781b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
78230fdc8d8SChris Lattner }
78330fdc8d8SChris Lattner 
78430fdc8d8SChris Lattner void
78530fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
78630fdc8d8SChris Lattner {
78744d93782SGreg Clayton     if (m_error_file_sp)
78844d93782SGreg Clayton         m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
78944d93782SGreg Clayton     else
79044d93782SGreg Clayton         m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
79144d93782SGreg Clayton 
79244d93782SGreg Clayton     File &err_file = m_error_file_sp->GetFile();
79351b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
79451b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
79530fdc8d8SChris Lattner }
79630fdc8d8SChris Lattner 
797c5917d9aSJim Ingham void
798c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
799c5917d9aSJim Ingham {
80044d93782SGreg Clayton     if (m_input_file_sp)
80144d93782SGreg Clayton     {
80244d93782SGreg Clayton         File &in_file = m_input_file_sp->GetFile();
803c5917d9aSJim Ingham         if (in_file.GetDescriptor() != File::kInvalidDescriptor)
804c5917d9aSJim Ingham             m_terminal_state.Save(in_file.GetDescriptor(), true);
805c5917d9aSJim Ingham     }
80644d93782SGreg Clayton }
807c5917d9aSJim Ingham 
808c5917d9aSJim Ingham void
809c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
810c5917d9aSJim Ingham {
811c5917d9aSJim Ingham     m_terminal_state.Restore();
812c5917d9aSJim Ingham }
813c5917d9aSJim Ingham 
81430fdc8d8SChris Lattner ExecutionContext
8152976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
81630fdc8d8SChris Lattner {
81730fdc8d8SChris Lattner     ExecutionContext exe_ctx;
818c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
819c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
82030fdc8d8SChris Lattner 
82130fdc8d8SChris Lattner     if (target_sp)
82230fdc8d8SChris Lattner     {
823c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
824c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
825c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
82630fdc8d8SChris Lattner         {
827c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
828c14ee32dSGreg Clayton             if (thread_sp)
82930fdc8d8SChris Lattner             {
830c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
831c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
832c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
833c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
83430fdc8d8SChris Lattner             }
83530fdc8d8SChris Lattner         }
83630fdc8d8SChris Lattner     }
83730fdc8d8SChris Lattner     return exe_ctx;
83830fdc8d8SChris Lattner }
83930fdc8d8SChris Lattner 
84030fdc8d8SChris Lattner void
841efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
842efed6131SCaroline Tice {
84344d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
84444d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
845efed6131SCaroline Tice     if (reader_sp)
84644d93782SGreg Clayton         reader_sp->Interrupt();
847efed6131SCaroline Tice }
848efed6131SCaroline Tice 
849efed6131SCaroline Tice void
850efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
851efed6131SCaroline Tice {
85244d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
85344d93782SGreg Clayton     IOHandlerSP reader_sp (m_input_reader_stack.Top());
854efed6131SCaroline Tice     if (reader_sp)
85544d93782SGreg Clayton         reader_sp->GotEOF();
856efed6131SCaroline Tice }
857efed6131SCaroline Tice 
858efed6131SCaroline Tice void
85944d93782SGreg Clayton Debugger::ClearIOHandlers ()
8603d6086f6SCaroline Tice {
861b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
86244d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
863d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8643d6086f6SCaroline Tice     {
86544d93782SGreg Clayton         IOHandlerSP reader_sp (m_input_reader_stack.Top());
8663d6086f6SCaroline Tice         if (reader_sp)
8673d6086f6SCaroline Tice         {
86844d93782SGreg Clayton             m_input_reader_stack.Pop();
8693d6086f6SCaroline Tice             reader_sp->SetIsDone(true);
870e68f5d6bSGreg Clayton             reader_sp->Cancel();
8713d6086f6SCaroline Tice         }
8723d6086f6SCaroline Tice     }
8733d6086f6SCaroline Tice }
8743d6086f6SCaroline Tice 
8753d6086f6SCaroline Tice void
87644d93782SGreg Clayton Debugger::ExecuteIOHanders()
877969ed3d1SCaroline Tice {
87844d93782SGreg Clayton 
87944d93782SGreg Clayton     while (1)
880969ed3d1SCaroline Tice     {
88144d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
88230fdc8d8SChris Lattner         if (!reader_sp)
88330fdc8d8SChris Lattner             break;
88430fdc8d8SChris Lattner 
88544d93782SGreg Clayton         reader_sp->Activate();
88644d93782SGreg Clayton         reader_sp->Run();
88744d93782SGreg Clayton         reader_sp->Deactivate();
88844d93782SGreg Clayton 
88944d93782SGreg Clayton         // Remove all input readers that are done from the top of the stack
89044d93782SGreg Clayton         while (1)
89130fdc8d8SChris Lattner         {
89244d93782SGreg Clayton             IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
89344d93782SGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
89444d93782SGreg Clayton                 m_input_reader_stack.Pop();
89530fdc8d8SChris Lattner             else
89630fdc8d8SChris Lattner                 break;
89730fdc8d8SChris Lattner         }
89830fdc8d8SChris Lattner     }
89944d93782SGreg Clayton     ClearIOHandlers();
90044d93782SGreg Clayton }
90130fdc8d8SChris Lattner 
90244d93782SGreg Clayton bool
90344d93782SGreg Clayton Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
90444d93782SGreg Clayton {
90544d93782SGreg Clayton     return m_input_reader_stack.IsTop (reader_sp);
90644d93782SGreg Clayton }
90730fdc8d8SChris Lattner 
90844d93782SGreg Clayton 
90944d93782SGreg Clayton ConstString
91044d93782SGreg Clayton Debugger::GetTopIOHandlerControlSequence(char ch)
91144d93782SGreg Clayton {
91244d93782SGreg Clayton     return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
91330fdc8d8SChris Lattner }
91430fdc8d8SChris Lattner 
91530fdc8d8SChris Lattner void
91644d93782SGreg Clayton Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
91744d93782SGreg Clayton {
91844d93782SGreg Clayton     PushIOHandler (reader_sp);
919577508dfSGreg Clayton 
920577508dfSGreg Clayton     IOHandlerSP top_reader_sp = reader_sp;
921577508dfSGreg Clayton     while (top_reader_sp)
922577508dfSGreg Clayton     {
923577508dfSGreg Clayton         top_reader_sp->Activate();
924577508dfSGreg Clayton         top_reader_sp->Run();
925577508dfSGreg Clayton         top_reader_sp->Deactivate();
926577508dfSGreg Clayton 
927577508dfSGreg Clayton         if (top_reader_sp.get() == reader_sp.get())
928577508dfSGreg Clayton         {
929577508dfSGreg Clayton             if (PopIOHandler (reader_sp))
930577508dfSGreg Clayton                 break;
931577508dfSGreg Clayton         }
932577508dfSGreg Clayton 
933577508dfSGreg Clayton         while (1)
934577508dfSGreg Clayton         {
935577508dfSGreg Clayton             top_reader_sp = m_input_reader_stack.Top();
936577508dfSGreg Clayton             if (top_reader_sp && top_reader_sp->GetIsDone())
937577508dfSGreg Clayton                 m_input_reader_stack.Pop();
938577508dfSGreg Clayton             else
939577508dfSGreg Clayton                 break;
940577508dfSGreg Clayton         }
941577508dfSGreg Clayton     }
94244d93782SGreg Clayton }
94344d93782SGreg Clayton 
94444d93782SGreg Clayton void
94544d93782SGreg Clayton Debugger::AdoptTopIOHandlerFilesIfInvalid (StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
94644d93782SGreg Clayton {
94744d93782SGreg Clayton     // Before an IOHandler runs, it must have in/out/err streams.
94844d93782SGreg Clayton     // This function is called when one ore more of the streams
94944d93782SGreg Clayton     // are NULL. We use the top input reader's in/out/err streams,
95044d93782SGreg Clayton     // or fall back to the debugger file handles, or we fall back
95144d93782SGreg Clayton     // onto stdin/stdout/stderr as a last resort.
95244d93782SGreg Clayton 
95344d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
95444d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
95544d93782SGreg Clayton     // If no STDIN has been set, then set it appropriately
95644d93782SGreg Clayton     if (!in)
95744d93782SGreg Clayton     {
95844d93782SGreg Clayton         if (top_reader_sp)
95944d93782SGreg Clayton             in = top_reader_sp->GetInputStreamFile();
96044d93782SGreg Clayton         else
96144d93782SGreg Clayton             in = GetInputFile();
96244d93782SGreg Clayton 
96344d93782SGreg Clayton         // If there is nothing, use stdin
96444d93782SGreg Clayton         if (!in)
96544d93782SGreg Clayton             in = StreamFileSP(new StreamFile(stdin, false));
96644d93782SGreg Clayton     }
96744d93782SGreg Clayton     // If no STDOUT has been set, then set it appropriately
96844d93782SGreg Clayton     if (!out)
96944d93782SGreg Clayton     {
97044d93782SGreg Clayton         if (top_reader_sp)
97144d93782SGreg Clayton             out = top_reader_sp->GetOutputStreamFile();
97244d93782SGreg Clayton         else
97344d93782SGreg Clayton             out = GetOutputFile();
97444d93782SGreg Clayton 
97544d93782SGreg Clayton         // If there is nothing, use stdout
97644d93782SGreg Clayton         if (!out)
97744d93782SGreg Clayton             out = StreamFileSP(new StreamFile(stdout, false));
97844d93782SGreg Clayton     }
97944d93782SGreg Clayton     // If no STDERR has been set, then set it appropriately
98044d93782SGreg Clayton     if (!err)
98144d93782SGreg Clayton     {
98244d93782SGreg Clayton         if (top_reader_sp)
98344d93782SGreg Clayton             err = top_reader_sp->GetErrorStreamFile();
98444d93782SGreg Clayton         else
98544d93782SGreg Clayton             err = GetErrorFile();
98644d93782SGreg Clayton 
98744d93782SGreg Clayton         // If there is nothing, use stderr
98844d93782SGreg Clayton         if (!err)
98944d93782SGreg Clayton             err = StreamFileSP(new StreamFile(stdout, false));
99044d93782SGreg Clayton 
99144d93782SGreg Clayton     }
99244d93782SGreg Clayton }
99344d93782SGreg Clayton 
99444d93782SGreg Clayton void
99544d93782SGreg Clayton Debugger::PushIOHandler (const IOHandlerSP& reader_sp)
99630fdc8d8SChris Lattner {
99730fdc8d8SChris Lattner     if (!reader_sp)
99830fdc8d8SChris Lattner         return;
999b44880caSCaroline Tice 
100044d93782SGreg Clayton     // Got the current top input reader...
100144d93782SGreg Clayton     IOHandlerSP top_reader_sp (m_input_reader_stack.Top());
1002b44880caSCaroline Tice 
1003b4874f1aSGreg Clayton     // Don't push the same IO handler twice...
1004b4874f1aSGreg Clayton     if (reader_sp.get() != top_reader_sp.get())
1005b4874f1aSGreg Clayton     {
100644d93782SGreg Clayton         // Push our new input reader
1007d5a0a01bSCaroline Tice         m_input_reader_stack.Push (reader_sp);
100844d93782SGreg Clayton 
100944d93782SGreg Clayton         // Interrupt the top input reader to it will exit its Run() function
101044d93782SGreg Clayton         // and let this new input reader take over
101144d93782SGreg Clayton         if (top_reader_sp)
101244d93782SGreg Clayton             top_reader_sp->Deactivate();
101330fdc8d8SChris Lattner     }
1014b4874f1aSGreg Clayton }
101530fdc8d8SChris Lattner 
101630fdc8d8SChris Lattner bool
101744d93782SGreg Clayton Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp)
101830fdc8d8SChris Lattner {
101930fdc8d8SChris Lattner     bool result = false;
102030fdc8d8SChris Lattner 
102144d93782SGreg Clayton     Mutex::Locker locker (m_input_reader_stack.GetMutex());
102244d93782SGreg Clayton 
102330fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
10246a7f3338SBruce Mitchener     // read on the stack refresh its prompt and if there is one...
1025d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
102630fdc8d8SChris Lattner     {
102744d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
102830fdc8d8SChris Lattner 
102930fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
103030fdc8d8SChris Lattner         {
103144d93782SGreg Clayton             reader_sp->Deactivate();
1032b4874f1aSGreg Clayton             reader_sp->Cancel();
1033d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
103430fdc8d8SChris Lattner 
1035d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
103630fdc8d8SChris Lattner             if (reader_sp)
103744d93782SGreg Clayton                 reader_sp->Activate();
103844d93782SGreg Clayton 
103944d93782SGreg Clayton             result = true;
104030fdc8d8SChris Lattner         }
104130fdc8d8SChris Lattner     }
104230fdc8d8SChris Lattner     return result;
104330fdc8d8SChris Lattner }
104430fdc8d8SChris Lattner 
104530fdc8d8SChris Lattner bool
104644d93782SGreg Clayton Debugger::HideTopIOHandler()
104730fdc8d8SChris Lattner {
104844d93782SGreg Clayton     Mutex::Locker locker;
104930fdc8d8SChris Lattner 
105044d93782SGreg Clayton     if (locker.TryLock(m_input_reader_stack.GetMutex()))
105130fdc8d8SChris Lattner     {
105244d93782SGreg Clayton         IOHandlerSP reader_sp(m_input_reader_stack.Top());
105344d93782SGreg Clayton         if (reader_sp)
105444d93782SGreg Clayton             reader_sp->Hide();
105544d93782SGreg Clayton         return true;
105630fdc8d8SChris Lattner     }
105744d93782SGreg Clayton     return false;
105830fdc8d8SChris Lattner }
105930fdc8d8SChris Lattner 
106030fdc8d8SChris Lattner void
106144d93782SGreg Clayton Debugger::RefreshTopIOHandler()
106230fdc8d8SChris Lattner {
106344d93782SGreg Clayton     IOHandlerSP reader_sp(m_input_reader_stack.Top());
106444d93782SGreg Clayton     if (reader_sp)
106544d93782SGreg Clayton         reader_sp->Refresh();
106630fdc8d8SChris Lattner }
106744d93782SGreg Clayton 
10686611103cSGreg Clayton 
10695b52f0c7SJim Ingham StreamSP
10705b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
10715b52f0c7SJim Ingham {
10725b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10735b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
10745b52f0c7SJim Ingham }
10755b52f0c7SJim Ingham 
10765b52f0c7SJim Ingham StreamSP
10775b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
10785b52f0c7SJim Ingham {
10795b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10805b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
10815b52f0c7SJim Ingham }
10825b52f0c7SJim Ingham 
1083c7bece56SGreg Clayton size_t
1084061858ceSEnrico Granata Debugger::GetNumDebuggers()
1085061858ceSEnrico Granata {
1086c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1087c15f55e2SGreg Clayton     {
1088061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1089061858ceSEnrico Granata         return GetDebuggerList().size();
1090061858ceSEnrico Granata     }
1091c15f55e2SGreg Clayton     return 0;
1092c15f55e2SGreg Clayton }
1093061858ceSEnrico Granata 
1094061858ceSEnrico Granata lldb::DebuggerSP
1095c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1096061858ceSEnrico Granata {
1097061858ceSEnrico Granata     DebuggerSP debugger_sp;
1098061858ceSEnrico Granata 
1099c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1100c15f55e2SGreg Clayton     {
1101061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1102061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1103061858ceSEnrico Granata 
1104061858ceSEnrico Granata         if (index < debugger_list.size())
1105061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1106c15f55e2SGreg Clayton     }
1107061858ceSEnrico Granata 
1108061858ceSEnrico Granata     return debugger_sp;
1109061858ceSEnrico Granata }
1110061858ceSEnrico Granata 
1111ebc1bb27SCaroline Tice DebuggerSP
1112ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1113ebc1bb27SCaroline Tice {
11144d122c40SGreg Clayton     DebuggerSP debugger_sp;
1115ebc1bb27SCaroline Tice 
1116c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1117c15f55e2SGreg Clayton     {
1118ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1119ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1120ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1121ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1122ebc1bb27SCaroline Tice         {
1123ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1124ebc1bb27SCaroline Tice             {
1125ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1126ebc1bb27SCaroline Tice                 break;
1127ebc1bb27SCaroline Tice             }
1128ebc1bb27SCaroline Tice         }
1129c15f55e2SGreg Clayton     }
1130ebc1bb27SCaroline Tice     return debugger_sp;
1131ebc1bb27SCaroline Tice }
11323df9a8dfSCaroline Tice 
11332643b905SSaleem Abdulrasool #if 0
11341b654882SGreg Clayton static void
1135b57e4a1bSJason Molenda TestPromptFormats (StackFrame *frame)
11361b654882SGreg Clayton {
11371b654882SGreg Clayton     if (frame == NULL)
11381b654882SGreg Clayton         return;
11391b654882SGreg Clayton 
11401b654882SGreg Clayton     StreamString s;
11411b654882SGreg Clayton     const char *prompt_format =
11421b654882SGreg Clayton     "{addr = '${addr}'\n}"
1143aff1b357SJason Molenda     "{addr-file-or-load = '${addr-file-or-load}'\n}"
1144aff1b357SJason Molenda     "{current-pc-arrow = '${current-pc-arrow}'\n}"
11451b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
11461b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
11471b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
11481b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
11491b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
11501b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
11511b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
11521b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
11531b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
11541b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
11551b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
11561b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
11571b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
11581b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
11591b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
11601b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
11611b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
11621b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
11631b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
11641b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
11651b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
11661b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
11671b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
11681b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
11691b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
11701b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
11711b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
1172aff1b357SJason Molenda     "{function.changed = '${function.changed}'\n}"
1173aff1b357SJason Molenda     "{function.initial-function = '${function.initial-function}'\n}"
11741b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1175aff1b357SJason Molenda     "{function.name-without-args = '${function.name-without-args}'\n}"
1176ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
11771b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
1178aff1b357SJason Molenda     "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
11791b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
11801b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
11811b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
11821b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
11831b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
11841b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
11851b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
11861b654882SGreg Clayton ;
11871b654882SGreg Clayton 
11881b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
11891b654882SGreg Clayton     ExecutionContext exe_ctx;
11900603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
1191c3ce7f27SMichael Sartain     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s))
11921b654882SGreg Clayton     {
11931b654882SGreg Clayton         printf("%s\n", s.GetData());
11941b654882SGreg Clayton     }
11951b654882SGreg Clayton     else
11961b654882SGreg Clayton     {
11971b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
11981b654882SGreg Clayton     }
11991b654882SGreg Clayton }
12002643b905SSaleem Abdulrasool #endif
12011b654882SGreg Clayton 
12029fc1944eSEnrico Granata static bool
12039fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin,
12049fc1944eSEnrico Granata                       const char* var_name_end,
12059fc1944eSEnrico Granata                       const char** var_name_final,
12069fc1944eSEnrico Granata                       const char** percent_position,
12074d122c40SGreg Clayton                       Format* custom_format,
12089fc1944eSEnrico Granata                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
12099fc1944eSEnrico Granata {
12105160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12119fc1944eSEnrico Granata     *percent_position = ::strchr(var_name_begin,'%');
12129fc1944eSEnrico Granata     if (!*percent_position || *percent_position > var_name_end)
1213e992a089SEnrico Granata     {
1214e992a089SEnrico Granata         if (log)
1215d228483dSEnrico Granata             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
12169fc1944eSEnrico Granata         *var_name_final = var_name_end;
1217e992a089SEnrico Granata     }
12189fc1944eSEnrico Granata     else
12199fc1944eSEnrico Granata     {
12209fc1944eSEnrico Granata         *var_name_final = *percent_position;
122136aa5ae6SEnrico Granata         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1222e992a089SEnrico Granata         if (log)
122368ae4117SEnrico Granata             log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
122436aa5ae6SEnrico Granata         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
12259fc1944eSEnrico Granata                                                   true,
12269fc1944eSEnrico Granata                                                   *custom_format) )
12279fc1944eSEnrico Granata         {
1228e992a089SEnrico Granata             if (log)
122968ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
123036aa5ae6SEnrico Granata 
123136aa5ae6SEnrico Granata             switch (format_name.front())
123236aa5ae6SEnrico Granata             {
123336aa5ae6SEnrico Granata                 case '@':             // if this is an @ sign, print ObjC description
123486cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
123536aa5ae6SEnrico Granata                     break;
123636aa5ae6SEnrico Granata                 case 'V': // if this is a V, print the value using the default format
123786cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
123836aa5ae6SEnrico Granata                     break;
123936aa5ae6SEnrico Granata                 case 'L': // if this is an L, print the location of the value
124086cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
124136aa5ae6SEnrico Granata                     break;
124236aa5ae6SEnrico Granata                 case 'S': // if this is an S, print the summary after all
124386cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
124436aa5ae6SEnrico Granata                     break;
124536aa5ae6SEnrico Granata                 case '#': // if this is a '#', print the number of children
124686cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
124736aa5ae6SEnrico Granata                     break;
124836aa5ae6SEnrico Granata                 case 'T': // if this is a 'T', print the type
124986cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
125036aa5ae6SEnrico Granata                     break;
12512c75f11eSEnrico Granata                 case 'N': // if this is a 'N', print the name
12522c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
12532c75f11eSEnrico Granata                     break;
12542c75f11eSEnrico Granata                 case '>': // if this is a '>', print the name
12552c75f11eSEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
12562c75f11eSEnrico Granata                     break;
125736aa5ae6SEnrico Granata                 default:
12585c42d8a8SJim Ingham                     if (log)
125936aa5ae6SEnrico Granata                         log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
126036aa5ae6SEnrico Granata                     break;
126136aa5ae6SEnrico Granata             }
12629fc1944eSEnrico Granata         }
12639fc1944eSEnrico Granata         // a good custom format tells us to print the value using it
12649fc1944eSEnrico Granata         else
1265e992a089SEnrico Granata         {
1266e992a089SEnrico Granata             if (log)
126768ae4117SEnrico Granata                 log->Printf("[ScanFormatDescriptor] will display value for this VO");
126886cc9829SEnrico Granata             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1269e992a089SEnrico Granata         }
12709fc1944eSEnrico Granata     }
1271e992a089SEnrico Granata     if (log)
127268ae4117SEnrico Granata         log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1273e992a089SEnrico Granata                     *custom_format,
1274e992a089SEnrico Granata                     *val_obj_display);
12759fc1944eSEnrico Granata     return true;
12769fc1944eSEnrico Granata }
12779fc1944eSEnrico Granata 
12789fc1944eSEnrico Granata static bool
12799fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin,
12809fc1944eSEnrico Granata                     const char* var_name_end,
12819fc1944eSEnrico Granata                     const char* var_name_final,
12829fc1944eSEnrico Granata                     const char** open_bracket_position,
12839fc1944eSEnrico Granata                     const char** separator_position,
12849fc1944eSEnrico Granata                     const char** close_bracket_position,
12859fc1944eSEnrico Granata                     const char** var_name_final_if_array_range,
12869fc1944eSEnrico Granata                     int64_t* index_lower,
12879fc1944eSEnrico Granata                     int64_t* index_higher)
12889fc1944eSEnrico Granata {
12895160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12909fc1944eSEnrico Granata     *open_bracket_position = ::strchr(var_name_begin,'[');
12919fc1944eSEnrico Granata     if (*open_bracket_position && *open_bracket_position < var_name_final)
12929fc1944eSEnrico Granata     {
12939fc1944eSEnrico Granata         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
12949fc1944eSEnrico Granata         *close_bracket_position = ::strchr(*open_bracket_position,']');
12959fc1944eSEnrico Granata         // as usual, we assume that [] will come before %
12969fc1944eSEnrico Granata         //printf("trying to expand a []\n");
12979fc1944eSEnrico Granata         *var_name_final_if_array_range = *open_bracket_position;
12989fc1944eSEnrico Granata         if (*close_bracket_position - *open_bracket_position == 1)
12999fc1944eSEnrico Granata         {
1300e992a089SEnrico Granata             if (log)
1301d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
13029fc1944eSEnrico Granata             *index_lower = 0;
13039fc1944eSEnrico Granata         }
13049fc1944eSEnrico Granata         else if (*separator_position == NULL || *separator_position > var_name_end)
13059fc1944eSEnrico Granata         {
13069fc1944eSEnrico Granata             char *end = NULL;
13079fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
13089fc1944eSEnrico Granata             *index_higher = *index_lower;
1309e992a089SEnrico Granata             if (log)
1310d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
13119fc1944eSEnrico Granata         }
13129fc1944eSEnrico Granata         else if (*close_bracket_position && *close_bracket_position < var_name_end)
13139fc1944eSEnrico Granata         {
13149fc1944eSEnrico Granata             char *end = NULL;
13159fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
13169fc1944eSEnrico Granata             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1317e992a089SEnrico Granata             if (log)
1318d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
13199fc1944eSEnrico Granata         }
13209fc1944eSEnrico Granata         else
1321e992a089SEnrico Granata         {
1322e992a089SEnrico Granata             if (log)
1323d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
13249fc1944eSEnrico Granata             return false;
1325e992a089SEnrico Granata         }
13269fc1944eSEnrico Granata         if (*index_lower > *index_higher && *index_higher > 0)
13279fc1944eSEnrico Granata         {
1328e992a089SEnrico Granata             if (log)
1329d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] swapping indices");
1330c7bece56SGreg Clayton             int64_t temp = *index_lower;
13319fc1944eSEnrico Granata             *index_lower = *index_higher;
13329fc1944eSEnrico Granata             *index_higher = temp;
13339fc1944eSEnrico Granata         }
13349fc1944eSEnrico Granata     }
1335e992a089SEnrico Granata     else if (log)
1336d228483dSEnrico Granata             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
13379fc1944eSEnrico Granata     return true;
13389fc1944eSEnrico Granata }
13399fc1944eSEnrico Granata 
13400769b2b1SMichael Sartain template <typename T>
13410769b2b1SMichael Sartain static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
13420769b2b1SMichael Sartain {
13430769b2b1SMichael Sartain     if (script_interpreter)
13440769b2b1SMichael Sartain     {
13450769b2b1SMichael Sartain         Error script_error;
13460769b2b1SMichael Sartain         std::string script_output;
13470769b2b1SMichael Sartain 
13480769b2b1SMichael Sartain         if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
13490769b2b1SMichael Sartain         {
13500769b2b1SMichael Sartain             s.Printf("%s", script_output.c_str());
13510769b2b1SMichael Sartain             return true;
13520769b2b1SMichael Sartain         }
13530769b2b1SMichael Sartain         else
13540769b2b1SMichael Sartain         {
13550769b2b1SMichael Sartain             s.Printf("<error: %s>",script_error.AsCString());
13560769b2b1SMichael Sartain         }
13570769b2b1SMichael Sartain     }
13580769b2b1SMichael Sartain     return false;
13590769b2b1SMichael Sartain }
13600769b2b1SMichael Sartain 
13619fc1944eSEnrico Granata static ValueObjectSP
1362c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj,
1363c7bece56SGreg Clayton                          size_t index,
1364b57e4a1bSJason Molenda                          StackFrame* frame,
1365fc7a7f3bSEnrico Granata                          bool deref_pointer)
13669fc1944eSEnrico Granata {
13675160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1368fc7a7f3bSEnrico Granata     const char* ptr_deref_format = "[%d]";
1369599171adSEnrico Granata     std::string ptr_deref_buffer(10,0);
1370599171adSEnrico Granata     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1371e992a089SEnrico Granata     if (log)
1372599171adSEnrico Granata         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1373fc7a7f3bSEnrico Granata     const char* first_unparsed;
1374fc7a7f3bSEnrico Granata     ValueObject::GetValueForExpressionPathOptions options;
1375fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathEndResultType final_value_type;
1376fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathScanEndReason reason_to_stop;
137786cc9829SEnrico Granata     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1378599171adSEnrico Granata     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1379fc7a7f3bSEnrico Granata                                                           &first_unparsed,
1380fc7a7f3bSEnrico Granata                                                           &reason_to_stop,
1381fc7a7f3bSEnrico Granata                                                           &final_value_type,
1382fc7a7f3bSEnrico Granata                                                           options,
1383fc7a7f3bSEnrico Granata                                                           &what_next);
1384fc7a7f3bSEnrico Granata     if (!item)
1385fc7a7f3bSEnrico Granata     {
1386e992a089SEnrico Granata         if (log)
1387d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1388e992a089SEnrico Granata                " final_value_type %d",
1389fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
1390fc7a7f3bSEnrico Granata     }
13919fc1944eSEnrico Granata     else
13929fc1944eSEnrico Granata     {
1393e992a089SEnrico Granata         if (log)
1394d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1395e992a089SEnrico Granata                " final_value_type %d",
1396fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
13979fc1944eSEnrico Granata     }
13989fc1944eSEnrico Granata     return item;
13999fc1944eSEnrico Granata }
14009fc1944eSEnrico Granata 
14010769b2b1SMichael Sartain static inline bool
14020769b2b1SMichael Sartain IsToken(const char *var_name_begin, const char *var)
14030769b2b1SMichael Sartain {
14040769b2b1SMichael Sartain     return (::strncmp (var_name_begin, var, strlen(var)) == 0);
14050769b2b1SMichael Sartain }
14060769b2b1SMichael Sartain 
14070769b2b1SMichael Sartain static bool
14080769b2b1SMichael Sartain IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
14090769b2b1SMichael Sartain     const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
14100769b2b1SMichael Sartain {
14110769b2b1SMichael Sartain     int var_len = strlen(var);
14120769b2b1SMichael Sartain     if (::strncmp (var_name_begin, var, var_len) == 0)
14130769b2b1SMichael Sartain     {
14140769b2b1SMichael Sartain         var_name_begin += var_len;
14150769b2b1SMichael Sartain         if (*var_name_begin == '}')
14160769b2b1SMichael Sartain         {
14170769b2b1SMichael Sartain             format = default_format;
14180769b2b1SMichael Sartain             return true;
14190769b2b1SMichael Sartain         }
14200769b2b1SMichael Sartain         else if (*var_name_begin == '%')
14210769b2b1SMichael Sartain         {
14220769b2b1SMichael Sartain             // Allow format specifiers: x|X|u with optional width specifiers.
14230769b2b1SMichael Sartain             //   ${thread.id%x}    ; hex
14240769b2b1SMichael Sartain             //   ${thread.id%X}    ; uppercase hex
14250769b2b1SMichael Sartain             //   ${thread.id%u}    ; unsigned decimal
14260769b2b1SMichael Sartain             //   ${thread.id%8.8X} ; width.precision + specifier
14270769b2b1SMichael Sartain             //   ${thread.id%tid}  ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
14280769b2b1SMichael Sartain             int dot_count = 0;
14290769b2b1SMichael Sartain             const char *specifier = NULL;
14300769b2b1SMichael Sartain             int width_precision_length = 0;
14310769b2b1SMichael Sartain             const char *width_precision = ++var_name_begin;
14320769b2b1SMichael Sartain             while (isdigit(*var_name_begin) || *var_name_begin == '.')
14330769b2b1SMichael Sartain             {
14340769b2b1SMichael Sartain                 dot_count += (*var_name_begin == '.');
14350769b2b1SMichael Sartain                 if (dot_count > 1)
14360769b2b1SMichael Sartain                     break;
14370769b2b1SMichael Sartain                 var_name_begin++;
14380769b2b1SMichael Sartain                 width_precision_length++;
14390769b2b1SMichael Sartain             }
14400769b2b1SMichael Sartain 
14410769b2b1SMichael Sartain             if (IsToken (var_name_begin, "tid}"))
14420769b2b1SMichael Sartain             {
14430769b2b1SMichael Sartain                 Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
14440769b2b1SMichael Sartain                 if (target)
14450769b2b1SMichael Sartain                 {
14460769b2b1SMichael Sartain                     ArchSpec arch (target->GetArchitecture ());
14470769b2b1SMichael Sartain                     llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
14480769b2b1SMichael Sartain                     if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
14490769b2b1SMichael Sartain                         specifier = PRIu64;
14500769b2b1SMichael Sartain                 }
14510769b2b1SMichael Sartain                 if (!specifier)
14520769b2b1SMichael Sartain                 {
14530769b2b1SMichael Sartain                     format = default_format;
14540769b2b1SMichael Sartain                     return true;
14550769b2b1SMichael Sartain                 }
14560769b2b1SMichael Sartain             }
14570769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "x}"))
14580769b2b1SMichael Sartain                 specifier = PRIx64;
14590769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "X}"))
14600769b2b1SMichael Sartain                 specifier = PRIX64;
14610769b2b1SMichael Sartain             else if (IsToken (var_name_begin, "u}"))
14620769b2b1SMichael Sartain                 specifier = PRIu64;
14630769b2b1SMichael Sartain 
14640769b2b1SMichael Sartain             if (specifier)
14650769b2b1SMichael Sartain             {
14660769b2b1SMichael Sartain                 format = "%";
14670769b2b1SMichael Sartain                 if (width_precision_length)
14680769b2b1SMichael Sartain                     format += std::string(width_precision, width_precision_length);
14690769b2b1SMichael Sartain                 format += specifier;
14700769b2b1SMichael Sartain                 return true;
14710769b2b1SMichael Sartain             }
14720769b2b1SMichael Sartain         }
14730769b2b1SMichael Sartain     }
14740769b2b1SMichael Sartain     return false;
14750769b2b1SMichael Sartain }
14760769b2b1SMichael Sartain 
1477705b1809SJason Molenda // Find information for the "thread.info.*" specifiers in a format string
1478705b1809SJason Molenda static bool
1479705b1809SJason Molenda FormatThreadExtendedInfoRecurse
1480705b1809SJason Molenda (
1481705b1809SJason Molenda     const char *var_name_begin,
1482705b1809SJason Molenda     StructuredData::ObjectSP thread_info_dictionary,
1483705b1809SJason Molenda     const SymbolContext *sc,
1484705b1809SJason Molenda     const ExecutionContext *exe_ctx,
1485705b1809SJason Molenda     Stream &s
1486705b1809SJason Molenda )
1487705b1809SJason Molenda {
1488705b1809SJason Molenda     bool var_success = false;
1489705b1809SJason Molenda     std::string token_format;
1490705b1809SJason Molenda 
1491705b1809SJason Molenda     llvm::StringRef var_name(var_name_begin);
1492705b1809SJason Molenda     size_t percent_idx = var_name.find('%');
1493705b1809SJason Molenda     size_t close_curly_idx = var_name.find('}');
1494705b1809SJason Molenda     llvm::StringRef path = var_name;
1495705b1809SJason Molenda     llvm::StringRef formatter = var_name;
1496705b1809SJason Molenda 
1497705b1809SJason Molenda     // 'path' will be the dot separated list of objects to transverse up until we hit
1498705b1809SJason Molenda     // a close curly brace, a percent sign, or an end of string.
1499705b1809SJason Molenda     if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos)
1500705b1809SJason Molenda     {
1501705b1809SJason Molenda         if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos)
1502705b1809SJason Molenda         {
1503705b1809SJason Molenda             if (percent_idx < close_curly_idx)
1504705b1809SJason Molenda             {
1505705b1809SJason Molenda                 path = var_name.slice(0, percent_idx);
1506705b1809SJason Molenda                 formatter = var_name.substr (percent_idx);
1507705b1809SJason Molenda             }
1508705b1809SJason Molenda             else
1509705b1809SJason Molenda             {
1510705b1809SJason Molenda                 path = var_name.slice(0, close_curly_idx);
1511705b1809SJason Molenda                 formatter = var_name.substr (close_curly_idx);
1512705b1809SJason Molenda             }
1513705b1809SJason Molenda         }
1514705b1809SJason Molenda         else if (percent_idx != llvm::StringRef::npos)
1515705b1809SJason Molenda         {
1516705b1809SJason Molenda             path = var_name.slice(0, percent_idx);
1517705b1809SJason Molenda             formatter = var_name.substr (percent_idx);
1518705b1809SJason Molenda         }
1519705b1809SJason Molenda         else if (close_curly_idx != llvm::StringRef::npos)
1520705b1809SJason Molenda         {
1521705b1809SJason Molenda             path = var_name.slice(0, close_curly_idx);
1522705b1809SJason Molenda             formatter = var_name.substr (close_curly_idx);
1523705b1809SJason Molenda         }
1524705b1809SJason Molenda     }
1525705b1809SJason Molenda 
1526705b1809SJason Molenda     StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
1527705b1809SJason Molenda 
1528705b1809SJason Molenda     if (value.get())
1529705b1809SJason Molenda     {
1530705b1809SJason Molenda         if (value->GetType() == StructuredData::Type::eTypeInteger)
1531705b1809SJason Molenda         {
1532705b1809SJason Molenda             if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
1533705b1809SJason Molenda             {
1534705b1809SJason Molenda                 s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue());
1535705b1809SJason Molenda                 var_success = true;
1536705b1809SJason Molenda             }
1537705b1809SJason Molenda         }
1538705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeFloat)
1539705b1809SJason Molenda         {
1540705b1809SJason Molenda             s.Printf ("%f", value->GetAsFloat()->GetValue());
1541705b1809SJason Molenda             var_success = true;
1542705b1809SJason Molenda         }
1543705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeString)
1544705b1809SJason Molenda         {
1545705b1809SJason Molenda             s.Printf("%s", value->GetAsString()->GetValue().c_str());
1546705b1809SJason Molenda             var_success = true;
1547705b1809SJason Molenda         }
1548705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeArray)
1549705b1809SJason Molenda         {
1550705b1809SJason Molenda             if (value->GetAsArray()->GetSize() > 0)
1551705b1809SJason Molenda             {
1552705b1809SJason Molenda                 s.Printf ("%zu", value->GetAsArray()->GetSize());
1553705b1809SJason Molenda                 var_success = true;
1554705b1809SJason Molenda             }
1555705b1809SJason Molenda         }
1556705b1809SJason Molenda         else if (value->GetType() == StructuredData::Type::eTypeDictionary)
1557705b1809SJason Molenda         {
1558705b1809SJason Molenda             s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1559705b1809SJason Molenda             var_success = true;
1560705b1809SJason Molenda         }
1561705b1809SJason Molenda     }
1562705b1809SJason Molenda 
1563705b1809SJason Molenda     return var_success;
1564705b1809SJason Molenda }
1565705b1809SJason Molenda 
1566705b1809SJason Molenda 
1567c3ce7f27SMichael Sartain static bool
1568c3ce7f27SMichael Sartain FormatPromptRecurse
15691b654882SGreg Clayton (
15701b654882SGreg Clayton     const char *format,
15711b654882SGreg Clayton     const SymbolContext *sc,
15721b654882SGreg Clayton     const ExecutionContext *exe_ctx,
15731b654882SGreg Clayton     const Address *addr,
15741b654882SGreg Clayton     Stream &s,
15754becb37eSEnrico Granata     const char **end,
1576aff1b357SJason Molenda     ValueObject* valobj,
1577aff1b357SJason Molenda     bool function_changed,
1578aff1b357SJason Molenda     bool initial_function
15791b654882SGreg Clayton )
15801b654882SGreg Clayton {
1581c482a192SEnrico Granata     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
15821b654882SGreg Clayton     bool success = true;
15831b654882SGreg Clayton     const char *p;
15845160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1585c3ce7f27SMichael Sartain 
15861b654882SGreg Clayton     for (p = format; *p != '\0'; ++p)
15871b654882SGreg Clayton     {
1588c482a192SEnrico Granata         if (realvalobj)
15894becb37eSEnrico Granata         {
1590c482a192SEnrico Granata             valobj = realvalobj;
1591c482a192SEnrico Granata             realvalobj = NULL;
15924becb37eSEnrico Granata         }
15931b654882SGreg Clayton         size_t non_special_chars = ::strcspn (p, "${}\\");
15941b654882SGreg Clayton         if (non_special_chars > 0)
15951b654882SGreg Clayton         {
15961b654882SGreg Clayton             if (success)
15971b654882SGreg Clayton                 s.Write (p, non_special_chars);
15981b654882SGreg Clayton             p += non_special_chars;
15991b654882SGreg Clayton         }
16001b654882SGreg Clayton 
16011b654882SGreg Clayton         if (*p == '\0')
16021b654882SGreg Clayton         {
16031b654882SGreg Clayton             break;
16041b654882SGreg Clayton         }
16051b654882SGreg Clayton         else if (*p == '{')
16061b654882SGreg Clayton         {
16071b654882SGreg Clayton             // Start a new scope that must have everything it needs if it is to
16081b654882SGreg Clayton             // to make it into the final output stream "s". If you want to make
16091b654882SGreg Clayton             // a format that only prints out the function or symbol name if there
16101b654882SGreg Clayton             // is one in the symbol context you can use:
16111b654882SGreg Clayton             //      "{function =${function.name}}"
16121b654882SGreg Clayton             // The first '{' starts a new scope that end with the matching '}' at
16131b654882SGreg Clayton             // the end of the string. The contents "function =${function.name}"
16141b654882SGreg Clayton             // will then be evaluated and only be output if there is a function
16151b654882SGreg Clayton             // or symbol with a valid name.
16161b654882SGreg Clayton             StreamString sub_strm;
16171b654882SGreg Clayton 
16181b654882SGreg Clayton             ++p;  // Skip the '{'
16191b654882SGreg Clayton 
1620aff1b357SJason Molenda             if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj, function_changed, initial_function))
16211b654882SGreg Clayton             {
16221b654882SGreg Clayton                 // The stream had all it needed
16231b654882SGreg Clayton                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
16241b654882SGreg Clayton             }
16251b654882SGreg Clayton             if (*p != '}')
16261b654882SGreg Clayton             {
16271b654882SGreg Clayton                 success = false;
16281b654882SGreg Clayton                 break;
16291b654882SGreg Clayton             }
16301b654882SGreg Clayton         }
16311b654882SGreg Clayton         else if (*p == '}')
16321b654882SGreg Clayton         {
16331b654882SGreg Clayton             // End of a enclosing scope
16341b654882SGreg Clayton             break;
16351b654882SGreg Clayton         }
16361b654882SGreg Clayton         else if (*p == '$')
16371b654882SGreg Clayton         {
16381b654882SGreg Clayton             // We have a prompt variable to print
16391b654882SGreg Clayton             ++p;
16401b654882SGreg Clayton             if (*p == '{')
16411b654882SGreg Clayton             {
16421b654882SGreg Clayton                 ++p;
16431b654882SGreg Clayton                 const char *var_name_begin = p;
16441b654882SGreg Clayton                 const char *var_name_end = ::strchr (p, '}');
16451b654882SGreg Clayton 
16461b654882SGreg Clayton                 if (var_name_end && var_name_begin < var_name_end)
16471b654882SGreg Clayton                 {
16481b654882SGreg Clayton                     // if we have already failed to parse, skip this variable
16491b654882SGreg Clayton                     if (success)
16501b654882SGreg Clayton                     {
16511b654882SGreg Clayton                         const char *cstr = NULL;
16520769b2b1SMichael Sartain                         std::string token_format;
16531b654882SGreg Clayton                         Address format_addr;
1654aff1b357SJason Molenda 
1655aff1b357SJason Molenda                         // normally "addr" means print a raw address but
1656aff1b357SJason Molenda                         // "file-addr-or-load-addr" means print a module + file addr if there's no load addr
1657aff1b357SJason Molenda                         bool print_file_addr_or_load_addr = false;
1658aff1b357SJason Molenda                         bool addr_offset_concrete_func_only = false;
1659aff1b357SJason Molenda                         bool addr_offset_print_with_no_padding = false;
16601b654882SGreg Clayton                         bool calculate_format_addr_function_offset = false;
16611b654882SGreg Clayton                         // Set reg_kind and reg_num to invalid values
16621b654882SGreg Clayton                         RegisterKind reg_kind = kNumRegisterKinds;
16631b654882SGreg Clayton                         uint32_t reg_num = LLDB_INVALID_REGNUM;
16641b654882SGreg Clayton                         FileSpec format_file_spec;
1665e0d378b3SGreg Clayton                         const RegisterInfo *reg_info = NULL;
16661b654882SGreg Clayton                         RegisterContext *reg_ctx = NULL;
16679fc1944eSEnrico Granata                         bool do_deref_pointer = false;
166886cc9829SEnrico Granata                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
166986cc9829SEnrico Granata                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
16701b654882SGreg Clayton 
16711b654882SGreg Clayton                         // Each variable must set success to true below...
16721b654882SGreg Clayton                         bool var_success = false;
16731b654882SGreg Clayton                         switch (var_name_begin[0])
16741b654882SGreg Clayton                         {
16754becb37eSEnrico Granata                         case '*':
16766f3533fbSEnrico Granata                         case 'v':
16776f3533fbSEnrico Granata                         case 's':
16784becb37eSEnrico Granata                             {
1679c482a192SEnrico Granata                                 if (!valobj)
168034132754SGreg Clayton                                     break;
16816f3533fbSEnrico Granata 
1682c3e320a7SEnrico Granata                                 if (log)
1683d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1684c3e320a7SEnrico Granata 
16856f3533fbSEnrico Granata                                 // check for *var and *svar
16866f3533fbSEnrico Granata                                 if (*var_name_begin == '*')
16876f3533fbSEnrico Granata                                 {
16889fc1944eSEnrico Granata                                     do_deref_pointer = true;
16899fc1944eSEnrico Granata                                     var_name_begin++;
1690c3e320a7SEnrico Granata                                     if (log)
169168ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
169268ae4117SEnrico Granata                                 }
1693c3e320a7SEnrico Granata 
16946f3533fbSEnrico Granata                                 if (*var_name_begin == 's')
16954becb37eSEnrico Granata                                 {
1696c5bc412cSEnrico Granata                                     if (!valobj->IsSynthetic())
169786cc9829SEnrico Granata                                         valobj = valobj->GetSyntheticValue().get();
169886cc9829SEnrico Granata                                     if (!valobj)
169986cc9829SEnrico Granata                                         break;
17006f3533fbSEnrico Granata                                     var_name_begin++;
1701c3e320a7SEnrico Granata                                     if (log)
170268ae4117SEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
170368ae4117SEnrico Granata                                 }
1704c3e320a7SEnrico Granata 
17056f3533fbSEnrico Granata                                 // should be a 'v' by now
17066f3533fbSEnrico Granata                                 if (*var_name_begin != 'v')
17076f3533fbSEnrico Granata                                     break;
17086f3533fbSEnrico Granata 
1709c3e320a7SEnrico Granata                                 if (log)
171068ae4117SEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
1711c3e320a7SEnrico Granata 
1712fc7a7f3bSEnrico Granata                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
171386cc9829SEnrico Granata                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1714fc7a7f3bSEnrico Granata                                 ValueObject::GetValueForExpressionPathOptions options;
17158c9d3560SEnrico Granata                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
171686cc9829SEnrico Granata                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
171734132754SGreg Clayton                                 ValueObject* target = NULL;
17184d122c40SGreg Clayton                                 Format custom_format = eFormatInvalid;
171934132754SGreg Clayton                                 const char* var_name_final = NULL;
17209fc1944eSEnrico Granata                                 const char* var_name_final_if_array_range = NULL;
172134132754SGreg Clayton                                 const char* close_bracket_position = NULL;
172234132754SGreg Clayton                                 int64_t index_lower = -1;
172334132754SGreg Clayton                                 int64_t index_higher = -1;
17249fc1944eSEnrico Granata                                 bool is_array_range = false;
1725fc7a7f3bSEnrico Granata                                 const char* first_unparsed;
172685933ed4SEnrico Granata                                 bool was_plain_var = false;
172785933ed4SEnrico Granata                                 bool was_var_format = false;
1728a777dc2aSEnrico Granata                                 bool was_var_indexed = false;
1729fc7a7f3bSEnrico Granata 
1730c482a192SEnrico Granata                                 if (!valobj) break;
1731c482a192SEnrico Granata                                 // simplest case ${var}, just print valobj's value
17320769b2b1SMichael Sartain                                 if (IsToken (var_name_begin, "var}"))
17330a3958e0SEnrico Granata                                 {
173485933ed4SEnrico Granata                                     was_plain_var = true;
1735c482a192SEnrico Granata                                     target = valobj;
173686cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
17370a3958e0SEnrico Granata                                 }
1738*88282c69SEnrico Granata                                 else if (IsToken (var_name_begin, "var.script:"))
1739*88282c69SEnrico Granata                                 {
1740*88282c69SEnrico Granata                                     var_name_begin += ::strlen("var.script:");
1741*88282c69SEnrico Granata                                     std::string script_name(var_name_begin,var_name_end);
1742*88282c69SEnrico Granata                                     ScriptInterpreter* script_interpreter = valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1743*88282c69SEnrico Granata                                     if (RunScriptFormatKeyword (s, script_interpreter, valobj, script_name))
1744*88282c69SEnrico Granata                                         var_success = true;
1745*88282c69SEnrico Granata                                     break;
1746*88282c69SEnrico Granata                                 }
17470769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin,"var%"))
17489fc1944eSEnrico Granata                                 {
174985933ed4SEnrico Granata                                     was_var_format = true;
17509fc1944eSEnrico Granata                                     // this is a variable with some custom format applied to it
17519fc1944eSEnrico Granata                                     const char* percent_position;
1752c482a192SEnrico Granata                                     target = valobj;
175386cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
17549fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
17559fc1944eSEnrico Granata                                                           var_name_end,
17569fc1944eSEnrico Granata                                                           &var_name_final,
17579fc1944eSEnrico Granata                                                           &percent_position,
17589fc1944eSEnrico Granata                                                           &custom_format,
17599fc1944eSEnrico Granata                                                           &val_obj_display);
17600a3958e0SEnrico Granata                                 }
17619fc1944eSEnrico Granata                                     // this is ${var.something} or multiple .something nested
17620769b2b1SMichael Sartain                                 else if (IsToken (var_name_begin, "var"))
17639fc1944eSEnrico Granata                                 {
17640769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "var["))
1765a777dc2aSEnrico Granata                                         was_var_indexed = true;
17669fc1944eSEnrico Granata                                     const char* percent_position;
17679fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
17689fc1944eSEnrico Granata                                                           var_name_end,
17699fc1944eSEnrico Granata                                                           &var_name_final,
17709fc1944eSEnrico Granata                                                           &percent_position,
17719fc1944eSEnrico Granata                                                           &custom_format,
17729fc1944eSEnrico Granata                                                           &val_obj_display);
17739fc1944eSEnrico Granata 
17749fc1944eSEnrico Granata                                     const char* open_bracket_position;
17759fc1944eSEnrico Granata                                     const char* separator_position;
17769fc1944eSEnrico Granata                                     ScanBracketedRange (var_name_begin,
17779fc1944eSEnrico Granata                                                         var_name_end,
17789fc1944eSEnrico Granata                                                         var_name_final,
17799fc1944eSEnrico Granata                                                         &open_bracket_position,
17809fc1944eSEnrico Granata                                                         &separator_position,
17819fc1944eSEnrico Granata                                                         &close_bracket_position,
17829fc1944eSEnrico Granata                                                         &var_name_final_if_array_range,
17839fc1944eSEnrico Granata                                                         &index_lower,
17849fc1944eSEnrico Granata                                                         &index_higher);
17859fc1944eSEnrico Granata 
17869fc1944eSEnrico Granata                                     Error error;
17879fc1944eSEnrico Granata 
1788599171adSEnrico Granata                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1789599171adSEnrico Granata                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1790fc7a7f3bSEnrico Granata 
1791e992a089SEnrico Granata                                     if (log)
1792599171adSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1793fc7a7f3bSEnrico Granata 
1794599171adSEnrico Granata                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1795fc7a7f3bSEnrico Granata                                                                              &first_unparsed,
1796fc7a7f3bSEnrico Granata                                                                              &reason_to_stop,
1797fc7a7f3bSEnrico Granata                                                                              &final_value_type,
1798fc7a7f3bSEnrico Granata                                                                              options,
1799fc7a7f3bSEnrico Granata                                                                              &what_next).get();
1800fc7a7f3bSEnrico Granata 
1801fc7a7f3bSEnrico Granata                                     if (!target)
18029fc1944eSEnrico Granata                                     {
1803e992a089SEnrico Granata                                         if (log)
1804d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1805e992a089SEnrico Granata                                                " final_value_type %d",
1806fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1807fc7a7f3bSEnrico Granata                                         break;
18080a3958e0SEnrico Granata                                     }
1809a7187d00SEnrico Granata                                     else
1810fc7a7f3bSEnrico Granata                                     {
1811e992a089SEnrico Granata                                         if (log)
1812d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1813e992a089SEnrico Granata                                                " final_value_type %d",
1814fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
181550bed5e8SEnrico Granata                                         target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get();
1816a7187d00SEnrico Granata                                     }
18170a3958e0SEnrico Granata                                 }
18180a3958e0SEnrico Granata                                 else
18190a3958e0SEnrico Granata                                     break;
18209fc1944eSEnrico Granata 
182186cc9829SEnrico Granata                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
182286cc9829SEnrico Granata                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1823fc7a7f3bSEnrico Granata 
182486cc9829SEnrico Granata                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1825fc7a7f3bSEnrico Granata 
1826a7187d00SEnrico Granata                                 if (do_deref_pointer && !is_array_range)
18270a3958e0SEnrico Granata                                 {
18289fc1944eSEnrico Granata                                     // I have not deref-ed yet, let's do it
18299fc1944eSEnrico Granata                                     // this happens when we are not going through GetValueForVariableExpressionPath
18309fc1944eSEnrico Granata                                     // to get to the target ValueObject
18319fc1944eSEnrico Granata                                     Error error;
18329fc1944eSEnrico Granata                                     target = target->Dereference(error).get();
1833dc940730SEnrico Granata                                     if (error.Fail())
1834dc940730SEnrico Granata                                     {
1835dc940730SEnrico Granata                                         if (log)
1836d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1837dc940730SEnrico Granata                                         break;
1838dc940730SEnrico Granata                                     }
18399fc1944eSEnrico Granata                                     do_deref_pointer = false;
18400a3958e0SEnrico Granata                                 }
18410a3958e0SEnrico Granata 
1842f164d940SJim Ingham                                 if (!target)
1843f164d940SJim Ingham                                 {
1844f164d940SJim Ingham                                     if (log)
1845f164d940SJim Ingham                                         log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
1846f164d940SJim Ingham                                     break;
1847f164d940SJim Ingham                                 }
1848f164d940SJim Ingham 
1849a777dc2aSEnrico Granata                                 // we do not want to use the summary for a bitfield of type T:n
1850a777dc2aSEnrico Granata                                 // if we were originally dealing with just a T - that would get
1851a777dc2aSEnrico Granata                                 // us into an endless recursion
1852a777dc2aSEnrico Granata                                 if (target->IsBitfield() && was_var_indexed)
1853a777dc2aSEnrico Granata                                 {
1854a777dc2aSEnrico Granata                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1855a777dc2aSEnrico Granata                                     StreamString bitfield_name;
1856a777dc2aSEnrico Granata                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1857a777dc2aSEnrico Granata                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1858a777dc2aSEnrico Granata                                     if (!DataVisualization::GetSummaryForType(type_sp))
1859a777dc2aSEnrico Granata                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1860a777dc2aSEnrico Granata                                 }
1861a777dc2aSEnrico Granata 
186285933ed4SEnrico Granata                                 // TODO use flags for these
186357ee3067SGreg Clayton                                 const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
1864622be238SEnrico Granata                                 bool is_array = (type_info_flags & eTypeIsArray) != 0;
1865622be238SEnrico Granata                                 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
186657ee3067SGreg Clayton                                 bool is_aggregate = target->GetClangType().IsAggregateType();
1867f4efecd9SEnrico Granata 
186886cc9829SEnrico Granata                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1869f4efecd9SEnrico Granata                                 {
187085933ed4SEnrico Granata                                     StreamString str_temp;
1871e992a089SEnrico Granata                                     if (log)
1872d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1873d64d0bc0SEnrico Granata 
18745088c486SGreg Clayton                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1875d64d0bc0SEnrico Granata                                     {
1876f4efecd9SEnrico Granata                                         // try to use the special cases
187785933ed4SEnrico Granata                                         var_success = target->DumpPrintableRepresentation(str_temp,
187885933ed4SEnrico Granata                                                                                           val_obj_display,
187985933ed4SEnrico Granata                                                                                           custom_format);
1880e992a089SEnrico Granata                                         if (log)
1881d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1882d64d0bc0SEnrico Granata 
1883d64d0bc0SEnrico Granata                                         // should not happen
18845088c486SGreg Clayton                                         if (var_success)
188585933ed4SEnrico Granata                                             s << str_temp.GetData();
1886d64d0bc0SEnrico Granata                                         var_success = true;
1887d64d0bc0SEnrico Granata                                         break;
1888d64d0bc0SEnrico Granata                                     }
1889d64d0bc0SEnrico Granata                                     else
1890d64d0bc0SEnrico Granata                                     {
189188da35f8SEnrico Granata                                         if (was_plain_var) // if ${var}
1892d64d0bc0SEnrico Granata                                         {
1893d64d0bc0SEnrico Granata                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1894d64d0bc0SEnrico Granata                                         }
189588da35f8SEnrico Granata                                         else if (is_pointer) // if pointer, value is the address stored
189688da35f8SEnrico Granata                                         {
189723f59509SGreg Clayton                                             target->DumpPrintableRepresentation (s,
189888da35f8SEnrico Granata                                                                                  val_obj_display,
189986cc9829SEnrico Granata                                                                                  custom_format,
190086cc9829SEnrico Granata                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
190188da35f8SEnrico Granata                                         }
1902d64d0bc0SEnrico Granata                                         var_success = true;
1903d64d0bc0SEnrico Granata                                         break;
1904d64d0bc0SEnrico Granata                                     }
1905d64d0bc0SEnrico Granata                                 }
1906d64d0bc0SEnrico Granata 
1907d64d0bc0SEnrico Granata                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1908d64d0bc0SEnrico Granata                                 // type @ location message
1909d64d0bc0SEnrico Granata                                 if (is_aggregate && was_plain_var)
1910d64d0bc0SEnrico Granata                                 {
1911d64d0bc0SEnrico Granata                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1912d64d0bc0SEnrico Granata                                     var_success = true;
191385933ed4SEnrico Granata                                     break;
191485933ed4SEnrico Granata                                 }
191585933ed4SEnrico Granata 
1916d64d0bc0SEnrico Granata                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
191786cc9829SEnrico Granata                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
191885933ed4SEnrico Granata                                 {
191985933ed4SEnrico Granata                                     s << "<invalid use of aggregate type>";
192085933ed4SEnrico Granata                                     var_success = true;
1921f4efecd9SEnrico Granata                                     break;
1922f4efecd9SEnrico Granata                                 }
1923f4efecd9SEnrico Granata 
19249fc1944eSEnrico Granata                                 if (!is_array_range)
1925e992a089SEnrico Granata                                 {
1926e992a089SEnrico Granata                                     if (log)
1927d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
19289fc1944eSEnrico Granata                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1929e992a089SEnrico Granata                                 }
19309fc1944eSEnrico Granata                                 else
19319fc1944eSEnrico Granata                                 {
1932e992a089SEnrico Granata                                     if (log)
1933d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
19349fc1944eSEnrico Granata                                     if (!is_array && !is_pointer)
19359fc1944eSEnrico Granata                                         break;
1936e992a089SEnrico Granata                                     if (log)
1937d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1938fc7a7f3bSEnrico Granata                                     const char* special_directions = NULL;
1939fc7a7f3bSEnrico Granata                                     StreamString special_directions_writer;
19400a3958e0SEnrico Granata                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
19410a3958e0SEnrico Granata                                     {
1942fc7a7f3bSEnrico Granata                                         ConstString additional_data;
1943fc7a7f3bSEnrico Granata                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1944fc7a7f3bSEnrico Granata                                         special_directions_writer.Printf("${%svar%s}",
1945fc7a7f3bSEnrico Granata                                                                          do_deref_pointer ? "*" : "",
1946fc7a7f3bSEnrico Granata                                                                          additional_data.GetCString());
1947fc7a7f3bSEnrico Granata                                         special_directions = special_directions_writer.GetData();
19480a3958e0SEnrico Granata                                     }
19490a3958e0SEnrico Granata 
19500a3958e0SEnrico Granata                                     // let us display items index_lower thru index_higher of this array
19510a3958e0SEnrico Granata                                     s.PutChar('[');
19520a3958e0SEnrico Granata                                     var_success = true;
19530a3958e0SEnrico Granata 
19549fc1944eSEnrico Granata                                     if (index_higher < 0)
1955c482a192SEnrico Granata                                         index_higher = valobj->GetNumChildren() - 1;
19560a3958e0SEnrico Granata 
1957cc4d0146SGreg Clayton                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
195822c55d18SEnrico Granata 
19590a3958e0SEnrico Granata                                     for (;index_lower<=index_higher;index_lower++)
19600a3958e0SEnrico Granata                                     {
1961fc7a7f3bSEnrico Granata                                         ValueObject* item = ExpandIndexedExpression (target,
19629fc1944eSEnrico Granata                                                                                      index_lower,
1963c14ee32dSGreg Clayton                                                                                      exe_ctx->GetFramePtr(),
1964fc7a7f3bSEnrico Granata                                                                                      false).get();
19650a3958e0SEnrico Granata 
1966fc7a7f3bSEnrico Granata                                         if (!item)
1967fc7a7f3bSEnrico Granata                                         {
1968e992a089SEnrico Granata                                             if (log)
1969d01b2953SDaniel Malea                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1970fc7a7f3bSEnrico Granata                                         }
1971fc7a7f3bSEnrico Granata                                         else
1972fc7a7f3bSEnrico Granata                                         {
1973e992a089SEnrico Granata                                             if (log)
1974d228483dSEnrico Granata                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1975fc7a7f3bSEnrico Granata                                         }
1976fc7a7f3bSEnrico Granata 
19770a3958e0SEnrico Granata                                         if (!special_directions)
19789fc1944eSEnrico Granata                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
19790a3958e0SEnrico Granata                                         else
1980aff1b357SJason Molenda                                             var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item, function_changed, initial_function);
19810a3958e0SEnrico Granata 
198222c55d18SEnrico Granata                                         if (--max_num_children == 0)
198322c55d18SEnrico Granata                                         {
198422c55d18SEnrico Granata                                             s.PutCString(", ...");
198522c55d18SEnrico Granata                                             break;
198622c55d18SEnrico Granata                                         }
198722c55d18SEnrico Granata 
19880a3958e0SEnrico Granata                                         if (index_lower < index_higher)
19890a3958e0SEnrico Granata                                             s.PutChar(',');
19900a3958e0SEnrico Granata                                     }
19910a3958e0SEnrico Granata                                     s.PutChar(']');
19924becb37eSEnrico Granata                                 }
19934becb37eSEnrico Granata                             }
199434132754SGreg Clayton                             break;
19951b654882SGreg Clayton                         case 'a':
1996aff1b357SJason Molenda                             if (IsToken (var_name_begin, "addr-file-or-load}"))
1997aff1b357SJason Molenda                             {
1998aff1b357SJason Molenda                                 print_file_addr_or_load_addr = true;
1999aff1b357SJason Molenda                             }
2000aff1b357SJason Molenda                             if (IsToken (var_name_begin, "addr}")
2001aff1b357SJason Molenda                                 || IsToken (var_name_begin, "addr-file-or-load}"))
20021b654882SGreg Clayton                             {
20031b654882SGreg Clayton                                 if (addr && addr->IsValid())
20041b654882SGreg Clayton                                 {
20051b654882SGreg Clayton                                     var_success = true;
20061b654882SGreg Clayton                                     format_addr = *addr;
20071b654882SGreg Clayton                                 }
20081b654882SGreg Clayton                             }
20091b654882SGreg Clayton                             break;
20101b654882SGreg Clayton 
20111b654882SGreg Clayton                         case 'p':
20120769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "process."))
20131b654882SGreg Clayton                             {
2014c14ee32dSGreg Clayton                                 if (exe_ctx)
2015c14ee32dSGreg Clayton                                 {
2016c14ee32dSGreg Clayton                                     Process *process = exe_ctx->GetProcessPtr();
2017c14ee32dSGreg Clayton                                     if (process)
20181b654882SGreg Clayton                                     {
20191b654882SGreg Clayton                                         var_name_begin += ::strlen ("process.");
20200769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
20211b654882SGreg Clayton                                         {
20220769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), process->GetID());
20231b654882SGreg Clayton                                             var_success = true;
20241b654882SGreg Clayton                                         }
20250769b2b1SMichael Sartain                                         else if ((IsToken (var_name_begin, "name}")) ||
20260769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.basename}")) ||
20270769b2b1SMichael Sartain                                                 (IsToken (var_name_begin, "file.fullpath}")))
20281b654882SGreg Clayton                                         {
2029c14ee32dSGreg Clayton                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
2030aa149cbdSGreg Clayton                                             if (exe_module)
20311b654882SGreg Clayton                                             {
20321b654882SGreg Clayton                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
20331b654882SGreg Clayton                                                 {
2034aa149cbdSGreg Clayton                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
20359076c0ffSSean Callanan                                                     var_success = (bool)format_file_spec;
20361b654882SGreg Clayton                                                 }
20371b654882SGreg Clayton                                                 else
20381b654882SGreg Clayton                                                 {
2039aa149cbdSGreg Clayton                                                     format_file_spec = exe_module->GetFileSpec();
20409076c0ffSSean Callanan                                                     var_success = (bool)format_file_spec;
20411b654882SGreg Clayton                                                 }
20421b654882SGreg Clayton                                             }
20431b654882SGreg Clayton                                         }
20440769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2045aad8e480SEnrico Granata                                         {
2046aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2047aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2048aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
20490769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
2050aad8e480SEnrico Granata                                                 var_success = true;
2051aad8e480SEnrico Granata                                         }
20521b654882SGreg Clayton                                     }
20531b654882SGreg Clayton                                 }
2054c14ee32dSGreg Clayton                             }
20551b654882SGreg Clayton                             break;
20561b654882SGreg Clayton 
20571b654882SGreg Clayton                         case 't':
20580769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "thread."))
20591b654882SGreg Clayton                             {
2060c14ee32dSGreg Clayton                                 if (exe_ctx)
2061c14ee32dSGreg Clayton                                 {
2062c14ee32dSGreg Clayton                                     Thread *thread = exe_ctx->GetThreadPtr();
2063c14ee32dSGreg Clayton                                     if (thread)
20641b654882SGreg Clayton                                     {
20651b654882SGreg Clayton                                         var_name_begin += ::strlen ("thread.");
20660769b2b1SMichael Sartain                                         if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
20671b654882SGreg Clayton                                         {
20680769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetID());
20691b654882SGreg Clayton                                             var_success = true;
20701b654882SGreg Clayton                                         }
20710769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
2072160c9d81SGreg Clayton                                         {
20730769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), thread->GetProtocolID());
2074160c9d81SGreg Clayton                                             var_success = true;
2075160c9d81SGreg Clayton                                         }
20760769b2b1SMichael Sartain                                         else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
20771b654882SGreg Clayton                                         {
20780769b2b1SMichael Sartain                                             s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
20791b654882SGreg Clayton                                             var_success = true;
20801b654882SGreg Clayton                                         }
20810769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "name}"))
20821b654882SGreg Clayton                                         {
2083c14ee32dSGreg Clayton                                             cstr = thread->GetName();
20841b654882SGreg Clayton                                             var_success = cstr && cstr[0];
20851b654882SGreg Clayton                                             if (var_success)
20861b654882SGreg Clayton                                                 s.PutCString(cstr);
20871b654882SGreg Clayton                                         }
20880769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "queue}"))
20891b654882SGreg Clayton                                         {
2090c14ee32dSGreg Clayton                                             cstr = thread->GetQueueName();
20911b654882SGreg Clayton                                             var_success = cstr && cstr[0];
20921b654882SGreg Clayton                                             if (var_success)
20931b654882SGreg Clayton                                                 s.PutCString(cstr);
20941b654882SGreg Clayton                                         }
20950769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "stop-reason}"))
20961b654882SGreg Clayton                                         {
2097c14ee32dSGreg Clayton                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
20985d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
20991b654882SGreg Clayton                                             {
2100b15bfc75SJim Ingham                                                 cstr = stop_info_sp->GetDescription();
21011b654882SGreg Clayton                                                 if (cstr && cstr[0])
21021b654882SGreg Clayton                                                 {
21031b654882SGreg Clayton                                                     s.PutCString(cstr);
21041b654882SGreg Clayton                                                     var_success = true;
21051b654882SGreg Clayton                                                 }
21061b654882SGreg Clayton                                             }
21071b654882SGreg Clayton                                         }
21080769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "return-value}"))
210973ca05a2SJim Ingham                                         {
211073ca05a2SJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
21115d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
211273ca05a2SJim Ingham                                             {
211373ca05a2SJim Ingham                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
211473ca05a2SJim Ingham                                                 if (return_valobj_sp)
211573ca05a2SJim Ingham                                                 {
21164d93b8cdSEnrico Granata                                                     return_valobj_sp->Dump(s);
211773ca05a2SJim Ingham                                                     var_success = true;
211873ca05a2SJim Ingham                                                 }
211973ca05a2SJim Ingham                                             }
212073ca05a2SJim Ingham                                         }
212130fadafeSJim Ingham                                         else if (IsToken (var_name_begin, "completed-expression}"))
212230fadafeSJim Ingham                                         {
212330fadafeSJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
212430fadafeSJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
212530fadafeSJim Ingham                                             {
212630fadafeSJim Ingham                                                 ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
212730fadafeSJim Ingham                                                 if (expression_var_sp && expression_var_sp->GetValueObject())
212830fadafeSJim Ingham                                                 {
212930fadafeSJim Ingham                                                     expression_var_sp->GetValueObject()->Dump(s);
213030fadafeSJim Ingham                                                     var_success = true;
213130fadafeSJim Ingham                                                 }
213230fadafeSJim Ingham                                             }
213330fadafeSJim Ingham                                         }
21340769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2135aad8e480SEnrico Granata                                         {
2136aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2137aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2138aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
21390769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
2140aad8e480SEnrico Granata                                                 var_success = true;
2141aad8e480SEnrico Granata                                         }
2142705b1809SJason Molenda                                         else if (IsToken (var_name_begin, "info."))
2143705b1809SJason Molenda                                         {
2144705b1809SJason Molenda                                             var_name_begin += ::strlen("info.");
2145705b1809SJason Molenda                                             StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
2146705b1809SJason Molenda                                             if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
2147705b1809SJason Molenda                                             {
2148705b1809SJason Molenda                                                 var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s);
2149705b1809SJason Molenda                                             }
2150705b1809SJason Molenda                                         }
2151aad8e480SEnrico Granata                                     }
2152aad8e480SEnrico Granata                                 }
215373ca05a2SJim Ingham                             }
21540769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "target."))
21551b654882SGreg Clayton                             {
215667cc0636SGreg Clayton                                 // TODO: hookup properties
215767cc0636SGreg Clayton //                                if (!target_properties_sp)
215867cc0636SGreg Clayton //                                {
215967cc0636SGreg Clayton //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
216067cc0636SGreg Clayton //                                    if (target)
216167cc0636SGreg Clayton //                                        target_properties_sp = target->GetProperties();
216267cc0636SGreg Clayton //                                }
216367cc0636SGreg Clayton //
216467cc0636SGreg Clayton //                                if (target_properties_sp)
216567cc0636SGreg Clayton //                                {
216667cc0636SGreg Clayton //                                    var_name_begin += ::strlen ("target.");
216767cc0636SGreg Clayton //                                    const char *end_property = strchr(var_name_begin, '}');
216867cc0636SGreg Clayton //                                    if (end_property)
216967cc0636SGreg Clayton //                                    {
217067cc0636SGreg Clayton //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
217167cc0636SGreg Clayton //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
217267cc0636SGreg Clayton //                                        if (!property_value.empty())
217367cc0636SGreg Clayton //                                        {
217467cc0636SGreg Clayton //                                            s.PutCString (property_value.c_str());
217567cc0636SGreg Clayton //                                            var_success = true;
217667cc0636SGreg Clayton //                                        }
217767cc0636SGreg Clayton //                                    }
217867cc0636SGreg Clayton //                                }
21790603aa9dSGreg Clayton                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
21800603aa9dSGreg Clayton                                 if (target)
21811b654882SGreg Clayton                                 {
21821b654882SGreg Clayton                                     var_name_begin += ::strlen ("target.");
21830769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "arch}"))
21841b654882SGreg Clayton                                     {
21851b654882SGreg Clayton                                         ArchSpec arch (target->GetArchitecture ());
21861b654882SGreg Clayton                                         if (arch.IsValid())
21871b654882SGreg Clayton                                         {
218864195a2cSGreg Clayton                                             s.PutCString (arch.GetArchitectureName());
21891b654882SGreg Clayton                                             var_success = true;
21901b654882SGreg Clayton                                         }
21911b654882SGreg Clayton                                     }
21920769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "script:"))
2193aad8e480SEnrico Granata                                     {
2194aad8e480SEnrico Granata                                         var_name_begin += ::strlen("script:");
2195aad8e480SEnrico Granata                                         std::string script_name(var_name_begin,var_name_end);
2196aad8e480SEnrico Granata                                         ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
21970769b2b1SMichael Sartain                                         if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
2198aad8e480SEnrico Granata                                             var_success = true;
2199aad8e480SEnrico Granata                                     }
22001b654882SGreg Clayton                                 }
22011b654882SGreg Clayton                             }
22021b654882SGreg Clayton                             break;
22031b654882SGreg Clayton 
22041b654882SGreg Clayton                         case 'm':
22050769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "module."))
22061b654882SGreg Clayton                             {
22070603aa9dSGreg Clayton                                 if (sc && sc->module_sp.get())
22081b654882SGreg Clayton                                 {
22090603aa9dSGreg Clayton                                     Module *module = sc->module_sp.get();
22101b654882SGreg Clayton                                     var_name_begin += ::strlen ("module.");
22111b654882SGreg Clayton 
22120769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
22131b654882SGreg Clayton                                     {
22141b654882SGreg Clayton                                         if (module->GetFileSpec())
22151b654882SGreg Clayton                                         {
22161b654882SGreg Clayton                                             var_name_begin += ::strlen ("file.");
22171b654882SGreg Clayton 
22180769b2b1SMichael Sartain                                             if (IsToken (var_name_begin, "basename}"))
22191b654882SGreg Clayton                                             {
22201b654882SGreg Clayton                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
22219076c0ffSSean Callanan                                                 var_success = (bool)format_file_spec;
22221b654882SGreg Clayton                                             }
22230769b2b1SMichael Sartain                                             else if (IsToken (var_name_begin, "fullpath}"))
22241b654882SGreg Clayton                                             {
22251b654882SGreg Clayton                                                 format_file_spec = module->GetFileSpec();
22269076c0ffSSean Callanan                                                 var_success = (bool)format_file_spec;
22271b654882SGreg Clayton                                             }
22281b654882SGreg Clayton                                         }
22291b654882SGreg Clayton                                     }
22301b654882SGreg Clayton                                 }
22311b654882SGreg Clayton                             }
22321b654882SGreg Clayton                             break;
22331b654882SGreg Clayton 
22341b654882SGreg Clayton 
22351b654882SGreg Clayton                         case 'f':
22360769b2b1SMichael Sartain                            if (IsToken (var_name_begin, "file."))
22371b654882SGreg Clayton                             {
22381b654882SGreg Clayton                                 if (sc && sc->comp_unit != NULL)
22391b654882SGreg Clayton                                 {
22401b654882SGreg Clayton                                     var_name_begin += ::strlen ("file.");
22411b654882SGreg Clayton 
22420769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "basename}"))
22431b654882SGreg Clayton                                     {
22441b654882SGreg Clayton                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
22459076c0ffSSean Callanan                                         var_success = (bool)format_file_spec;
22461b654882SGreg Clayton                                     }
22470769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "fullpath}"))
22481b654882SGreg Clayton                                     {
22491b654882SGreg Clayton                                         format_file_spec = *sc->comp_unit;
22509076c0ffSSean Callanan                                         var_success = (bool)format_file_spec;
22511b654882SGreg Clayton                                     }
22521b654882SGreg Clayton                                 }
22531b654882SGreg Clayton                             }
22540769b2b1SMichael Sartain                            else if (IsToken (var_name_begin, "frame."))
22551b654882SGreg Clayton                             {
2256c14ee32dSGreg Clayton                                 if (exe_ctx)
2257c14ee32dSGreg Clayton                                 {
2258b57e4a1bSJason Molenda                                     StackFrame *frame = exe_ctx->GetFramePtr();
2259c14ee32dSGreg Clayton                                     if (frame)
22601b654882SGreg Clayton                                     {
22611b654882SGreg Clayton                                         var_name_begin += ::strlen ("frame.");
22620769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "index}"))
22631b654882SGreg Clayton                                         {
2264c14ee32dSGreg Clayton                                             s.Printf("%u", frame->GetFrameIndex());
22651b654882SGreg Clayton                                             var_success = true;
22661b654882SGreg Clayton                                         }
22670769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "pc}"))
22681b654882SGreg Clayton                                         {
22691b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22701b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_PC;
22711b654882SGreg Clayton                                             var_success = true;
22721b654882SGreg Clayton                                         }
22730769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "sp}"))
22741b654882SGreg Clayton                                         {
22751b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22761b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_SP;
22771b654882SGreg Clayton                                             var_success = true;
22781b654882SGreg Clayton                                         }
22790769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fp}"))
22801b654882SGreg Clayton                                         {
22811b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22821b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FP;
22831b654882SGreg Clayton                                             var_success = true;
22841b654882SGreg Clayton                                         }
22850769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "flags}"))
22861b654882SGreg Clayton                                         {
22871b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
22881b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
22891b654882SGreg Clayton                                             var_success = true;
22901b654882SGreg Clayton                                         }
22910769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "reg."))
22921b654882SGreg Clayton                                         {
2293c14ee32dSGreg Clayton                                             reg_ctx = frame->GetRegisterContext().get();
22941b654882SGreg Clayton                                             if (reg_ctx)
22951b654882SGreg Clayton                                             {
22961b654882SGreg Clayton                                                 var_name_begin += ::strlen ("reg.");
22971b654882SGreg Clayton                                                 if (var_name_begin < var_name_end)
22981b654882SGreg Clayton                                                 {
22991b654882SGreg Clayton                                                     std::string reg_name (var_name_begin, var_name_end);
23001b654882SGreg Clayton                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
23011b654882SGreg Clayton                                                     if (reg_info)
23021b654882SGreg Clayton                                                         var_success = true;
23031b654882SGreg Clayton                                                 }
23041b654882SGreg Clayton                                             }
23051b654882SGreg Clayton                                         }
23060769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "script:"))
2307aad8e480SEnrico Granata                                         {
2308aad8e480SEnrico Granata                                             var_name_begin += ::strlen("script:");
2309aad8e480SEnrico Granata                                             std::string script_name(var_name_begin,var_name_end);
2310aad8e480SEnrico Granata                                             ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
23110769b2b1SMichael Sartain                                             if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
2312aad8e480SEnrico Granata                                                 var_success = true;
2313aad8e480SEnrico Granata                                         }
2314aad8e480SEnrico Granata                                     }
2315aad8e480SEnrico Granata                                 }
23161b654882SGreg Clayton                             }
23170769b2b1SMichael Sartain                             else if (IsToken (var_name_begin, "function."))
23181b654882SGreg Clayton                             {
23191b654882SGreg Clayton                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
23201b654882SGreg Clayton                                 {
23211b654882SGreg Clayton                                     var_name_begin += ::strlen ("function.");
23220769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "id}"))
23231b654882SGreg Clayton                                     {
23241b654882SGreg Clayton                                         if (sc->function)
2325d01b2953SDaniel Malea                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
23261b654882SGreg Clayton                                         else
23271b654882SGreg Clayton                                             s.Printf("symbol[%u]", sc->symbol->GetID());
23281b654882SGreg Clayton 
23291b654882SGreg Clayton                                         var_success = true;
23301b654882SGreg Clayton                                     }
2331aff1b357SJason Molenda                                     if (IsToken (var_name_begin, "changed}") && function_changed)
2332aff1b357SJason Molenda                                     {
2333aff1b357SJason Molenda                                         var_success = true;
2334aff1b357SJason Molenda                                     }
2335aff1b357SJason Molenda                                     if (IsToken (var_name_begin, "initial-function}") && initial_function)
2336aff1b357SJason Molenda                                     {
2337aff1b357SJason Molenda                                         var_success = true;
2338aff1b357SJason Molenda                                     }
23390769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name}"))
23401b654882SGreg Clayton                                     {
23411b654882SGreg Clayton                                         if (sc->function)
23421b654882SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
23431b654882SGreg Clayton                                         else if (sc->symbol)
23441b654882SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
23451b654882SGreg Clayton                                         if (cstr)
23461b654882SGreg Clayton                                         {
23471b654882SGreg Clayton                                             s.PutCString(cstr);
23480d9c9934SGreg Clayton 
23490d9c9934SGreg Clayton                                             if (sc->block)
23500d9c9934SGreg Clayton                                             {
23510d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
23520d9c9934SGreg Clayton                                                 if (inline_block)
23530d9c9934SGreg Clayton                                                 {
23540d9c9934SGreg Clayton                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
23550d9c9934SGreg Clayton                                                     if (inline_info)
23560d9c9934SGreg Clayton                                                     {
23570d9c9934SGreg Clayton                                                         s.PutCString(" [inlined] ");
23580d9c9934SGreg Clayton                                                         inline_info->GetName().Dump(&s);
23590d9c9934SGreg Clayton                                                     }
23600d9c9934SGreg Clayton                                                 }
23610d9c9934SGreg Clayton                                             }
23621b654882SGreg Clayton                                             var_success = true;
23631b654882SGreg Clayton                                         }
23641b654882SGreg Clayton                                     }
2365aff1b357SJason Molenda                                     else if (IsToken (var_name_begin, "name-without-args}"))
2366aff1b357SJason Molenda                                     {
2367aff1b357SJason Molenda                                         ConstString name;
2368aff1b357SJason Molenda                                         if (sc->function)
2369aff1b357SJason Molenda                                             name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
2370aff1b357SJason Molenda                                         else if (sc->symbol)
2371aff1b357SJason Molenda                                             name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
2372aff1b357SJason Molenda                                         if (name)
2373aff1b357SJason Molenda                                         {
2374aff1b357SJason Molenda                                             s.PutCString(name.GetCString());
2375aff1b357SJason Molenda                                             var_success = true;
2376aff1b357SJason Molenda                                         }
2377aff1b357SJason Molenda                                     }
23780769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "name-with-args}"))
23796d3dbf51SGreg Clayton                                     {
23806d3dbf51SGreg Clayton                                         // Print the function name with arguments in it
23816d3dbf51SGreg Clayton 
23826d3dbf51SGreg Clayton                                         if (sc->function)
23836d3dbf51SGreg Clayton                                         {
23846d3dbf51SGreg Clayton                                             var_success = true;
23856d3dbf51SGreg Clayton                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
23866d3dbf51SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
23876d3dbf51SGreg Clayton                                             if (cstr)
23886d3dbf51SGreg Clayton                                             {
23896d3dbf51SGreg Clayton                                                 const InlineFunctionInfo *inline_info = NULL;
23906d3dbf51SGreg Clayton                                                 VariableListSP variable_list_sp;
23916d3dbf51SGreg Clayton                                                 bool get_function_vars = true;
23926d3dbf51SGreg Clayton                                                 if (sc->block)
23936d3dbf51SGreg Clayton                                                 {
23946d3dbf51SGreg Clayton                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
23956d3dbf51SGreg Clayton 
23966d3dbf51SGreg Clayton                                                     if (inline_block)
23976d3dbf51SGreg Clayton                                                     {
23986d3dbf51SGreg Clayton                                                         get_function_vars = false;
23996d3dbf51SGreg Clayton                                                         inline_info = sc->block->GetInlinedFunctionInfo();
24006d3dbf51SGreg Clayton                                                         if (inline_info)
24016d3dbf51SGreg Clayton                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
24026d3dbf51SGreg Clayton                                                     }
24036d3dbf51SGreg Clayton                                                 }
24046d3dbf51SGreg Clayton 
24056d3dbf51SGreg Clayton                                                 if (get_function_vars)
24066d3dbf51SGreg Clayton                                                 {
24076d3dbf51SGreg Clayton                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
24086d3dbf51SGreg Clayton                                                 }
24096d3dbf51SGreg Clayton 
24106d3dbf51SGreg Clayton                                                 if (inline_info)
24116d3dbf51SGreg Clayton                                                 {
24126d3dbf51SGreg Clayton                                                     s.PutCString (cstr);
24136d3dbf51SGreg Clayton                                                     s.PutCString (" [inlined] ");
24146d3dbf51SGreg Clayton                                                     cstr = inline_info->GetName().GetCString();
24156d3dbf51SGreg Clayton                                                 }
24166d3dbf51SGreg Clayton 
24176d3dbf51SGreg Clayton                                                 VariableList args;
24186d3dbf51SGreg Clayton                                                 if (variable_list_sp)
2419cc7f9bf5SEnrico Granata                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
24206d3dbf51SGreg Clayton                                                 if (args.GetSize() > 0)
24216d3dbf51SGreg Clayton                                                 {
24226d3dbf51SGreg Clayton                                                     const char *open_paren = strchr (cstr, '(');
2423e4a4f5d5SEnrico Granata                                                     const char *close_paren = nullptr;
2424e4a4f5d5SEnrico Granata                                                     const char *generic = strchr(cstr, '<');
2425e4a4f5d5SEnrico Granata                                                     // if before the arguments list begins there is a template sign
2426e4a4f5d5SEnrico Granata                                                     // then scan to the end of the generic args before you try to find
2427e4a4f5d5SEnrico Granata                                                     // the arguments list
2428e4a4f5d5SEnrico Granata                                                     if (generic && open_paren && generic < open_paren)
2429e4a4f5d5SEnrico Granata                                                     {
2430e4a4f5d5SEnrico Granata                                                         int generic_depth = 1;
2431e4a4f5d5SEnrico Granata                                                         ++generic;
2432e4a4f5d5SEnrico Granata                                                         for (;
2433e4a4f5d5SEnrico Granata                                                              *generic && generic_depth > 0;
2434e4a4f5d5SEnrico Granata                                                              generic++)
2435e4a4f5d5SEnrico Granata                                                         {
2436e4a4f5d5SEnrico Granata                                                             if (*generic == '<')
2437e4a4f5d5SEnrico Granata                                                                 generic_depth++;
2438e4a4f5d5SEnrico Granata                                                             if (*generic == '>')
2439e4a4f5d5SEnrico Granata                                                                 generic_depth--;
2440e4a4f5d5SEnrico Granata                                                         }
2441e4a4f5d5SEnrico Granata                                                         if (*generic)
2442e4a4f5d5SEnrico Granata                                                             open_paren = strchr(generic, '(');
2443e4a4f5d5SEnrico Granata                                                         else
2444e4a4f5d5SEnrico Granata                                                             open_paren = nullptr;
2445e4a4f5d5SEnrico Granata                                                     }
24466d3dbf51SGreg Clayton                                                     if (open_paren)
2447855958caSGreg Clayton                                                     {
24480769b2b1SMichael Sartain                                                         if (IsToken (open_paren, "(anonymous namespace)"))
2449855958caSGreg Clayton                                                         {
2450855958caSGreg Clayton                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2451855958caSGreg Clayton                                                             if (open_paren)
24526d3dbf51SGreg Clayton                                                                 close_paren = strchr (open_paren, ')');
2453855958caSGreg Clayton                                                         }
2454855958caSGreg Clayton                                                         else
2455855958caSGreg Clayton                                                             close_paren = strchr (open_paren, ')');
2456855958caSGreg Clayton                                                     }
24576d3dbf51SGreg Clayton 
24586d3dbf51SGreg Clayton                                                     if (open_paren)
24596d3dbf51SGreg Clayton                                                         s.Write(cstr, open_paren - cstr + 1);
24606d3dbf51SGreg Clayton                                                     else
24616d3dbf51SGreg Clayton                                                     {
24626d3dbf51SGreg Clayton                                                         s.PutCString (cstr);
24636d3dbf51SGreg Clayton                                                         s.PutChar ('(');
24646d3dbf51SGreg Clayton                                                     }
24655b6889b1SGreg Clayton                                                     const size_t num_args = args.GetSize();
24666d3dbf51SGreg Clayton                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
24676d3dbf51SGreg Clayton                                                     {
2468894f7359SEnrico Granata                                                         std::string buffer;
2469894f7359SEnrico Granata 
24706d3dbf51SGreg Clayton                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
24716d3dbf51SGreg Clayton                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
2472894f7359SEnrico Granata                                                         const char *var_representation = nullptr;
24736d3dbf51SGreg Clayton                                                         const char *var_name = var_value_sp->GetName().GetCString();
2474894f7359SEnrico Granata                                                         if (var_value_sp->GetClangType().IsAggregateType() &&
2475894f7359SEnrico Granata                                                             DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
2476894f7359SEnrico Granata                                                         {
2477894f7359SEnrico Granata                                                             static StringSummaryFormat format(TypeSummaryImpl::Flags()
2478894f7359SEnrico Granata                                                                                               .SetHideItemNames(false)
2479894f7359SEnrico Granata                                                                                               .SetShowMembersOneLiner(true),
2480894f7359SEnrico Granata                                                                                               "");
2481894f7359SEnrico Granata                                                             format.FormatObject(var_value_sp.get(), buffer);
2482894f7359SEnrico Granata                                                             var_representation = buffer.c_str();
2483894f7359SEnrico Granata                                                         }
2484894f7359SEnrico Granata                                                         else
2485894f7359SEnrico Granata                                                             var_representation = var_value_sp->GetValueAsCString();
24866d3dbf51SGreg Clayton                                                         if (arg_idx > 0)
24876d3dbf51SGreg Clayton                                                             s.PutCString (", ");
24883b188b17SGreg Clayton                                                         if (var_value_sp->GetError().Success())
2489cc7f9bf5SEnrico Granata                                                         {
2490894f7359SEnrico Granata                                                             if (var_representation)
2491894f7359SEnrico Granata                                                                 s.Printf ("%s=%s", var_name, var_representation);
24923b188b17SGreg Clayton                                                             else
2493cc7f9bf5SEnrico Granata                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2494cc7f9bf5SEnrico Granata                                                         }
2495cc7f9bf5SEnrico Granata                                                         else
24963b188b17SGreg Clayton                                                             s.Printf ("%s=<unavailable>", var_name);
24976d3dbf51SGreg Clayton                                                     }
24986d3dbf51SGreg Clayton 
24996d3dbf51SGreg Clayton                                                     if (close_paren)
25006d3dbf51SGreg Clayton                                                         s.PutCString (close_paren);
25016d3dbf51SGreg Clayton                                                     else
25026d3dbf51SGreg Clayton                                                         s.PutChar(')');
25036d3dbf51SGreg Clayton 
25046d3dbf51SGreg Clayton                                                 }
25056d3dbf51SGreg Clayton                                                 else
25066d3dbf51SGreg Clayton                                                 {
25076d3dbf51SGreg Clayton                                                     s.PutCString(cstr);
25086d3dbf51SGreg Clayton                                                 }
25096d3dbf51SGreg Clayton                                             }
25106d3dbf51SGreg Clayton                                         }
25116d3dbf51SGreg Clayton                                         else if (sc->symbol)
25126d3dbf51SGreg Clayton                                         {
25136d3dbf51SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
25146d3dbf51SGreg Clayton                                             if (cstr)
25156d3dbf51SGreg Clayton                                             {
25166d3dbf51SGreg Clayton                                                 s.PutCString(cstr);
25176d3dbf51SGreg Clayton                                                 var_success = true;
25186d3dbf51SGreg Clayton                                             }
25196d3dbf51SGreg Clayton                                         }
25206d3dbf51SGreg Clayton                                     }
2521aff1b357SJason Molenda                                     else if (IsToken (var_name_begin, "addr-offset}")
2522aff1b357SJason Molenda                                             || IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
25231b654882SGreg Clayton                                     {
2524aff1b357SJason Molenda                                         if (IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
2525aff1b357SJason Molenda                                         {
2526aff1b357SJason Molenda                                             addr_offset_print_with_no_padding = true;
2527aff1b357SJason Molenda                                             addr_offset_concrete_func_only = true;
2528aff1b357SJason Molenda                                         }
25291b654882SGreg Clayton                                         var_success = addr != NULL;
25301b654882SGreg Clayton                                         if (var_success)
25311b654882SGreg Clayton                                         {
25321b654882SGreg Clayton                                             format_addr = *addr;
25331b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
25341b654882SGreg Clayton                                         }
25351b654882SGreg Clayton                                     }
25360769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "line-offset}"))
25371b654882SGreg Clayton                                     {
25381b654882SGreg Clayton                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
25391b654882SGreg Clayton                                         if (var_success)
25401b654882SGreg Clayton                                         {
25411b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
25421b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
25431b654882SGreg Clayton                                         }
25441b654882SGreg Clayton                                     }
25450769b2b1SMichael Sartain                                     else if (IsToken (var_name_begin, "pc-offset}"))
25461b654882SGreg Clayton                                     {
2547b57e4a1bSJason Molenda                                         StackFrame *frame = exe_ctx->GetFramePtr();
2548c14ee32dSGreg Clayton                                         var_success = frame != NULL;
25491b654882SGreg Clayton                                         if (var_success)
25501b654882SGreg Clayton                                         {
2551c14ee32dSGreg Clayton                                             format_addr = frame->GetFrameCodeAddress();
25521b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
25531b654882SGreg Clayton                                         }
25541b654882SGreg Clayton                                     }
25551b654882SGreg Clayton                                 }
25561b654882SGreg Clayton                             }
25571b654882SGreg Clayton                             break;
25581b654882SGreg Clayton 
25591b654882SGreg Clayton                         case 'l':
25600769b2b1SMichael Sartain                             if (IsToken (var_name_begin, "line."))
25611b654882SGreg Clayton                             {
25621b654882SGreg Clayton                                 if (sc && sc->line_entry.IsValid())
25631b654882SGreg Clayton                                 {
25641b654882SGreg Clayton                                     var_name_begin += ::strlen ("line.");
25650769b2b1SMichael Sartain                                     if (IsToken (var_name_begin, "file."))
25661b654882SGreg Clayton                                     {
25671b654882SGreg Clayton                                         var_name_begin += ::strlen ("file.");
25681b654882SGreg Clayton 
25690769b2b1SMichael Sartain                                         if (IsToken (var_name_begin, "basename}"))
25701b654882SGreg Clayton                                         {
25711b654882SGreg Clayton                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
25729076c0ffSSean Callanan                                             var_success = (bool)format_file_spec;
25731b654882SGreg Clayton                                         }
25740769b2b1SMichael Sartain                                         else if (IsToken (var_name_begin, "fullpath}"))
25751b654882SGreg Clayton                                         {
25761b654882SGreg Clayton                                             format_file_spec = sc->line_entry.file;
25779076c0ffSSean Callanan                                             var_success = (bool)format_file_spec;
25781b654882SGreg Clayton                                         }
25791b654882SGreg Clayton                                     }
25800769b2b1SMichael Sartain                                     else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
25811b654882SGreg Clayton                                     {
25821b654882SGreg Clayton                                         var_success = true;
25830769b2b1SMichael Sartain                                         s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
25841b654882SGreg Clayton                                     }
25850769b2b1SMichael Sartain                                     else if ((IsToken (var_name_begin, "start-addr}")) ||
25860769b2b1SMichael Sartain                                              (IsToken (var_name_begin, "end-addr}")))
25871b654882SGreg Clayton                                     {
25881b654882SGreg Clayton                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
25891b654882SGreg Clayton                                         if (var_success)
25901b654882SGreg Clayton                                         {
25911b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
25921b654882SGreg Clayton                                             if (var_name_begin[0] == 'e')
25931b654882SGreg Clayton                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
25941b654882SGreg Clayton                                         }
25951b654882SGreg Clayton                                     }
25961b654882SGreg Clayton                                 }
25971b654882SGreg Clayton                             }
25981b654882SGreg Clayton                             break;
2599aff1b357SJason Molenda                         case 'c':
2600aff1b357SJason Molenda                             if (IsToken (var_name_begin, "current-pc-arrow"))
2601aff1b357SJason Molenda                             {
2602aff1b357SJason Molenda                                 if (addr && exe_ctx && exe_ctx->GetFramePtr())
2603aff1b357SJason Molenda                                 {
2604aff1b357SJason Molenda                                     RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
2605aff1b357SJason Molenda                                     if (reg_ctx.get())
2606aff1b357SJason Molenda                                     {
2607aff1b357SJason Molenda                                         addr_t pc_loadaddr = reg_ctx->GetPC();
2608aff1b357SJason Molenda                                         if (pc_loadaddr != LLDB_INVALID_ADDRESS)
2609aff1b357SJason Molenda                                         {
2610aff1b357SJason Molenda                                             Address pc;
2611aff1b357SJason Molenda                                             pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
2612aff1b357SJason Molenda                                             if (pc == *addr)
2613aff1b357SJason Molenda                                             {
2614aff1b357SJason Molenda                                                 s.Printf ("->");
2615aff1b357SJason Molenda                                                 var_success = true;
2616aff1b357SJason Molenda                                             }
2617aff1b357SJason Molenda                                             else
2618aff1b357SJason Molenda                                             {
2619aff1b357SJason Molenda                                                 s.Printf("  ");
2620aff1b357SJason Molenda                                                 var_success = true;
2621aff1b357SJason Molenda                                             }
2622aff1b357SJason Molenda                                         }
2623aff1b357SJason Molenda                                     }
2624aff1b357SJason Molenda                                 }
2625aff1b357SJason Molenda                             }
2626aff1b357SJason Molenda                             break;
26271b654882SGreg Clayton                         }
26281b654882SGreg Clayton 
26291b654882SGreg Clayton                         if (var_success)
26301b654882SGreg Clayton                         {
26311b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
26321b654882SGreg Clayton                             if (reg_num != LLDB_INVALID_REGNUM)
26331b654882SGreg Clayton                             {
2634b57e4a1bSJason Molenda                                 StackFrame *frame = exe_ctx->GetFramePtr();
26351b654882SGreg Clayton                                 // We have a register value to display...
26361b654882SGreg Clayton                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
26371b654882SGreg Clayton                                 {
2638c14ee32dSGreg Clayton                                     format_addr = frame->GetFrameCodeAddress();
26391b654882SGreg Clayton                                 }
26401b654882SGreg Clayton                                 else
26411b654882SGreg Clayton                                 {
26421b654882SGreg Clayton                                     if (reg_ctx == NULL)
2643c14ee32dSGreg Clayton                                         reg_ctx = frame->GetRegisterContext().get();
26441b654882SGreg Clayton 
26451b654882SGreg Clayton                                     if (reg_ctx)
26461b654882SGreg Clayton                                     {
26471b654882SGreg Clayton                                         if (reg_kind != kNumRegisterKinds)
26481b654882SGreg Clayton                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
26491b654882SGreg Clayton                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
26501b654882SGreg Clayton                                         var_success = reg_info != NULL;
26511b654882SGreg Clayton                                     }
26521b654882SGreg Clayton                                 }
26531b654882SGreg Clayton                             }
26541b654882SGreg Clayton 
26551b654882SGreg Clayton                             if (reg_info != NULL)
26561b654882SGreg Clayton                             {
26577349bd90SGreg Clayton                                 RegisterValue reg_value;
26587349bd90SGreg Clayton                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
26597349bd90SGreg Clayton                                 if (var_success)
26601b654882SGreg Clayton                                 {
26619a8fa916SGreg Clayton                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
26621b654882SGreg Clayton                                 }
26631b654882SGreg Clayton                             }
26641b654882SGreg Clayton 
26651b654882SGreg Clayton                             if (format_file_spec)
26661b654882SGreg Clayton                             {
26671b654882SGreg Clayton                                 s << format_file_spec;
26681b654882SGreg Clayton                             }
26691b654882SGreg Clayton 
26701b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
26711b654882SGreg Clayton                             if (format_addr.IsValid())
26721b654882SGreg Clayton                             {
26730603aa9dSGreg Clayton                                 var_success = false;
26740603aa9dSGreg Clayton 
26751b654882SGreg Clayton                                 if (calculate_format_addr_function_offset)
26761b654882SGreg Clayton                                 {
26771b654882SGreg Clayton                                     Address func_addr;
26780603aa9dSGreg Clayton 
26790603aa9dSGreg Clayton                                     if (sc)
26800603aa9dSGreg Clayton                                     {
26811b654882SGreg Clayton                                         if (sc->function)
26820d9c9934SGreg Clayton                                         {
26831b654882SGreg Clayton                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
2684aff1b357SJason Molenda                                             if (sc->block && addr_offset_concrete_func_only == false)
26850d9c9934SGreg Clayton                                             {
26860d9c9934SGreg Clayton                                                 // Check to make sure we aren't in an inline
26870d9c9934SGreg Clayton                                                 // function. If we are, use the inline block
26880d9c9934SGreg Clayton                                                 // range that contains "format_addr" since
26890d9c9934SGreg Clayton                                                 // blocks can be discontiguous.
26900d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
26910d9c9934SGreg Clayton                                                 AddressRange inline_range;
26920d9c9934SGreg Clayton                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
26930d9c9934SGreg Clayton                                                     func_addr = inline_range.GetBaseAddress();
26940d9c9934SGreg Clayton                                             }
26950d9c9934SGreg Clayton                                         }
2696e7612134SGreg Clayton                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2697e7612134SGreg Clayton                                             func_addr = sc->symbol->GetAddress();
26980603aa9dSGreg Clayton                                     }
26991b654882SGreg Clayton 
27000603aa9dSGreg Clayton                                     if (func_addr.IsValid())
27011b654882SGreg Clayton                                     {
2702aff1b357SJason Molenda                                         const char *addr_offset_padding  =  " ";
2703aff1b357SJason Molenda                                         if (addr_offset_print_with_no_padding)
2704aff1b357SJason Molenda                                         {
2705aff1b357SJason Molenda                                             addr_offset_padding = "";
2706aff1b357SJason Molenda                                         }
27071b654882SGreg Clayton                                         if (func_addr.GetSection() == format_addr.GetSection())
27081b654882SGreg Clayton                                         {
27091b654882SGreg Clayton                                             addr_t func_file_addr = func_addr.GetFileAddress();
27101b654882SGreg Clayton                                             addr_t addr_file_addr = format_addr.GetFileAddress();
27111b654882SGreg Clayton                                             if (addr_file_addr > func_file_addr)
2712aff1b357SJason Molenda                                                 s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
27131b654882SGreg Clayton                                             else if (addr_file_addr < func_file_addr)
2714aff1b357SJason Molenda                                                 s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
27150603aa9dSGreg Clayton                                             var_success = true;
27161b654882SGreg Clayton                                         }
27171b654882SGreg Clayton                                         else
27180603aa9dSGreg Clayton                                         {
27190603aa9dSGreg Clayton                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
27200603aa9dSGreg Clayton                                             if (target)
27210603aa9dSGreg Clayton                                             {
27220603aa9dSGreg Clayton                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
27230603aa9dSGreg Clayton                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
27240603aa9dSGreg Clayton                                                 if (addr_load_addr > func_load_addr)
2725aff1b357SJason Molenda                                                     s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
27260603aa9dSGreg Clayton                                                 else if (addr_load_addr < func_load_addr)
2727aff1b357SJason Molenda                                                     s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
27280603aa9dSGreg Clayton                                                 var_success = true;
27290603aa9dSGreg Clayton                                             }
27300603aa9dSGreg Clayton                                         }
27311b654882SGreg Clayton                                     }
27321b654882SGreg Clayton                                 }
27331b654882SGreg Clayton                                 else
27341b654882SGreg Clayton                                 {
27350603aa9dSGreg Clayton                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
27361b654882SGreg Clayton                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
27370603aa9dSGreg Clayton                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
27380603aa9dSGreg Clayton                                         vaddr = format_addr.GetLoadAddress (target);
27391b654882SGreg Clayton                                     if (vaddr == LLDB_INVALID_ADDRESS)
27401b654882SGreg Clayton                                         vaddr = format_addr.GetFileAddress ();
27411b654882SGreg Clayton 
27421b654882SGreg Clayton                                     if (vaddr != LLDB_INVALID_ADDRESS)
27430603aa9dSGreg Clayton                                     {
2744aff1b357SJason Molenda                                         int addr_width = 0;
2745aff1b357SJason Molenda                                         if (exe_ctx && target)
2746aff1b357SJason Molenda                                         {
2747fd1a9362SEric Christopher                                             addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
2748aff1b357SJason Molenda                                         }
274935f1a0d5SGreg Clayton                                         if (addr_width == 0)
275035f1a0d5SGreg Clayton                                             addr_width = 16;
2751aff1b357SJason Molenda                                         if (print_file_addr_or_load_addr)
2752aff1b357SJason Molenda                                         {
2753aff1b357SJason Molenda                                             format_addr.Dump (&s, exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
2754aff1b357SJason Molenda                                         }
2755aff1b357SJason Molenda                                         else
2756aff1b357SJason Molenda                                         {
2757d01b2953SDaniel Malea                                             s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
2758aff1b357SJason Molenda                                         }
27590603aa9dSGreg Clayton                                         var_success = true;
27600603aa9dSGreg Clayton                                     }
27611b654882SGreg Clayton                                 }
27621b654882SGreg Clayton                             }
27631b654882SGreg Clayton                         }
27641b654882SGreg Clayton 
27651b654882SGreg Clayton                         if (var_success == false)
27661b654882SGreg Clayton                             success = false;
27671b654882SGreg Clayton                     }
27681b654882SGreg Clayton                     p = var_name_end;
27691b654882SGreg Clayton                 }
27701b654882SGreg Clayton                 else
27711b654882SGreg Clayton                     break;
27721b654882SGreg Clayton             }
27731b654882SGreg Clayton             else
27741b654882SGreg Clayton             {
27751b654882SGreg Clayton                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
27761b654882SGreg Clayton                 s.PutChar(*p);
27771b654882SGreg Clayton             }
27781b654882SGreg Clayton         }
27791b654882SGreg Clayton         else if (*p == '\\')
27801b654882SGreg Clayton         {
27811b654882SGreg Clayton             ++p; // skip the slash
27821b654882SGreg Clayton             switch (*p)
27831b654882SGreg Clayton             {
27841b654882SGreg Clayton             case 'a': s.PutChar ('\a'); break;
27851b654882SGreg Clayton             case 'b': s.PutChar ('\b'); break;
27861b654882SGreg Clayton             case 'f': s.PutChar ('\f'); break;
27871b654882SGreg Clayton             case 'n': s.PutChar ('\n'); break;
27881b654882SGreg Clayton             case 'r': s.PutChar ('\r'); break;
27891b654882SGreg Clayton             case 't': s.PutChar ('\t'); break;
27901b654882SGreg Clayton             case 'v': s.PutChar ('\v'); break;
27911b654882SGreg Clayton             case '\'': s.PutChar ('\''); break;
27921b654882SGreg Clayton             case '\\': s.PutChar ('\\'); break;
27931b654882SGreg Clayton             case '0':
27941b654882SGreg Clayton                 // 1 to 3 octal chars
27951b654882SGreg Clayton                 {
27960603aa9dSGreg Clayton                     // Make a string that can hold onto the initial zero char,
27970603aa9dSGreg Clayton                     // up to 3 octal digits, and a terminating NULL.
27980603aa9dSGreg Clayton                     char oct_str[5] = { 0, 0, 0, 0, 0 };
27990603aa9dSGreg Clayton 
28000603aa9dSGreg Clayton                     int i;
28010603aa9dSGreg Clayton                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
28020603aa9dSGreg Clayton                         oct_str[i] = p[i];
28030603aa9dSGreg Clayton 
28040603aa9dSGreg Clayton                     // We don't want to consume the last octal character since
28050603aa9dSGreg Clayton                     // the main for loop will do this for us, so we advance p by
28060603aa9dSGreg Clayton                     // one less than i (even if i is zero)
28070603aa9dSGreg Clayton                     p += i - 1;
28080603aa9dSGreg Clayton                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
28090603aa9dSGreg Clayton                     if (octal_value <= UINT8_MAX)
28101b654882SGreg Clayton                     {
2811c7bece56SGreg Clayton                         s.PutChar((char)octal_value);
28121b654882SGreg Clayton                     }
28131b654882SGreg Clayton                 }
28141b654882SGreg Clayton                 break;
28151b654882SGreg Clayton 
28161b654882SGreg Clayton             case 'x':
28171b654882SGreg Clayton                 // hex number in the format
28180603aa9dSGreg Clayton                 if (isxdigit(p[1]))
28191b654882SGreg Clayton                 {
28200603aa9dSGreg Clayton                     ++p;    // Skip the 'x'
28211b654882SGreg Clayton 
28220603aa9dSGreg Clayton                     // Make a string that can hold onto two hex chars plus a
28230603aa9dSGreg Clayton                     // NULL terminator
28241b654882SGreg Clayton                     char hex_str[3] = { 0,0,0 };
28251b654882SGreg Clayton                     hex_str[0] = *p;
28260603aa9dSGreg Clayton                     if (isxdigit(p[1]))
28270603aa9dSGreg Clayton                     {
28280603aa9dSGreg Clayton                         ++p; // Skip the first of the two hex chars
28291b654882SGreg Clayton                         hex_str[1] = *p;
28300603aa9dSGreg Clayton                     }
28310603aa9dSGreg Clayton 
28321b654882SGreg Clayton                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
28330603aa9dSGreg Clayton                     if (hex_value <= UINT8_MAX)
2834c7bece56SGreg Clayton                         s.PutChar ((char)hex_value);
28351b654882SGreg Clayton                 }
28361b654882SGreg Clayton                 else
28371b654882SGreg Clayton                 {
28380603aa9dSGreg Clayton                     s.PutChar('x');
28391b654882SGreg Clayton                 }
28401b654882SGreg Clayton                 break;
28411b654882SGreg Clayton 
28421b654882SGreg Clayton             default:
28430603aa9dSGreg Clayton                 // Just desensitize any other character by just printing what
28440603aa9dSGreg Clayton                 // came after the '\'
28450603aa9dSGreg Clayton                 s << *p;
28461b654882SGreg Clayton                 break;
28471b654882SGreg Clayton 
28481b654882SGreg Clayton             }
28491b654882SGreg Clayton 
28501b654882SGreg Clayton         }
28511b654882SGreg Clayton     }
28521b654882SGreg Clayton     if (end)
28531b654882SGreg Clayton         *end = p;
28541b654882SGreg Clayton     return success;
28551b654882SGreg Clayton }
28561b654882SGreg Clayton 
2857c3ce7f27SMichael Sartain bool
2858c3ce7f27SMichael Sartain Debugger::FormatPrompt
2859c3ce7f27SMichael Sartain (
2860c3ce7f27SMichael Sartain     const char *format,
2861c3ce7f27SMichael Sartain     const SymbolContext *sc,
2862c3ce7f27SMichael Sartain     const ExecutionContext *exe_ctx,
2863c3ce7f27SMichael Sartain     const Address *addr,
2864c3ce7f27SMichael Sartain     Stream &s,
2865c3ce7f27SMichael Sartain     ValueObject* valobj
2866c3ce7f27SMichael Sartain )
2867c3ce7f27SMichael Sartain {
2868c3ce7f27SMichael Sartain     bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
2869c3ce7f27SMichael Sartain     std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
2870c3ce7f27SMichael Sartain     if (format_str.length())
2871c3ce7f27SMichael Sartain         format = format_str.c_str();
2872aff1b357SJason Molenda     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj, false, false);
2873c3ce7f27SMichael Sartain }
2874c3ce7f27SMichael Sartain 
2875aff1b357SJason Molenda bool
2876aff1b357SJason Molenda Debugger::FormatDisassemblerAddress (const char *format,
2877aff1b357SJason Molenda                                      const SymbolContext *sc,
2878aff1b357SJason Molenda                                      const SymbolContext *prev_sc,
2879aff1b357SJason Molenda                                      const ExecutionContext *exe_ctx,
2880aff1b357SJason Molenda                                      const Address *addr,
2881aff1b357SJason Molenda                                      Stream &s)
2882aff1b357SJason Molenda {
2883aff1b357SJason Molenda     if (format == NULL && exe_ctx != NULL && exe_ctx->HasTargetScope())
2884aff1b357SJason Molenda     {
2885aff1b357SJason Molenda         format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
2886aff1b357SJason Molenda     }
2887aff1b357SJason Molenda     bool function_changed = false;
2888aff1b357SJason Molenda     bool initial_function = false;
2889aff1b357SJason Molenda     if (prev_sc && (prev_sc->function || prev_sc->symbol))
2890aff1b357SJason Molenda     {
2891aff1b357SJason Molenda         if (sc && (sc->function || sc->symbol))
2892aff1b357SJason Molenda         {
2893aff1b357SJason Molenda             if (prev_sc->symbol && sc->symbol)
2894aff1b357SJason Molenda             {
2895aff1b357SJason Molenda                 if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
2896aff1b357SJason Molenda                 {
2897aff1b357SJason Molenda                     function_changed = true;
2898aff1b357SJason Molenda                 }
2899aff1b357SJason Molenda             }
2900aff1b357SJason Molenda             else if (prev_sc->function && sc->function)
2901aff1b357SJason Molenda             {
2902aff1b357SJason Molenda                 if (prev_sc->function->GetMangled() != sc->function->GetMangled())
2903aff1b357SJason Molenda                 {
2904aff1b357SJason Molenda                     function_changed = true;
2905aff1b357SJason Molenda                 }
2906aff1b357SJason Molenda             }
2907aff1b357SJason Molenda         }
2908aff1b357SJason Molenda     }
2909aff1b357SJason Molenda     // The first context on a list of instructions will have a prev_sc that
2910aff1b357SJason Molenda     // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
2911aff1b357SJason Molenda     // would return false.  But we do get a prev_sc pointer.
2912aff1b357SJason Molenda     if ((sc && (sc->function || sc->symbol))
2913aff1b357SJason Molenda         && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
2914aff1b357SJason Molenda     {
2915aff1b357SJason Molenda         initial_function = true;
2916aff1b357SJason Molenda     }
2917aff1b357SJason Molenda     return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, NULL, function_changed, initial_function);
2918aff1b357SJason Molenda }
2919aff1b357SJason Molenda 
2920aff1b357SJason Molenda 
2921228063cdSJim Ingham void
2922228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2923228063cdSJim Ingham {
29244f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
29254f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
29264f02b22dSJim Ingham     // callback.
2927228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2928228063cdSJim Ingham }
2929228063cdSJim Ingham 
2930228063cdSJim Ingham bool
2931228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2932228063cdSJim Ingham {
2933228063cdSJim Ingham     Log::Callbacks log_callbacks;
2934228063cdSJim Ingham 
2935228063cdSJim Ingham     StreamSP log_stream_sp;
29369a028519SSean Callanan     if (m_log_callback_stream_sp)
2937228063cdSJim Ingham     {
2938228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
2939228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
2940228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2941228063cdSJim Ingham     }
2942228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
2943228063cdSJim Ingham     {
294444d93782SGreg Clayton         log_stream_sp = GetOutputFile();
2945228063cdSJim Ingham     }
2946228063cdSJim Ingham     else
2947228063cdSJim Ingham     {
2948228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2949c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
2950c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
2951c1b2ccfdSGreg Clayton         if (!log_stream_sp)
2952228063cdSJim Ingham         {
2953228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
2954228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
2955228063cdSJim Ingham         }
2956228063cdSJim Ingham     }
2957228063cdSJim Ingham     assert (log_stream_sp.get());
2958228063cdSJim Ingham 
2959228063cdSJim Ingham     if (log_options == 0)
2960228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2961228063cdSJim Ingham 
296257abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2963228063cdSJim Ingham     {
2964228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2965228063cdSJim Ingham         return true;
2966228063cdSJim Ingham     }
2967228063cdSJim Ingham     else
2968228063cdSJim Ingham     {
2969228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2970228063cdSJim Ingham         if (log_channel_sp)
2971228063cdSJim Ingham         {
2972228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2973228063cdSJim Ingham             {
2974228063cdSJim Ingham                 return true;
2975228063cdSJim Ingham             }
2976228063cdSJim Ingham             else
2977228063cdSJim Ingham             {
2978228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2979228063cdSJim Ingham                 return false;
2980228063cdSJim Ingham             }
2981228063cdSJim Ingham         }
2982228063cdSJim Ingham         else
2983228063cdSJim Ingham         {
2984228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2985228063cdSJim Ingham             return false;
2986228063cdSJim Ingham         }
2987228063cdSJim Ingham     }
2988228063cdSJim Ingham     return false;
2989228063cdSJim Ingham }
2990228063cdSJim Ingham 
29919585fbfcSGreg Clayton SourceManager &
29929585fbfcSGreg Clayton Debugger::GetSourceManager ()
29939585fbfcSGreg Clayton {
29949585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
29959585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
29969585fbfcSGreg Clayton     return *m_source_manager_ap;
29979585fbfcSGreg Clayton }
29989585fbfcSGreg Clayton 
29999585fbfcSGreg Clayton 
300044d93782SGreg Clayton 
300144d93782SGreg Clayton // This function handles events that were broadcast by the process.
300244d93782SGreg Clayton void
300344d93782SGreg Clayton Debugger::HandleBreakpointEvent (const EventSP &event_sp)
300444d93782SGreg Clayton {
300544d93782SGreg Clayton     using namespace lldb;
300644d93782SGreg Clayton     const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
300744d93782SGreg Clayton 
300844d93782SGreg Clayton //    if (event_type & eBreakpointEventTypeAdded
300944d93782SGreg Clayton //        || event_type & eBreakpointEventTypeRemoved
301044d93782SGreg Clayton //        || event_type & eBreakpointEventTypeEnabled
301144d93782SGreg Clayton //        || event_type & eBreakpointEventTypeDisabled
301244d93782SGreg Clayton //        || event_type & eBreakpointEventTypeCommandChanged
301344d93782SGreg Clayton //        || event_type & eBreakpointEventTypeConditionChanged
301444d93782SGreg Clayton //        || event_type & eBreakpointEventTypeIgnoreChanged
301544d93782SGreg Clayton //        || event_type & eBreakpointEventTypeLocationsResolved)
301644d93782SGreg Clayton //    {
301744d93782SGreg Clayton //        // Don't do anything about these events, since the breakpoint commands already echo these actions.
301844d93782SGreg Clayton //    }
301944d93782SGreg Clayton //
302044d93782SGreg Clayton     if (event_type & eBreakpointEventTypeLocationsAdded)
302144d93782SGreg Clayton     {
302244d93782SGreg Clayton         uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
302344d93782SGreg Clayton         if (num_new_locations > 0)
302444d93782SGreg Clayton         {
302544d93782SGreg Clayton             BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
302644d93782SGreg Clayton             StreamFileSP output_sp (GetOutputFile());
302744d93782SGreg Clayton             if (output_sp)
302844d93782SGreg Clayton             {
302944d93782SGreg Clayton                 output_sp->Printf("%d location%s added to breakpoint %d\n",
303044d93782SGreg Clayton                                   num_new_locations,
303144d93782SGreg Clayton                                   num_new_locations == 1 ? "" : "s",
303244d93782SGreg Clayton                                   breakpoint->GetID());
303344d93782SGreg Clayton                 RefreshTopIOHandler();
303444d93782SGreg Clayton             }
303544d93782SGreg Clayton         }
303644d93782SGreg Clayton     }
303744d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
303844d93782SGreg Clayton //    {
303944d93782SGreg Clayton //        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
304044d93782SGreg Clayton //    }
304144d93782SGreg Clayton //    else if (event_type & eBreakpointEventTypeLocationsResolved)
304244d93782SGreg Clayton //    {
304344d93782SGreg Clayton //        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
304444d93782SGreg Clayton //    }
304544d93782SGreg Clayton }
304644d93782SGreg Clayton 
304744d93782SGreg Clayton size_t
304844d93782SGreg Clayton Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
304944d93782SGreg Clayton {
305044d93782SGreg Clayton     size_t total_bytes = 0;
305144d93782SGreg Clayton     if (stream == NULL)
305244d93782SGreg Clayton         stream = GetOutputFile().get();
305344d93782SGreg Clayton 
305444d93782SGreg Clayton     if (stream)
305544d93782SGreg Clayton     {
305644d93782SGreg Clayton         //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
305744d93782SGreg Clayton         if (process == NULL)
305844d93782SGreg Clayton         {
305944d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
306044d93782SGreg Clayton             if (target_sp)
306144d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
306244d93782SGreg Clayton         }
306344d93782SGreg Clayton         if (process)
306444d93782SGreg Clayton         {
306544d93782SGreg Clayton             Error error;
306644d93782SGreg Clayton             size_t len;
306744d93782SGreg Clayton             char stdio_buffer[1024];
306844d93782SGreg Clayton             while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
306944d93782SGreg Clayton             {
307044d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
307144d93782SGreg Clayton                 total_bytes += len;
307244d93782SGreg Clayton             }
307344d93782SGreg Clayton         }
307444d93782SGreg Clayton         stream->Flush();
307544d93782SGreg Clayton     }
307644d93782SGreg Clayton     return total_bytes;
307744d93782SGreg Clayton }
307844d93782SGreg Clayton 
307944d93782SGreg Clayton size_t
308044d93782SGreg Clayton Debugger::GetProcessSTDERR (Process *process, Stream *stream)
308144d93782SGreg Clayton {
308244d93782SGreg Clayton     size_t total_bytes = 0;
308344d93782SGreg Clayton     if (stream == NULL)
308444d93782SGreg Clayton         stream = GetOutputFile().get();
308544d93782SGreg Clayton 
308644d93782SGreg Clayton     if (stream)
308744d93782SGreg Clayton     {
308844d93782SGreg Clayton         //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
308944d93782SGreg Clayton         if (process == NULL)
309044d93782SGreg Clayton         {
309144d93782SGreg Clayton             TargetSP target_sp = GetTargetList().GetSelectedTarget();
309244d93782SGreg Clayton             if (target_sp)
309344d93782SGreg Clayton                 process = target_sp->GetProcessSP().get();
309444d93782SGreg Clayton         }
309544d93782SGreg Clayton         if (process)
309644d93782SGreg Clayton         {
309744d93782SGreg Clayton             Error error;
309844d93782SGreg Clayton             size_t len;
309944d93782SGreg Clayton             char stdio_buffer[1024];
310044d93782SGreg Clayton             while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
310144d93782SGreg Clayton             {
310244d93782SGreg Clayton                 stream->Write(stdio_buffer, len);
310344d93782SGreg Clayton                 total_bytes += len;
310444d93782SGreg Clayton             }
310544d93782SGreg Clayton         }
310644d93782SGreg Clayton         stream->Flush();
310744d93782SGreg Clayton     }
310844d93782SGreg Clayton     return total_bytes;
310944d93782SGreg Clayton }
311044d93782SGreg Clayton 
3111dc6224e0SGreg Clayton 
311244d93782SGreg Clayton // This function handles events that were broadcast by the process.
311344d93782SGreg Clayton void
311444d93782SGreg Clayton Debugger::HandleProcessEvent (const EventSP &event_sp)
311544d93782SGreg Clayton {
311644d93782SGreg Clayton     using namespace lldb;
311744d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
311844d93782SGreg Clayton     ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
311944d93782SGreg Clayton 
3120b4874f1aSGreg Clayton     StreamString output_stream;
3121b4874f1aSGreg Clayton     StreamString error_stream;
312244d93782SGreg Clayton     const bool gui_enabled = IsForwardingEvents();
312344d93782SGreg Clayton 
3124b4874f1aSGreg Clayton     if (!gui_enabled)
3125b4874f1aSGreg Clayton     {
3126b4874f1aSGreg Clayton         bool pop_process_io_handler = false;
312744d93782SGreg Clayton         assert (process_sp);
312844d93782SGreg Clayton 
3129b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
313044d93782SGreg Clayton         {
3131b4874f1aSGreg Clayton             GetProcessSTDOUT (process_sp.get(), &output_stream);
313244d93782SGreg Clayton         }
3133b4874f1aSGreg Clayton 
3134b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
313544d93782SGreg Clayton         {
3136b4874f1aSGreg Clayton             GetProcessSTDERR (process_sp.get(), &error_stream);
313744d93782SGreg Clayton         }
3138b4874f1aSGreg Clayton 
3139b4874f1aSGreg Clayton         if (event_type & Process::eBroadcastBitStateChanged)
314044d93782SGreg Clayton         {
3141dc6224e0SGreg Clayton             Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler);
314244d93782SGreg Clayton         }
3143b4874f1aSGreg Clayton 
3144b4874f1aSGreg Clayton         if (output_stream.GetSize() || error_stream.GetSize())
3145b4874f1aSGreg Clayton         {
3146b4874f1aSGreg Clayton             StreamFileSP error_stream_sp (GetOutputFile());
31476fea17e8SGreg Clayton             bool top_io_handler_hid = false;
31486fea17e8SGreg Clayton 
31496fea17e8SGreg Clayton             if (process_sp->ProcessIOHandlerIsActive() == false)
31506fea17e8SGreg Clayton                 top_io_handler_hid = HideTopIOHandler();
3151b4874f1aSGreg Clayton 
3152b4874f1aSGreg Clayton             if (output_stream.GetSize())
3153b4874f1aSGreg Clayton             {
3154b4874f1aSGreg Clayton                 StreamFileSP output_stream_sp (GetOutputFile());
3155b4874f1aSGreg Clayton                 if (output_stream_sp)
3156b4874f1aSGreg Clayton                     output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize());
3157b4874f1aSGreg Clayton             }
3158b4874f1aSGreg Clayton 
3159b4874f1aSGreg Clayton             if (error_stream.GetSize())
3160b4874f1aSGreg Clayton             {
3161b4874f1aSGreg Clayton                 StreamFileSP error_stream_sp (GetErrorFile());
3162b4874f1aSGreg Clayton                 if (error_stream_sp)
3163b4874f1aSGreg Clayton                     error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize());
316444d93782SGreg Clayton             }
316544d93782SGreg Clayton 
316644d93782SGreg Clayton             if (top_io_handler_hid)
316744d93782SGreg Clayton                 RefreshTopIOHandler();
316844d93782SGreg Clayton         }
316944d93782SGreg Clayton 
3170b4874f1aSGreg Clayton         if (pop_process_io_handler)
3171b4874f1aSGreg Clayton             process_sp->PopProcessIOHandler();
3172b4874f1aSGreg Clayton     }
3173b4874f1aSGreg Clayton }
3174b4874f1aSGreg Clayton 
317544d93782SGreg Clayton void
317644d93782SGreg Clayton Debugger::HandleThreadEvent (const EventSP &event_sp)
317744d93782SGreg Clayton {
317844d93782SGreg Clayton     // At present the only thread event we handle is the Frame Changed event,
317944d93782SGreg Clayton     // and all we do for that is just reprint the thread status for that thread.
318044d93782SGreg Clayton     using namespace lldb;
318144d93782SGreg Clayton     const uint32_t event_type = event_sp->GetType();
318244d93782SGreg Clayton     if (event_type == Thread::eBroadcastBitStackChanged   ||
318344d93782SGreg Clayton         event_type == Thread::eBroadcastBitThreadSelected )
318444d93782SGreg Clayton     {
318544d93782SGreg Clayton         ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
318644d93782SGreg Clayton         if (thread_sp)
318744d93782SGreg Clayton         {
318844d93782SGreg Clayton             HideTopIOHandler();
318944d93782SGreg Clayton             StreamFileSP stream_sp (GetOutputFile());
319044d93782SGreg Clayton             thread_sp->GetStatus(*stream_sp, 0, 1, 1);
319144d93782SGreg Clayton             RefreshTopIOHandler();
319244d93782SGreg Clayton         }
319344d93782SGreg Clayton     }
319444d93782SGreg Clayton }
319544d93782SGreg Clayton 
319644d93782SGreg Clayton bool
319744d93782SGreg Clayton Debugger::IsForwardingEvents ()
319844d93782SGreg Clayton {
319944d93782SGreg Clayton     return (bool)m_forward_listener_sp;
320044d93782SGreg Clayton }
320144d93782SGreg Clayton 
320244d93782SGreg Clayton void
320344d93782SGreg Clayton Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
320444d93782SGreg Clayton {
320544d93782SGreg Clayton     m_forward_listener_sp = listener_sp;
320644d93782SGreg Clayton }
320744d93782SGreg Clayton 
320844d93782SGreg Clayton void
320944d93782SGreg Clayton Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
321044d93782SGreg Clayton {
321144d93782SGreg Clayton     m_forward_listener_sp.reset();
321244d93782SGreg Clayton }
321344d93782SGreg Clayton 
321444d93782SGreg Clayton 
321544d93782SGreg Clayton void
321644d93782SGreg Clayton Debugger::DefaultEventHandler()
321744d93782SGreg Clayton {
321844d93782SGreg Clayton     Listener& listener(GetListener());
321944d93782SGreg Clayton     ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
322044d93782SGreg Clayton     ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
322144d93782SGreg Clayton     ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
322244d93782SGreg Clayton     BroadcastEventSpec target_event_spec (broadcaster_class_target,
322344d93782SGreg Clayton                                           Target::eBroadcastBitBreakpointChanged);
322444d93782SGreg Clayton 
322544d93782SGreg Clayton     BroadcastEventSpec process_event_spec (broadcaster_class_process,
322644d93782SGreg Clayton                                            Process::eBroadcastBitStateChanged   |
322744d93782SGreg Clayton                                            Process::eBroadcastBitSTDOUT         |
322844d93782SGreg Clayton                                            Process::eBroadcastBitSTDERR);
322944d93782SGreg Clayton 
323044d93782SGreg Clayton     BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
323144d93782SGreg Clayton                                           Thread::eBroadcastBitStackChanged     |
323244d93782SGreg Clayton                                           Thread::eBroadcastBitThreadSelected   );
323344d93782SGreg Clayton 
323444d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, target_event_spec);
323544d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, process_event_spec);
323644d93782SGreg Clayton     listener.StartListeningForEventSpec (*this, thread_event_spec);
323744d93782SGreg Clayton     listener.StartListeningForEvents (m_command_interpreter_ap.get(),
323844d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitQuitCommandReceived      |
323944d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousOutputData   |
324044d93782SGreg Clayton                                       CommandInterpreter::eBroadcastBitAsynchronousErrorData    );
324144d93782SGreg Clayton 
324244d93782SGreg Clayton     bool done = false;
324344d93782SGreg Clayton     while (!done)
324444d93782SGreg Clayton     {
324544d93782SGreg Clayton //        Mutex::Locker locker;
324644d93782SGreg Clayton //        if (locker.TryLock(m_input_reader_stack.GetMutex()))
324744d93782SGreg Clayton //        {
324844d93782SGreg Clayton //            if (m_input_reader_stack.IsEmpty())
324944d93782SGreg Clayton //                break;
325044d93782SGreg Clayton //        }
325144d93782SGreg Clayton //
325244d93782SGreg Clayton         EventSP event_sp;
325344d93782SGreg Clayton         if (listener.WaitForEvent(NULL, event_sp))
325444d93782SGreg Clayton         {
325544d93782SGreg Clayton             if (event_sp)
325644d93782SGreg Clayton             {
325744d93782SGreg Clayton                 Broadcaster *broadcaster = event_sp->GetBroadcaster();
325844d93782SGreg Clayton                 if (broadcaster)
325944d93782SGreg Clayton                 {
326044d93782SGreg Clayton                     uint32_t event_type = event_sp->GetType();
326144d93782SGreg Clayton                     ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
326244d93782SGreg Clayton                     if (broadcaster_class == broadcaster_class_process)
326344d93782SGreg Clayton                     {
326444d93782SGreg Clayton                         HandleProcessEvent (event_sp);
326544d93782SGreg Clayton                     }
326644d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_target)
326744d93782SGreg Clayton                     {
326844d93782SGreg Clayton                         if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
326944d93782SGreg Clayton                         {
327044d93782SGreg Clayton                             HandleBreakpointEvent (event_sp);
327144d93782SGreg Clayton                         }
327244d93782SGreg Clayton                     }
327344d93782SGreg Clayton                     else if (broadcaster_class == broadcaster_class_thread)
327444d93782SGreg Clayton                     {
327544d93782SGreg Clayton                         HandleThreadEvent (event_sp);
327644d93782SGreg Clayton                     }
327744d93782SGreg Clayton                     else if (broadcaster == m_command_interpreter_ap.get())
327844d93782SGreg Clayton                     {
327944d93782SGreg Clayton                         if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
328044d93782SGreg Clayton                         {
328144d93782SGreg Clayton                             done = true;
328244d93782SGreg Clayton                         }
328344d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
328444d93782SGreg Clayton                         {
328544d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
328644d93782SGreg Clayton                             if (data && data[0])
328744d93782SGreg Clayton                             {
328844d93782SGreg Clayton                                 StreamFileSP error_sp (GetErrorFile());
328944d93782SGreg Clayton                                 if (error_sp)
329044d93782SGreg Clayton                                 {
329144d93782SGreg Clayton                                     HideTopIOHandler();
329244d93782SGreg Clayton                                     error_sp->PutCString(data);
329344d93782SGreg Clayton                                     error_sp->Flush();
329444d93782SGreg Clayton                                     RefreshTopIOHandler();
329544d93782SGreg Clayton                                 }
329644d93782SGreg Clayton                             }
329744d93782SGreg Clayton                         }
329844d93782SGreg Clayton                         else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
329944d93782SGreg Clayton                         {
330044d93782SGreg Clayton                             const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
330144d93782SGreg Clayton                             if (data && data[0])
330244d93782SGreg Clayton                             {
330344d93782SGreg Clayton                                 StreamFileSP output_sp (GetOutputFile());
330444d93782SGreg Clayton                                 if (output_sp)
330544d93782SGreg Clayton                                 {
330644d93782SGreg Clayton                                     HideTopIOHandler();
330744d93782SGreg Clayton                                     output_sp->PutCString(data);
330844d93782SGreg Clayton                                     output_sp->Flush();
330944d93782SGreg Clayton                                     RefreshTopIOHandler();
331044d93782SGreg Clayton                                 }
331144d93782SGreg Clayton                             }
331244d93782SGreg Clayton                         }
331344d93782SGreg Clayton                     }
331444d93782SGreg Clayton                 }
331544d93782SGreg Clayton 
331644d93782SGreg Clayton                 if (m_forward_listener_sp)
331744d93782SGreg Clayton                     m_forward_listener_sp->AddEvent(event_sp);
331844d93782SGreg Clayton             }
331944d93782SGreg Clayton         }
332044d93782SGreg Clayton     }
332144d93782SGreg Clayton }
332244d93782SGreg Clayton 
332344d93782SGreg Clayton lldb::thread_result_t
332444d93782SGreg Clayton Debugger::EventHandlerThread (lldb::thread_arg_t arg)
332544d93782SGreg Clayton {
332644d93782SGreg Clayton     ((Debugger *)arg)->DefaultEventHandler();
332744d93782SGreg Clayton     return NULL;
332844d93782SGreg Clayton }
332944d93782SGreg Clayton 
333044d93782SGreg Clayton bool
333144d93782SGreg Clayton Debugger::StartEventHandlerThread()
333244d93782SGreg Clayton {
3333acee96aeSZachary Turner     if (!m_event_handler_thread.IsJoinable())
3334807b6b32SGreg Clayton     {
33357c2896a2SZachary Turner         // Use larger 8MB stack for this thread
33367c2896a2SZachary Turner         m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread, this, NULL,
33377c2896a2SZachary Turner                                                               g_debugger_event_thread_stack_bytes);
3338807b6b32SGreg Clayton     }
3339acee96aeSZachary Turner     return m_event_handler_thread.IsJoinable();
334044d93782SGreg Clayton }
334144d93782SGreg Clayton 
334244d93782SGreg Clayton void
334344d93782SGreg Clayton Debugger::StopEventHandlerThread()
334444d93782SGreg Clayton {
3345acee96aeSZachary Turner     if (m_event_handler_thread.IsJoinable())
334644d93782SGreg Clayton     {
334744d93782SGreg Clayton         GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
334839de3110SZachary Turner         m_event_handler_thread.Join(nullptr);
334944d93782SGreg Clayton     }
335044d93782SGreg Clayton }
335144d93782SGreg Clayton 
335244d93782SGreg Clayton 
335344d93782SGreg Clayton lldb::thread_result_t
335444d93782SGreg Clayton Debugger::IOHandlerThread (lldb::thread_arg_t arg)
335544d93782SGreg Clayton {
335644d93782SGreg Clayton     Debugger *debugger = (Debugger *)arg;
335744d93782SGreg Clayton     debugger->ExecuteIOHanders();
335844d93782SGreg Clayton     debugger->StopEventHandlerThread();
335944d93782SGreg Clayton     return NULL;
336044d93782SGreg Clayton }
336144d93782SGreg Clayton 
336244d93782SGreg Clayton bool
336344d93782SGreg Clayton Debugger::StartIOHandlerThread()
336444d93782SGreg Clayton {
3365acee96aeSZachary Turner     if (!m_io_handler_thread.IsJoinable())
3366807b6b32SGreg Clayton         m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
3367807b6b32SGreg Clayton                                                             IOHandlerThread,
3368807b6b32SGreg Clayton                                                             this,
3369807b6b32SGreg Clayton                                                             NULL,
3370807b6b32SGreg Clayton                                                             8*1024*1024); // Use larger 8MB stack for this thread
3371acee96aeSZachary Turner     return m_io_handler_thread.IsJoinable();
337244d93782SGreg Clayton }
337344d93782SGreg Clayton 
337444d93782SGreg Clayton void
337544d93782SGreg Clayton Debugger::StopIOHandlerThread()
337644d93782SGreg Clayton {
3377acee96aeSZachary Turner     if (m_io_handler_thread.IsJoinable())
337844d93782SGreg Clayton     {
337944d93782SGreg Clayton         if (m_input_file_sp)
338044d93782SGreg Clayton             m_input_file_sp->GetFile().Close();
338139de3110SZachary Turner         m_io_handler_thread.Join(nullptr);
338244d93782SGreg Clayton     }
338344d93782SGreg Clayton }
338444d93782SGreg Clayton 
338544d93782SGreg Clayton 
3386