130fdc8d8SChris Lattner //===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
1221dfcd9dSEnrico Granata #include "lldb/API/SBDebugger.h"
1321dfcd9dSEnrico Granata 
144a33d318SGreg Clayton #include "lldb/Core/Debugger.h"
154a33d318SGreg Clayton 
164a33d318SGreg Clayton #include <map>
174a33d318SGreg Clayton 
184becb37eSEnrico Granata #include "clang/AST/DeclCXX.h"
194becb37eSEnrico Granata #include "clang/AST/Type.h"
204becb37eSEnrico Granata 
2130fdc8d8SChris Lattner #include "lldb/lldb-private.h"
2230fdc8d8SChris Lattner #include "lldb/Core/ConnectionFileDescriptor.h"
2330fdc8d8SChris Lattner #include "lldb/Core/InputReader.h"
241f746071SGreg Clayton #include "lldb/Core/Module.h"
25e8cd0c98SGreg Clayton #include "lldb/Core/PluginManager.h"
267349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h"
2730fdc8d8SChris Lattner #include "lldb/Core/State.h"
285b52f0c7SJim Ingham #include "lldb/Core/StreamAsynchronousIO.h"
29228063cdSJim Ingham #include "lldb/Core/StreamCallback.h"
301b654882SGreg Clayton #include "lldb/Core/StreamString.h"
3130fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
324becb37eSEnrico Granata #include "lldb/Core/ValueObject.h"
336d3dbf51SGreg Clayton #include "lldb/Core/ValueObjectVariable.h"
345548cb50SEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
355548cb50SEnrico Granata #include "lldb/DataFormatters/FormatManager.h"
3621dfcd9dSEnrico Granata #include "lldb/Host/DynamicLibrary.h"
37a3406614SGreg Clayton #include "lldb/Host/Terminal.h"
386611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
3967cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueSInt64.h"
4067cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h"
411f746071SGreg Clayton #include "lldb/Symbol/ClangASTContext.h"
421f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
431f746071SGreg Clayton #include "lldb/Symbol/Function.h"
441f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
456d3dbf51SGreg Clayton #include "lldb/Symbol/VariableList.h"
4630fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
4730fdc8d8SChris Lattner #include "lldb/Target/Process.h"
481b654882SGreg Clayton #include "lldb/Target/RegisterContext.h"
491b654882SGreg Clayton #include "lldb/Target/StopInfo.h"
5030fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
515a31471eSGreg Clayton #include "lldb/Utility/AnsiTerminal.h"
5230fdc8d8SChris Lattner 
5330fdc8d8SChris Lattner using namespace lldb;
5430fdc8d8SChris Lattner using namespace lldb_private;
5530fdc8d8SChris Lattner 
5630fdc8d8SChris Lattner 
571b654882SGreg Clayton static uint32_t g_shared_debugger_refcount = 0;
58ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
59ebc1bb27SCaroline Tice 
601b654882SGreg Clayton #pragma mark Static Functions
611b654882SGreg Clayton 
621b654882SGreg Clayton static Mutex &
631b654882SGreg Clayton GetDebuggerListMutex ()
641b654882SGreg Clayton {
651b654882SGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
661b654882SGreg Clayton     return g_mutex;
671b654882SGreg Clayton }
681b654882SGreg Clayton 
691b654882SGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
701b654882SGreg Clayton 
711b654882SGreg Clayton static DebuggerList &
721b654882SGreg Clayton GetDebuggerList()
731b654882SGreg Clayton {
741b654882SGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
751b654882SGreg Clayton     // global init contructors
761b654882SGreg Clayton     static DebuggerList g_list;
771b654882SGreg Clayton     return g_list;
781b654882SGreg Clayton }
79e372b98dSGreg Clayton 
80e372b98dSGreg Clayton OptionEnumValueElement
8167cc0636SGreg Clayton g_show_disassembly_enum_values[] =
82e372b98dSGreg Clayton {
8367cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNever,    "never",     "Never show disassembly when displaying a stop context."},
8467cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
8567cc0636SGreg Clayton     { Debugger::eStopDisassemblyTypeAlways,   "always",    "Always show disassembly when displaying a stop context."},
86e372b98dSGreg Clayton     { 0, NULL, NULL }
87e372b98dSGreg Clayton };
88e372b98dSGreg Clayton 
8967cc0636SGreg Clayton OptionEnumValueElement
9067cc0636SGreg Clayton g_language_enumerators[] =
9167cc0636SGreg Clayton {
9267cc0636SGreg Clayton     { eScriptLanguageNone,      "none",     "Disable scripting languages."},
9367cc0636SGreg Clayton     { eScriptLanguagePython,    "python",   "Select python as the default scripting language."},
9467cc0636SGreg Clayton     { eScriptLanguageDefault,   "default",  "Select the lldb default as the default scripting language."},
95a12993c9SGreg Clayton     { 0, NULL, NULL }
9667cc0636SGreg Clayton };
97e372b98dSGreg Clayton 
9867cc0636SGreg Clayton #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
9967cc0636SGreg Clayton #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
10067cc0636SGreg Clayton 
10167cc0636SGreg Clayton #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
10267cc0636SGreg Clayton     "{, ${frame.pc}}"\
10367cc0636SGreg Clayton     MODULE_WITH_FUNC\
10467cc0636SGreg Clayton     FILE_AND_LINE\
10585d0c57bSGreg Clayton     "{, name = '${thread.name}}"\
10685d0c57bSGreg Clayton     "{, queue = '${thread.queue}}"\
10767cc0636SGreg Clayton     "{, stop reason = ${thread.stop-reason}}"\
10867cc0636SGreg Clayton     "{\\nReturn value: ${thread.return-value}}"\
10967cc0636SGreg Clayton     "\\n"
11067cc0636SGreg Clayton 
11167cc0636SGreg Clayton #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
11267cc0636SGreg Clayton     MODULE_WITH_FUNC\
11367cc0636SGreg Clayton     FILE_AND_LINE\
11467cc0636SGreg Clayton     "\\n"
11567cc0636SGreg Clayton 
11667cc0636SGreg Clayton 
11767cc0636SGreg Clayton 
118754a9369SGreg Clayton static PropertyDefinition
119754a9369SGreg Clayton g_properties[] =
12067cc0636SGreg Clayton {
12167cc0636SGreg Clayton {   "auto-confirm",             OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
12267cc0636SGreg 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." },
12367cc0636SGreg Clayton {   "notify-void",              OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
1244c05410fSGreg Clayton {   "prompt",                   OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
12567cc0636SGreg Clayton {   "script-lang",              OptionValue::eTypeEnum   , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
12667cc0636SGreg Clayton {   "stop-disassembly-count",   OptionValue::eTypeSInt64 , true, 4    , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
12767cc0636SGreg 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." },
12867cc0636SGreg 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." },
12967cc0636SGreg 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." },
13067cc0636SGreg Clayton {   "term-width",               OptionValue::eTypeSInt64 , true, 80   , NULL, NULL, "The maximum number of columns to use for displaying text." },
13167cc0636SGreg Clayton {   "thread-format",            OptionValue::eTypeString , true, 0    , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
13267cc0636SGreg Clayton {   "use-external-editor",      OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
133e8cd0c98SGreg Clayton 
13467cc0636SGreg Clayton     {   NULL,                       OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
13567cc0636SGreg Clayton };
13667cc0636SGreg Clayton 
13767cc0636SGreg Clayton enum
13867cc0636SGreg Clayton {
13967cc0636SGreg Clayton     ePropertyAutoConfirm = 0,
14067cc0636SGreg Clayton     ePropertyFrameFormat,
14167cc0636SGreg Clayton     ePropertyNotiftVoid,
14267cc0636SGreg Clayton     ePropertyPrompt,
14367cc0636SGreg Clayton     ePropertyScriptLanguage,
14467cc0636SGreg Clayton     ePropertyStopDisassemblyCount,
14567cc0636SGreg Clayton     ePropertyStopDisassemblyDisplay,
14667cc0636SGreg Clayton     ePropertyStopLineCountAfter,
14767cc0636SGreg Clayton     ePropertyStopLineCountBefore,
14867cc0636SGreg Clayton     ePropertyTerminalWidth,
14967cc0636SGreg Clayton     ePropertyThreadFormat,
15067cc0636SGreg Clayton     ePropertyUseExternalEditor
15167cc0636SGreg Clayton };
15267cc0636SGreg Clayton 
15367cc0636SGreg Clayton //
15467cc0636SGreg Clayton //const char *
15567cc0636SGreg Clayton //Debugger::GetFrameFormat() const
15667cc0636SGreg Clayton //{
15767cc0636SGreg Clayton //    return m_properties_sp->GetFrameFormat();
15867cc0636SGreg Clayton //}
15967cc0636SGreg Clayton //const char *
16067cc0636SGreg Clayton //Debugger::GetThreadFormat() const
16167cc0636SGreg Clayton //{
16267cc0636SGreg Clayton //    return m_properties_sp->GetThreadFormat();
16367cc0636SGreg Clayton //}
16467cc0636SGreg Clayton //
1654c05410fSGreg Clayton 
1664c05410fSGreg Clayton 
1674c05410fSGreg Clayton Error
1684c05410fSGreg Clayton Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
1694c05410fSGreg Clayton                             VarSetOperationType op,
1704c05410fSGreg Clayton                             const char *property_path,
1714c05410fSGreg Clayton                             const char *value)
1724c05410fSGreg Clayton {
1734c05410fSGreg Clayton     Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
1744c05410fSGreg Clayton     if (error.Success())
1754c05410fSGreg Clayton     {
1764c05410fSGreg Clayton         if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
1774c05410fSGreg Clayton         {
1784c05410fSGreg Clayton             const char *new_prompt = GetPrompt();
1794c05410fSGreg Clayton             EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
1804c05410fSGreg Clayton             GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
1814c05410fSGreg Clayton         }
1824c05410fSGreg Clayton     }
1834c05410fSGreg Clayton     return error;
1844c05410fSGreg Clayton }
1854c05410fSGreg Clayton 
18667cc0636SGreg Clayton bool
18767cc0636SGreg Clayton Debugger::GetAutoConfirm () const
18867cc0636SGreg Clayton {
18967cc0636SGreg Clayton     const uint32_t idx = ePropertyAutoConfirm;
190754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
19167cc0636SGreg Clayton }
19267cc0636SGreg Clayton 
19367cc0636SGreg Clayton const char *
19467cc0636SGreg Clayton Debugger::GetFrameFormat() const
19567cc0636SGreg Clayton {
19667cc0636SGreg Clayton     const uint32_t idx = ePropertyFrameFormat;
197754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
19867cc0636SGreg Clayton }
19967cc0636SGreg Clayton 
20067cc0636SGreg Clayton bool
20167cc0636SGreg Clayton Debugger::GetNotifyVoid () const
20267cc0636SGreg Clayton {
20367cc0636SGreg Clayton     const uint32_t idx = ePropertyNotiftVoid;
204754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
20567cc0636SGreg Clayton }
20667cc0636SGreg Clayton 
20767cc0636SGreg Clayton const char *
20867cc0636SGreg Clayton Debugger::GetPrompt() const
20967cc0636SGreg Clayton {
21067cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
211754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
21267cc0636SGreg Clayton }
21367cc0636SGreg Clayton 
21467cc0636SGreg Clayton void
21567cc0636SGreg Clayton Debugger::SetPrompt(const char *p)
21667cc0636SGreg Clayton {
21767cc0636SGreg Clayton     const uint32_t idx = ePropertyPrompt;
21867cc0636SGreg Clayton     m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, p);
21967cc0636SGreg Clayton     const char *new_prompt = GetPrompt();
22067cc0636SGreg Clayton     EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
22167cc0636SGreg Clayton     GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
22267cc0636SGreg Clayton }
22367cc0636SGreg Clayton 
22467cc0636SGreg Clayton const char *
22567cc0636SGreg Clayton Debugger::GetThreadFormat() const
22667cc0636SGreg Clayton {
22767cc0636SGreg Clayton     const uint32_t idx = ePropertyThreadFormat;
228754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
22967cc0636SGreg Clayton }
23067cc0636SGreg Clayton 
23167cc0636SGreg Clayton lldb::ScriptLanguage
23267cc0636SGreg Clayton Debugger::GetScriptLanguage() const
23367cc0636SGreg Clayton {
23467cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
235754a9369SGreg Clayton     return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
23667cc0636SGreg Clayton }
23767cc0636SGreg Clayton 
23867cc0636SGreg Clayton bool
23967cc0636SGreg Clayton Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
24067cc0636SGreg Clayton {
24167cc0636SGreg Clayton     const uint32_t idx = ePropertyScriptLanguage;
24267cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsEnumeration (NULL, idx, script_lang);
24367cc0636SGreg Clayton }
24467cc0636SGreg Clayton 
24567cc0636SGreg Clayton uint32_t
24667cc0636SGreg Clayton Debugger::GetTerminalWidth () const
24767cc0636SGreg Clayton {
24867cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
249754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
25067cc0636SGreg Clayton }
25167cc0636SGreg Clayton 
25267cc0636SGreg Clayton bool
25367cc0636SGreg Clayton Debugger::SetTerminalWidth (uint32_t term_width)
25467cc0636SGreg Clayton {
25567cc0636SGreg Clayton     const uint32_t idx = ePropertyTerminalWidth;
25667cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsSInt64 (NULL, idx, term_width);
25767cc0636SGreg Clayton }
25867cc0636SGreg Clayton 
25967cc0636SGreg Clayton bool
26067cc0636SGreg Clayton Debugger::GetUseExternalEditor () const
26167cc0636SGreg Clayton {
26267cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
263754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
26467cc0636SGreg Clayton }
26567cc0636SGreg Clayton 
26667cc0636SGreg Clayton bool
26767cc0636SGreg Clayton Debugger::SetUseExternalEditor (bool b)
26867cc0636SGreg Clayton {
26967cc0636SGreg Clayton     const uint32_t idx = ePropertyUseExternalEditor;
27067cc0636SGreg Clayton     return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
27167cc0636SGreg Clayton }
27267cc0636SGreg Clayton 
27367cc0636SGreg Clayton uint32_t
27467cc0636SGreg Clayton Debugger::GetStopSourceLineCount (bool before) const
27567cc0636SGreg Clayton {
27667cc0636SGreg Clayton     const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
277754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
27867cc0636SGreg Clayton }
27967cc0636SGreg Clayton 
28067cc0636SGreg Clayton Debugger::StopDisassemblyType
28167cc0636SGreg Clayton Debugger::GetStopDisassemblyDisplay () const
28267cc0636SGreg Clayton {
28367cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyDisplay;
284754a9369SGreg Clayton     return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
28567cc0636SGreg Clayton }
28667cc0636SGreg Clayton 
28767cc0636SGreg Clayton uint32_t
28867cc0636SGreg Clayton Debugger::GetDisassemblyLineCount () const
28967cc0636SGreg Clayton {
29067cc0636SGreg Clayton     const uint32_t idx = ePropertyStopDisassemblyCount;
291754a9369SGreg Clayton     return m_collection_sp->GetPropertyAtIndexAsSInt64 (NULL, idx, g_properties[idx].default_uint_value);
29267cc0636SGreg Clayton }
293e372b98dSGreg Clayton 
2941b654882SGreg Clayton #pragma mark Debugger
2951b654882SGreg Clayton 
29667cc0636SGreg Clayton //const DebuggerPropertiesSP &
29767cc0636SGreg Clayton //Debugger::GetSettings() const
29867cc0636SGreg Clayton //{
29967cc0636SGreg Clayton //    return m_properties_sp;
30067cc0636SGreg Clayton //}
30167cc0636SGreg Clayton //
30299d0faf2SGreg Clayton 
3032f88aadfSCaroline Tice int
3042f88aadfSCaroline Tice Debugger::TestDebuggerRefCount ()
3052f88aadfSCaroline Tice {
3062f88aadfSCaroline Tice     return g_shared_debugger_refcount;
3072f88aadfSCaroline Tice }
3082f88aadfSCaroline Tice 
30930fdc8d8SChris Lattner void
31030fdc8d8SChris Lattner Debugger::Initialize ()
31130fdc8d8SChris Lattner {
312c15f55e2SGreg Clayton     if (g_shared_debugger_refcount++ == 0)
313dbe54508SGreg Clayton         lldb_private::Initialize();
31499d0faf2SGreg Clayton }
31530fdc8d8SChris Lattner 
31630fdc8d8SChris Lattner void
31730fdc8d8SChris Lattner Debugger::Terminate ()
31830fdc8d8SChris Lattner {
3196611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
3206611103cSGreg Clayton     {
32130fdc8d8SChris Lattner         g_shared_debugger_refcount--;
32230fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
32330fdc8d8SChris Lattner         {
324dbe54508SGreg Clayton             lldb_private::WillTerminate();
325dbe54508SGreg Clayton             lldb_private::Terminate();
3266760a517SCaroline Tice 
32799d0faf2SGreg Clayton             // Clear our master list of debugger objects
32899d0faf2SGreg Clayton             Mutex::Locker locker (GetDebuggerListMutex ());
32999d0faf2SGreg Clayton             GetDebuggerList().clear();
33030fdc8d8SChris Lattner         }
3316760a517SCaroline Tice     }
3326760a517SCaroline Tice }
33330fdc8d8SChris Lattner 
33420bd37f7SCaroline Tice void
33520bd37f7SCaroline Tice Debugger::SettingsInitialize ()
33620bd37f7SCaroline Tice {
3376920b52bSGreg Clayton     Target::SettingsInitialize ();
33820bd37f7SCaroline Tice }
33920bd37f7SCaroline Tice 
34020bd37f7SCaroline Tice void
34120bd37f7SCaroline Tice Debugger::SettingsTerminate ()
34220bd37f7SCaroline Tice {
3436920b52bSGreg Clayton     Target::SettingsTerminate ();
34420bd37f7SCaroline Tice }
34520bd37f7SCaroline Tice 
34621dfcd9dSEnrico Granata bool
347e743c782SEnrico Granata Debugger::LoadPlugin (const FileSpec& spec, Error& error)
34821dfcd9dSEnrico Granata {
34921dfcd9dSEnrico Granata     lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec));
350e743c782SEnrico Granata     if (!dynlib_sp || dynlib_sp->IsValid() == false)
351e743c782SEnrico Granata     {
352e743c782SEnrico Granata         if (spec.Exists())
353e743c782SEnrico Granata             error.SetErrorString("this file does not represent a loadable dylib");
354e743c782SEnrico Granata         else
355e743c782SEnrico Granata             error.SetErrorString("no such file");
356e743c782SEnrico Granata         return false;
357e743c782SEnrico Granata     }
35821dfcd9dSEnrico Granata     lldb::DebuggerSP debugger_sp(shared_from_this());
35921dfcd9dSEnrico Granata     lldb::SBDebugger debugger_sb(debugger_sp);
36021dfcd9dSEnrico Granata     // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays
36121dfcd9dSEnrico Granata     LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol<LLDBCommandPluginInit>("_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
36221dfcd9dSEnrico Granata     if (!init_func)
363e743c782SEnrico Granata     {
364e743c782SEnrico Granata         error.SetErrorString("cannot find the initialization function lldb::PluginInitialize(lldb::SBDebugger)");
36521dfcd9dSEnrico Granata         return false;
366e743c782SEnrico Granata     }
36721dfcd9dSEnrico Granata     if (init_func(debugger_sb))
36821dfcd9dSEnrico Granata     {
36921dfcd9dSEnrico Granata         m_loaded_plugins.push_back(dynlib_sp);
37021dfcd9dSEnrico Granata         return true;
37121dfcd9dSEnrico Granata     }
372e743c782SEnrico Granata     error.SetErrorString("dylib refused to be loaded");
37321dfcd9dSEnrico Granata     return false;
37421dfcd9dSEnrico Granata }
37521dfcd9dSEnrico Granata 
37621dfcd9dSEnrico Granata static FileSpec::EnumerateDirectoryResult
37721dfcd9dSEnrico Granata LoadPluginCallback
37821dfcd9dSEnrico Granata (
37921dfcd9dSEnrico Granata  void *baton,
38021dfcd9dSEnrico Granata  FileSpec::FileType file_type,
38121dfcd9dSEnrico Granata  const FileSpec &file_spec
38221dfcd9dSEnrico Granata  )
38321dfcd9dSEnrico Granata {
38421dfcd9dSEnrico Granata     Error error;
38521dfcd9dSEnrico Granata 
38621dfcd9dSEnrico Granata     static ConstString g_dylibext("dylib");
38721dfcd9dSEnrico Granata 
38821dfcd9dSEnrico Granata     if (!baton)
38921dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultQuit;
39021dfcd9dSEnrico Granata 
39121dfcd9dSEnrico Granata     Debugger *debugger = (Debugger*)baton;
39221dfcd9dSEnrico Granata 
39321dfcd9dSEnrico Granata     // If we have a regular file, a symbolic link or unknown file type, try
39421dfcd9dSEnrico Granata     // and process the file. We must handle unknown as sometimes the directory
39521dfcd9dSEnrico Granata     // enumeration might be enumerating a file system that doesn't have correct
39621dfcd9dSEnrico Granata     // file type information.
39721dfcd9dSEnrico Granata     if (file_type == FileSpec::eFileTypeRegular         ||
39821dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink    ||
39921dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeUnknown          )
40021dfcd9dSEnrico Granata     {
40121dfcd9dSEnrico Granata         FileSpec plugin_file_spec (file_spec);
40221dfcd9dSEnrico Granata         plugin_file_spec.ResolvePath ();
40321dfcd9dSEnrico Granata 
40421dfcd9dSEnrico Granata         if (plugin_file_spec.GetFileNameExtension() != g_dylibext)
40521dfcd9dSEnrico Granata             return FileSpec::eEnumerateDirectoryResultNext;
40621dfcd9dSEnrico Granata 
407e743c782SEnrico Granata         Error plugin_load_error;
408e743c782SEnrico Granata         debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
40921dfcd9dSEnrico Granata 
41021dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultNext;
41121dfcd9dSEnrico Granata     }
41221dfcd9dSEnrico Granata 
41321dfcd9dSEnrico Granata     else if (file_type == FileSpec::eFileTypeUnknown     ||
41421dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeDirectory   ||
41521dfcd9dSEnrico Granata         file_type == FileSpec::eFileTypeSymbolicLink )
41621dfcd9dSEnrico Granata     {
41721dfcd9dSEnrico Granata         // Try and recurse into anything that a directory or symbolic link.
41821dfcd9dSEnrico Granata         // We must also do this for unknown as sometimes the directory enumeration
41921dfcd9dSEnrico Granata         // might be enurating a file system that doesn't have correct file type
42021dfcd9dSEnrico Granata         // information.
42121dfcd9dSEnrico Granata         return FileSpec::eEnumerateDirectoryResultEnter;
42221dfcd9dSEnrico Granata     }
42321dfcd9dSEnrico Granata 
42421dfcd9dSEnrico Granata     return FileSpec::eEnumerateDirectoryResultNext;
42521dfcd9dSEnrico Granata }
42621dfcd9dSEnrico Granata 
42721dfcd9dSEnrico Granata void
42821dfcd9dSEnrico Granata Debugger::InstanceInitialize ()
42921dfcd9dSEnrico Granata {
43021dfcd9dSEnrico Granata     FileSpec dir_spec;
43121dfcd9dSEnrico Granata     const bool find_directories = true;
43221dfcd9dSEnrico Granata     const bool find_files = true;
43321dfcd9dSEnrico Granata     const bool find_other = true;
43421dfcd9dSEnrico Granata     char dir_path[PATH_MAX];
43521dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
43621dfcd9dSEnrico Granata     {
43721dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
43821dfcd9dSEnrico Granata         {
43921dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
44021dfcd9dSEnrico Granata                                           find_directories,
44121dfcd9dSEnrico Granata                                           find_files,
44221dfcd9dSEnrico Granata                                           find_other,
44321dfcd9dSEnrico Granata                                           LoadPluginCallback,
44421dfcd9dSEnrico Granata                                           this);
44521dfcd9dSEnrico Granata         }
44621dfcd9dSEnrico Granata     }
44721dfcd9dSEnrico Granata 
44821dfcd9dSEnrico Granata     if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
44921dfcd9dSEnrico Granata     {
45021dfcd9dSEnrico Granata         if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
45121dfcd9dSEnrico Granata         {
45221dfcd9dSEnrico Granata             FileSpec::EnumerateDirectory (dir_path,
45321dfcd9dSEnrico Granata                                           find_directories,
45421dfcd9dSEnrico Granata                                           find_files,
45521dfcd9dSEnrico Granata                                           find_other,
45621dfcd9dSEnrico Granata                                           LoadPluginCallback,
45721dfcd9dSEnrico Granata                                           this);
45821dfcd9dSEnrico Granata         }
45921dfcd9dSEnrico Granata     }
460e8cd0c98SGreg Clayton 
461e8cd0c98SGreg Clayton     PluginManager::DebuggerInitialize (*this);
46221dfcd9dSEnrico Granata }
46321dfcd9dSEnrico Granata 
4646611103cSGreg Clayton DebuggerSP
465228063cdSJim Ingham Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
4666611103cSGreg Clayton {
467228063cdSJim Ingham     DebuggerSP debugger_sp (new Debugger(log_callback, baton));
468c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
4696611103cSGreg Clayton     {
4706611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
4716611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
4726611103cSGreg Clayton     }
47321dfcd9dSEnrico Granata     debugger_sp->InstanceInitialize ();
4746611103cSGreg Clayton     return debugger_sp;
4756611103cSGreg Clayton }
4766611103cSGreg Clayton 
477e02657b1SCaroline Tice void
4784d122c40SGreg Clayton Debugger::Destroy (DebuggerSP &debugger_sp)
479e02657b1SCaroline Tice {
480e02657b1SCaroline Tice     if (debugger_sp.get() == NULL)
481e02657b1SCaroline Tice         return;
482e02657b1SCaroline Tice 
4838314c525SJim Ingham     debugger_sp->Clear();
4848314c525SJim Ingham 
485c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
486c15f55e2SGreg Clayton     {
487e02657b1SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
488e02657b1SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList ();
489e02657b1SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
490e02657b1SCaroline Tice         for (pos = debugger_list.begin (); pos != end; ++pos)
491e02657b1SCaroline Tice         {
492e02657b1SCaroline Tice             if ((*pos).get() == debugger_sp.get())
493e02657b1SCaroline Tice             {
494e02657b1SCaroline Tice                 debugger_list.erase (pos);
495e02657b1SCaroline Tice                 return;
496e02657b1SCaroline Tice             }
497e02657b1SCaroline Tice         }
498e02657b1SCaroline Tice     }
499c15f55e2SGreg Clayton }
500e02657b1SCaroline Tice 
5014d122c40SGreg Clayton DebuggerSP
5023df9a8dfSCaroline Tice Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
5033df9a8dfSCaroline Tice {
5044d122c40SGreg Clayton     DebuggerSP debugger_sp;
5056920b52bSGreg Clayton     if (g_shared_debugger_refcount > 0)
5066920b52bSGreg Clayton     {
5076920b52bSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5086920b52bSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5096920b52bSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5106920b52bSGreg Clayton 
5116920b52bSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5126920b52bSGreg Clayton         {
5136920b52bSGreg Clayton             if ((*pos).get()->m_instance_name == instance_name)
5146920b52bSGreg Clayton             {
5156920b52bSGreg Clayton                 debugger_sp = *pos;
5166920b52bSGreg Clayton                 break;
5176920b52bSGreg Clayton             }
5186920b52bSGreg Clayton         }
5196920b52bSGreg Clayton     }
5203df9a8dfSCaroline Tice     return debugger_sp;
5213df9a8dfSCaroline Tice }
5226611103cSGreg Clayton 
5236611103cSGreg Clayton TargetSP
5246611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
5256611103cSGreg Clayton {
5264d122c40SGreg Clayton     TargetSP target_sp;
527c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
528c15f55e2SGreg Clayton     {
5296611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
5306611103cSGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
5316611103cSGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
5326611103cSGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
5336611103cSGreg Clayton         {
5346611103cSGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
5356611103cSGreg Clayton             if (target_sp)
5366611103cSGreg Clayton                 break;
5376611103cSGreg Clayton         }
538c15f55e2SGreg Clayton     }
5396611103cSGreg Clayton     return target_sp;
5406611103cSGreg Clayton }
5416611103cSGreg Clayton 
542e4e45924SGreg Clayton TargetSP
543e4e45924SGreg Clayton Debugger::FindTargetWithProcess (Process *process)
544e4e45924SGreg Clayton {
545e4e45924SGreg Clayton     TargetSP target_sp;
546c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
547c15f55e2SGreg Clayton     {
548e4e45924SGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
549e4e45924SGreg Clayton         DebuggerList &debugger_list = GetDebuggerList();
550e4e45924SGreg Clayton         DebuggerList::iterator pos, end = debugger_list.end();
551e4e45924SGreg Clayton         for (pos = debugger_list.begin(); pos != end; ++pos)
552e4e45924SGreg Clayton         {
553e4e45924SGreg Clayton             target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
554e4e45924SGreg Clayton             if (target_sp)
555e4e45924SGreg Clayton                 break;
556e4e45924SGreg Clayton         }
557c15f55e2SGreg Clayton     }
558e4e45924SGreg Clayton     return target_sp;
559e4e45924SGreg Clayton }
560e4e45924SGreg Clayton 
561228063cdSJim Ingham Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
562ebc1bb27SCaroline Tice     UserID (g_unique_id++),
56367cc0636SGreg Clayton     Properties(OptionValuePropertiesSP(new OptionValueProperties())),
564d46c87a1SGreg Clayton     m_input_comm("debugger.input"),
56530fdc8d8SChris Lattner     m_input_file (),
56630fdc8d8SChris Lattner     m_output_file (),
56730fdc8d8SChris Lattner     m_error_file (),
568c5917d9aSJim Ingham     m_terminal_state (),
5694bddaeb5SJim Ingham     m_target_list (*this),
570ded470d3SGreg Clayton     m_platform_list (),
57130fdc8d8SChris Lattner     m_listener ("lldb.Debugger"),
5729585fbfcSGreg Clayton     m_source_manager_ap(),
573e37d605eSJim Ingham     m_source_file_cache(),
5746611103cSGreg Clayton     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
575d5a0a01bSCaroline Tice     m_input_reader_stack (),
57667cc0636SGreg Clayton     m_input_reader_data (),
57767cc0636SGreg Clayton     m_instance_name()
57830fdc8d8SChris Lattner {
57967cc0636SGreg Clayton     char instance_cstr[256];
58067cc0636SGreg Clayton     snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
58167cc0636SGreg Clayton     m_instance_name.SetCString(instance_cstr);
582228063cdSJim Ingham     if (log_callback)
583228063cdSJim Ingham         m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
5846611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
585ded470d3SGreg Clayton     // Always add our default platform to the platform list
586ded470d3SGreg Clayton     PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
587ded470d3SGreg Clayton     assert (default_platform_sp.get());
588ded470d3SGreg Clayton     m_platform_list.Append (default_platform_sp, true);
58967cc0636SGreg Clayton 
590754a9369SGreg Clayton     m_collection_sp->Initialize (g_properties);
59167cc0636SGreg Clayton     m_collection_sp->AppendProperty (ConstString("target"),
59267cc0636SGreg Clayton                                      ConstString("Settings specify to debugging targets."),
59367cc0636SGreg Clayton                                      true,
59467cc0636SGreg Clayton                                      Target::GetGlobalProperties()->GetValueProperties());
595754a9369SGreg Clayton     if (m_command_interpreter_ap.get())
596754a9369SGreg Clayton     {
597754a9369SGreg Clayton         m_collection_sp->AppendProperty (ConstString("interpreter"),
598754a9369SGreg Clayton                                          ConstString("Settings specify to the debugger's command interpreter."),
599754a9369SGreg Clayton                                          true,
600754a9369SGreg Clayton                                          m_command_interpreter_ap->GetValueProperties());
601754a9369SGreg Clayton     }
60267cc0636SGreg Clayton     OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64 (NULL, ePropertyTerminalWidth);
60367cc0636SGreg Clayton     term_width->SetMinimumValue(10);
60467cc0636SGreg Clayton     term_width->SetMaximumValue(1024);
60530fdc8d8SChris Lattner }
60630fdc8d8SChris Lattner 
60730fdc8d8SChris Lattner Debugger::~Debugger ()
60830fdc8d8SChris Lattner {
6098314c525SJim Ingham     Clear();
6108314c525SJim Ingham }
6118314c525SJim Ingham 
6128314c525SJim Ingham void
6138314c525SJim Ingham Debugger::Clear()
6148314c525SJim Ingham {
6153d6086f6SCaroline Tice     CleanUpInputReaders();
6161ed54f50SGreg Clayton     m_listener.Clear();
6176611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
6186611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
6196611103cSGreg Clayton     {
620ccbc08e6SGreg Clayton         TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
621ccbc08e6SGreg Clayton         if (target_sp)
622ccbc08e6SGreg Clayton         {
623ccbc08e6SGreg Clayton             ProcessSP process_sp (target_sp->GetProcessSP());
6246611103cSGreg Clayton             if (process_sp)
6251fd07059SJim Ingham                 process_sp->Finalize();
626ccbc08e6SGreg Clayton             target_sp->Destroy();
6276611103cSGreg Clayton         }
62830fdc8d8SChris Lattner     }
6294bddaeb5SJim Ingham     BroadcasterManager::Clear ();
63030fdc8d8SChris Lattner 
6310d69a3a4SGreg Clayton     // Close the input file _before_ we close the input read communications class
6320d69a3a4SGreg Clayton     // as it does NOT own the input file, our m_input_file does.
633c5917d9aSJim Ingham     m_terminal_state.Clear();
6340d69a3a4SGreg Clayton     GetInputFile().Close ();
6350d69a3a4SGreg Clayton     // Now that we have closed m_input_file, we can now tell our input communication
6360d69a3a4SGreg Clayton     // class to close down. Its read thread should quickly exit after we close
6370d69a3a4SGreg Clayton     // the input file handle above.
6380d69a3a4SGreg Clayton     m_input_comm.Clear ();
6398314c525SJim Ingham }
64030fdc8d8SChris Lattner 
64130fdc8d8SChris Lattner bool
642fc3f027dSGreg Clayton Debugger::GetCloseInputOnEOF () const
643fc3f027dSGreg Clayton {
644fc3f027dSGreg Clayton     return m_input_comm.GetCloseOnEOF();
645fc3f027dSGreg Clayton }
646fc3f027dSGreg Clayton 
647fc3f027dSGreg Clayton void
648fc3f027dSGreg Clayton Debugger::SetCloseInputOnEOF (bool b)
649fc3f027dSGreg Clayton {
650fc3f027dSGreg Clayton     m_input_comm.SetCloseOnEOF(b);
651fc3f027dSGreg Clayton }
652fc3f027dSGreg Clayton 
653fc3f027dSGreg Clayton bool
65430fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
65530fdc8d8SChris Lattner {
6566611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
65730fdc8d8SChris Lattner }
65830fdc8d8SChris Lattner 
65930fdc8d8SChris Lattner void
66030fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
66130fdc8d8SChris Lattner {
6626611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
66330fdc8d8SChris Lattner }
66430fdc8d8SChris Lattner 
66530fdc8d8SChris Lattner 
66630fdc8d8SChris Lattner void
66730fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
66830fdc8d8SChris Lattner {
66951b1e2d2SGreg Clayton     File &in_file = GetInputFile();
67051b1e2d2SGreg Clayton     in_file.SetStream (fh, tranfer_ownership);
67151b1e2d2SGreg Clayton     if (in_file.IsValid() == false)
67251b1e2d2SGreg Clayton         in_file.SetStream (stdin, true);
67330fdc8d8SChris Lattner 
67430fdc8d8SChris Lattner     // Disconnect from any old connection if we had one
67530fdc8d8SChris Lattner     m_input_comm.Disconnect ();
67632720b51SGreg Clayton     // Pass false as the second argument to ConnectionFileDescriptor below because
67732720b51SGreg Clayton     // our "in_file" above will already take ownership if requested and we don't
67832720b51SGreg Clayton     // want to objects trying to own and close a file descriptor.
67932720b51SGreg Clayton     m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false));
68030fdc8d8SChris Lattner     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
68130fdc8d8SChris Lattner 
682c5917d9aSJim Ingham     // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
683c5917d9aSJim Ingham     SaveInputTerminalState ();
684c5917d9aSJim Ingham 
68530fdc8d8SChris Lattner     Error error;
68630fdc8d8SChris Lattner     if (m_input_comm.StartReadThread (&error) == false)
68730fdc8d8SChris Lattner     {
68851b1e2d2SGreg Clayton         File &err_file = GetErrorFile();
68951b1e2d2SGreg Clayton 
69051b1e2d2SGreg Clayton         err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
69130fdc8d8SChris Lattner         exit(1);
69230fdc8d8SChris Lattner     }
69330fdc8d8SChris Lattner }
69430fdc8d8SChris Lattner 
69530fdc8d8SChris Lattner void
69630fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
69730fdc8d8SChris Lattner {
69851b1e2d2SGreg Clayton     File &out_file = GetOutputFile();
69951b1e2d2SGreg Clayton     out_file.SetStream (fh, tranfer_ownership);
70051b1e2d2SGreg Clayton     if (out_file.IsValid() == false)
70151b1e2d2SGreg Clayton         out_file.SetStream (stdout, false);
7022f88aadfSCaroline Tice 
703b588726eSEnrico Granata     // do not create the ScriptInterpreter just for setting the output file handle
704b588726eSEnrico Granata     // as the constructor will know how to do the right thing on its own
705b588726eSEnrico Granata     const bool can_create = false;
706b588726eSEnrico Granata     ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
707b588726eSEnrico Granata     if (script_interpreter)
708b588726eSEnrico Granata         script_interpreter->ResetOutputFileHandle (fh);
70930fdc8d8SChris Lattner }
71030fdc8d8SChris Lattner 
71130fdc8d8SChris Lattner void
71230fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
71330fdc8d8SChris Lattner {
71451b1e2d2SGreg Clayton     File &err_file = GetErrorFile();
71551b1e2d2SGreg Clayton     err_file.SetStream (fh, tranfer_ownership);
71651b1e2d2SGreg Clayton     if (err_file.IsValid() == false)
71751b1e2d2SGreg Clayton         err_file.SetStream (stderr, false);
71830fdc8d8SChris Lattner }
71930fdc8d8SChris Lattner 
720c5917d9aSJim Ingham void
721c5917d9aSJim Ingham Debugger::SaveInputTerminalState ()
722c5917d9aSJim Ingham {
723c5917d9aSJim Ingham     File &in_file = GetInputFile();
724c5917d9aSJim Ingham     if (in_file.GetDescriptor() != File::kInvalidDescriptor)
725c5917d9aSJim Ingham         m_terminal_state.Save(in_file.GetDescriptor(), true);
726c5917d9aSJim Ingham }
727c5917d9aSJim Ingham 
728c5917d9aSJim Ingham void
729c5917d9aSJim Ingham Debugger::RestoreInputTerminalState ()
730c5917d9aSJim Ingham {
731c5917d9aSJim Ingham     m_terminal_state.Restore();
732c5917d9aSJim Ingham }
733c5917d9aSJim Ingham 
73430fdc8d8SChris Lattner ExecutionContext
7352976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
73630fdc8d8SChris Lattner {
73730fdc8d8SChris Lattner     ExecutionContext exe_ctx;
738c14ee32dSGreg Clayton     TargetSP target_sp(GetSelectedTarget());
739c14ee32dSGreg Clayton     exe_ctx.SetTargetSP (target_sp);
74030fdc8d8SChris Lattner 
74130fdc8d8SChris Lattner     if (target_sp)
74230fdc8d8SChris Lattner     {
743c14ee32dSGreg Clayton         ProcessSP process_sp (target_sp->GetProcessSP());
744c14ee32dSGreg Clayton         exe_ctx.SetProcessSP (process_sp);
745c14ee32dSGreg Clayton         if (process_sp && process_sp->IsRunning() == false)
74630fdc8d8SChris Lattner         {
747c14ee32dSGreg Clayton             ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
748c14ee32dSGreg Clayton             if (thread_sp)
74930fdc8d8SChris Lattner             {
750c14ee32dSGreg Clayton                 exe_ctx.SetThreadSP (thread_sp);
751c14ee32dSGreg Clayton                 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
752c14ee32dSGreg Clayton                 if (exe_ctx.GetFramePtr() == NULL)
753c14ee32dSGreg Clayton                     exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
75430fdc8d8SChris Lattner             }
75530fdc8d8SChris Lattner         }
75630fdc8d8SChris Lattner     }
75730fdc8d8SChris Lattner     return exe_ctx;
75830fdc8d8SChris Lattner 
75930fdc8d8SChris Lattner }
76030fdc8d8SChris Lattner 
761b44880caSCaroline Tice InputReaderSP
762b44880caSCaroline Tice Debugger::GetCurrentInputReader ()
763b44880caSCaroline Tice {
764b44880caSCaroline Tice     InputReaderSP reader_sp;
765b44880caSCaroline Tice 
766d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
767b44880caSCaroline Tice     {
768b44880caSCaroline Tice         // Clear any finished readers from the stack
769b44880caSCaroline Tice         while (CheckIfTopInputReaderIsDone()) ;
770b44880caSCaroline Tice 
771d5a0a01bSCaroline Tice         if (!m_input_reader_stack.IsEmpty())
772d5a0a01bSCaroline Tice             reader_sp = m_input_reader_stack.Top();
773b44880caSCaroline Tice     }
774b44880caSCaroline Tice 
775b44880caSCaroline Tice     return reader_sp;
776b44880caSCaroline Tice }
777b44880caSCaroline Tice 
77830fdc8d8SChris Lattner void
77930fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
78030fdc8d8SChris Lattner {
781efed6131SCaroline Tice     if (bytes_len > 0)
78230fdc8d8SChris Lattner         ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
783efed6131SCaroline Tice     else
784efed6131SCaroline Tice         ((Debugger *)baton)->DispatchInputEndOfFile ();
78530fdc8d8SChris Lattner }
78630fdc8d8SChris Lattner 
78730fdc8d8SChris Lattner 
78830fdc8d8SChris Lattner void
78930fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len)
79030fdc8d8SChris Lattner {
791efed6131SCaroline Tice     if (bytes == NULL || bytes_len == 0)
792efed6131SCaroline Tice         return;
79330fdc8d8SChris Lattner 
79430fdc8d8SChris Lattner     WriteToDefaultReader (bytes, bytes_len);
79530fdc8d8SChris Lattner }
79630fdc8d8SChris Lattner 
79730fdc8d8SChris Lattner void
798efed6131SCaroline Tice Debugger::DispatchInputInterrupt ()
799efed6131SCaroline Tice {
800efed6131SCaroline Tice     m_input_reader_data.clear();
801efed6131SCaroline Tice 
802b44880caSCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader ());
803efed6131SCaroline Tice     if (reader_sp)
804b44880caSCaroline Tice     {
805efed6131SCaroline Tice         reader_sp->Notify (eInputReaderInterrupt);
806efed6131SCaroline Tice 
807b44880caSCaroline Tice         // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
808efed6131SCaroline Tice         while (CheckIfTopInputReaderIsDone ()) ;
809efed6131SCaroline Tice     }
810efed6131SCaroline Tice }
811efed6131SCaroline Tice 
812efed6131SCaroline Tice void
813efed6131SCaroline Tice Debugger::DispatchInputEndOfFile ()
814efed6131SCaroline Tice {
815efed6131SCaroline Tice     m_input_reader_data.clear();
816efed6131SCaroline Tice 
817b44880caSCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader ());
818efed6131SCaroline Tice     if (reader_sp)
819b44880caSCaroline Tice     {
820efed6131SCaroline Tice         reader_sp->Notify (eInputReaderEndOfFile);
821efed6131SCaroline Tice 
822b44880caSCaroline Tice         // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
823efed6131SCaroline Tice         while (CheckIfTopInputReaderIsDone ()) ;
824efed6131SCaroline Tice     }
825efed6131SCaroline Tice }
826efed6131SCaroline Tice 
827efed6131SCaroline Tice void
8283d6086f6SCaroline Tice Debugger::CleanUpInputReaders ()
8293d6086f6SCaroline Tice {
8303d6086f6SCaroline Tice     m_input_reader_data.clear();
8313d6086f6SCaroline Tice 
832b44880caSCaroline Tice     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
833d5a0a01bSCaroline Tice     while (m_input_reader_stack.GetSize() > 1)
8343d6086f6SCaroline Tice     {
835b44880caSCaroline Tice         InputReaderSP reader_sp (GetCurrentInputReader ());
8363d6086f6SCaroline Tice         if (reader_sp)
8373d6086f6SCaroline Tice         {
8383d6086f6SCaroline Tice             reader_sp->Notify (eInputReaderEndOfFile);
8393d6086f6SCaroline Tice             reader_sp->SetIsDone (true);
8403d6086f6SCaroline Tice         }
8413d6086f6SCaroline Tice     }
8423d6086f6SCaroline Tice }
8433d6086f6SCaroline Tice 
8443d6086f6SCaroline Tice void
845969ed3d1SCaroline Tice Debugger::NotifyTopInputReader (InputReaderAction notification)
846969ed3d1SCaroline Tice {
847969ed3d1SCaroline Tice     InputReaderSP reader_sp (GetCurrentInputReader());
848969ed3d1SCaroline Tice     if (reader_sp)
849969ed3d1SCaroline Tice 	{
850969ed3d1SCaroline Tice         reader_sp->Notify (notification);
851969ed3d1SCaroline Tice 
852969ed3d1SCaroline Tice         // Flush out any input readers that are done.
853969ed3d1SCaroline Tice         while (CheckIfTopInputReaderIsDone ())
854969ed3d1SCaroline Tice             /* Do nothing. */;
855969ed3d1SCaroline Tice     }
856969ed3d1SCaroline Tice }
857969ed3d1SCaroline Tice 
8589088b068SCaroline Tice bool
8594d122c40SGreg Clayton Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp)
8609088b068SCaroline Tice {
8619088b068SCaroline Tice     InputReaderSP top_reader_sp (GetCurrentInputReader());
8629088b068SCaroline Tice 
863d61c10bcSCaroline Tice     return (reader_sp.get() == top_reader_sp.get());
8649088b068SCaroline Tice }
8659088b068SCaroline Tice 
8669088b068SCaroline Tice 
867969ed3d1SCaroline Tice void
86830fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
86930fdc8d8SChris Lattner {
87030fdc8d8SChris Lattner     if (bytes && bytes_len)
87130fdc8d8SChris Lattner         m_input_reader_data.append (bytes, bytes_len);
87230fdc8d8SChris Lattner 
87330fdc8d8SChris Lattner     if (m_input_reader_data.empty())
87430fdc8d8SChris Lattner         return;
87530fdc8d8SChris Lattner 
876d5a0a01bSCaroline Tice     while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
87730fdc8d8SChris Lattner     {
87830fdc8d8SChris Lattner         // Get the input reader from the top of the stack
879b44880caSCaroline Tice         InputReaderSP reader_sp (GetCurrentInputReader ());
88030fdc8d8SChris Lattner         if (!reader_sp)
88130fdc8d8SChris Lattner             break;
88230fdc8d8SChris Lattner 
883471b31ceSGreg Clayton         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
88430fdc8d8SChris Lattner                                                           m_input_reader_data.size());
88530fdc8d8SChris Lattner         if (bytes_handled)
88630fdc8d8SChris Lattner         {
88730fdc8d8SChris Lattner             m_input_reader_data.erase (0, bytes_handled);
88830fdc8d8SChris Lattner         }
88930fdc8d8SChris Lattner         else
89030fdc8d8SChris Lattner         {
89130fdc8d8SChris Lattner             // No bytes were handled, we might not have reached our
89230fdc8d8SChris Lattner             // granularity, just return and wait for more data
89330fdc8d8SChris Lattner             break;
89430fdc8d8SChris Lattner         }
89530fdc8d8SChris Lattner     }
89630fdc8d8SChris Lattner 
897b44880caSCaroline Tice     // Flush out any input readers that are done.
89830fdc8d8SChris Lattner     while (CheckIfTopInputReaderIsDone ())
89930fdc8d8SChris Lattner         /* Do nothing. */;
90030fdc8d8SChris Lattner 
90130fdc8d8SChris Lattner }
90230fdc8d8SChris Lattner 
90330fdc8d8SChris Lattner void
90430fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp)
90530fdc8d8SChris Lattner {
90630fdc8d8SChris Lattner     if (!reader_sp)
90730fdc8d8SChris Lattner         return;
908b44880caSCaroline Tice 
90930fdc8d8SChris Lattner     // Deactivate the old top reader
910b44880caSCaroline Tice     InputReaderSP top_reader_sp (GetCurrentInputReader ());
911b44880caSCaroline Tice 
91230fdc8d8SChris Lattner     if (top_reader_sp)
91330fdc8d8SChris Lattner         top_reader_sp->Notify (eInputReaderDeactivate);
914b44880caSCaroline Tice 
915d5a0a01bSCaroline Tice     m_input_reader_stack.Push (reader_sp);
91630fdc8d8SChris Lattner     reader_sp->Notify (eInputReaderActivate);
91730fdc8d8SChris Lattner     ActivateInputReader (reader_sp);
91830fdc8d8SChris Lattner }
91930fdc8d8SChris Lattner 
92030fdc8d8SChris Lattner bool
9214d122c40SGreg Clayton Debugger::PopInputReader (const InputReaderSP& pop_reader_sp)
92230fdc8d8SChris Lattner {
92330fdc8d8SChris Lattner     bool result = false;
92430fdc8d8SChris Lattner 
92530fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
92630fdc8d8SChris Lattner     // read on the stack referesh its prompt and if there is one...
927d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
92830fdc8d8SChris Lattner     {
929b44880caSCaroline Tice         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
930d5a0a01bSCaroline Tice         InputReaderSP reader_sp(m_input_reader_stack.Top());
93130fdc8d8SChris Lattner 
93230fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
93330fdc8d8SChris Lattner         {
934d5a0a01bSCaroline Tice             m_input_reader_stack.Pop ();
93530fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDeactivate);
93630fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDone);
93730fdc8d8SChris Lattner             result = true;
93830fdc8d8SChris Lattner 
939d5a0a01bSCaroline Tice             if (!m_input_reader_stack.IsEmpty())
94030fdc8d8SChris Lattner             {
941d5a0a01bSCaroline Tice                 reader_sp = m_input_reader_stack.Top();
94230fdc8d8SChris Lattner                 if (reader_sp)
94330fdc8d8SChris Lattner                 {
94430fdc8d8SChris Lattner                     ActivateInputReader (reader_sp);
94530fdc8d8SChris Lattner                     reader_sp->Notify (eInputReaderReactivate);
94630fdc8d8SChris Lattner                 }
94730fdc8d8SChris Lattner             }
94830fdc8d8SChris Lattner         }
94930fdc8d8SChris Lattner     }
95030fdc8d8SChris Lattner     return result;
95130fdc8d8SChris Lattner }
95230fdc8d8SChris Lattner 
95330fdc8d8SChris Lattner bool
95430fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone ()
95530fdc8d8SChris Lattner {
95630fdc8d8SChris Lattner     bool result = false;
957d5a0a01bSCaroline Tice     if (!m_input_reader_stack.IsEmpty())
95830fdc8d8SChris Lattner     {
959b44880caSCaroline Tice         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
960d5a0a01bSCaroline Tice         InputReaderSP reader_sp(m_input_reader_stack.Top());
96130fdc8d8SChris Lattner 
96230fdc8d8SChris Lattner         if (reader_sp && reader_sp->IsDone())
96330fdc8d8SChris Lattner         {
96430fdc8d8SChris Lattner             result = true;
96530fdc8d8SChris Lattner             PopInputReader (reader_sp);
96630fdc8d8SChris Lattner         }
96730fdc8d8SChris Lattner     }
96830fdc8d8SChris Lattner     return result;
96930fdc8d8SChris Lattner }
97030fdc8d8SChris Lattner 
97130fdc8d8SChris Lattner void
97230fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
97330fdc8d8SChris Lattner {
97451b1e2d2SGreg Clayton     int input_fd = m_input_file.GetFile().GetDescriptor();
97530fdc8d8SChris Lattner 
97651b1e2d2SGreg Clayton     if (input_fd >= 0)
97730fdc8d8SChris Lattner     {
97851b1e2d2SGreg Clayton         Terminal tty(input_fd);
979a3406614SGreg Clayton 
980a3406614SGreg Clayton         tty.SetEcho(reader_sp->GetEcho());
98130fdc8d8SChris Lattner 
98230fdc8d8SChris Lattner         switch (reader_sp->GetGranularity())
98330fdc8d8SChris Lattner         {
98430fdc8d8SChris Lattner         case eInputReaderGranularityByte:
98530fdc8d8SChris Lattner         case eInputReaderGranularityWord:
986a3406614SGreg Clayton             tty.SetCanonical (false);
98730fdc8d8SChris Lattner             break;
98830fdc8d8SChris Lattner 
98930fdc8d8SChris Lattner         case eInputReaderGranularityLine:
99030fdc8d8SChris Lattner         case eInputReaderGranularityAll:
991a3406614SGreg Clayton             tty.SetCanonical (true);
99230fdc8d8SChris Lattner             break;
99330fdc8d8SChris Lattner 
99430fdc8d8SChris Lattner         default:
99530fdc8d8SChris Lattner             break;
99630fdc8d8SChris Lattner         }
99730fdc8d8SChris Lattner     }
99830fdc8d8SChris Lattner }
9996611103cSGreg Clayton 
10005b52f0c7SJim Ingham StreamSP
10015b52f0c7SJim Ingham Debugger::GetAsyncOutputStream ()
10025b52f0c7SJim Ingham {
10035b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10045b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousOutputData));
10055b52f0c7SJim Ingham }
10065b52f0c7SJim Ingham 
10075b52f0c7SJim Ingham StreamSP
10085b52f0c7SJim Ingham Debugger::GetAsyncErrorStream ()
10095b52f0c7SJim Ingham {
10105b52f0c7SJim Ingham     return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
10115b52f0c7SJim Ingham                                                CommandInterpreter::eBroadcastBitAsynchronousErrorData));
10125b52f0c7SJim Ingham }
10135b52f0c7SJim Ingham 
1014c7bece56SGreg Clayton size_t
1015061858ceSEnrico Granata Debugger::GetNumDebuggers()
1016061858ceSEnrico Granata {
1017c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1018c15f55e2SGreg Clayton     {
1019061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1020061858ceSEnrico Granata         return GetDebuggerList().size();
1021061858ceSEnrico Granata     }
1022c15f55e2SGreg Clayton     return 0;
1023c15f55e2SGreg Clayton }
1024061858ceSEnrico Granata 
1025061858ceSEnrico Granata lldb::DebuggerSP
1026c7bece56SGreg Clayton Debugger::GetDebuggerAtIndex (size_t index)
1027061858ceSEnrico Granata {
1028061858ceSEnrico Granata     DebuggerSP debugger_sp;
1029061858ceSEnrico Granata 
1030c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1031c15f55e2SGreg Clayton     {
1032061858ceSEnrico Granata         Mutex::Locker locker (GetDebuggerListMutex ());
1033061858ceSEnrico Granata         DebuggerList &debugger_list = GetDebuggerList();
1034061858ceSEnrico Granata 
1035061858ceSEnrico Granata         if (index < debugger_list.size())
1036061858ceSEnrico Granata             debugger_sp = debugger_list[index];
1037c15f55e2SGreg Clayton     }
1038061858ceSEnrico Granata 
1039061858ceSEnrico Granata     return debugger_sp;
1040061858ceSEnrico Granata }
1041061858ceSEnrico Granata 
1042ebc1bb27SCaroline Tice DebuggerSP
1043ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
1044ebc1bb27SCaroline Tice {
10454d122c40SGreg Clayton     DebuggerSP debugger_sp;
1046ebc1bb27SCaroline Tice 
1047c15f55e2SGreg Clayton     if (g_shared_debugger_refcount > 0)
1048c15f55e2SGreg Clayton     {
1049ebc1bb27SCaroline Tice         Mutex::Locker locker (GetDebuggerListMutex ());
1050ebc1bb27SCaroline Tice         DebuggerList &debugger_list = GetDebuggerList();
1051ebc1bb27SCaroline Tice         DebuggerList::iterator pos, end = debugger_list.end();
1052ebc1bb27SCaroline Tice         for (pos = debugger_list.begin(); pos != end; ++pos)
1053ebc1bb27SCaroline Tice         {
1054ebc1bb27SCaroline Tice             if ((*pos).get()->GetID() == id)
1055ebc1bb27SCaroline Tice             {
1056ebc1bb27SCaroline Tice                 debugger_sp = *pos;
1057ebc1bb27SCaroline Tice                 break;
1058ebc1bb27SCaroline Tice             }
1059ebc1bb27SCaroline Tice         }
1060c15f55e2SGreg Clayton     }
1061ebc1bb27SCaroline Tice     return debugger_sp;
1062ebc1bb27SCaroline Tice }
10633df9a8dfSCaroline Tice 
10641b654882SGreg Clayton static void
10651b654882SGreg Clayton TestPromptFormats (StackFrame *frame)
10661b654882SGreg Clayton {
10671b654882SGreg Clayton     if (frame == NULL)
10681b654882SGreg Clayton         return;
10691b654882SGreg Clayton 
10701b654882SGreg Clayton     StreamString s;
10711b654882SGreg Clayton     const char *prompt_format =
10721b654882SGreg Clayton     "{addr = '${addr}'\n}"
10731b654882SGreg Clayton     "{process.id = '${process.id}'\n}"
10741b654882SGreg Clayton     "{process.name = '${process.name}'\n}"
10751b654882SGreg Clayton     "{process.file.basename = '${process.file.basename}'\n}"
10761b654882SGreg Clayton     "{process.file.fullpath = '${process.file.fullpath}'\n}"
10771b654882SGreg Clayton     "{thread.id = '${thread.id}'\n}"
10781b654882SGreg Clayton     "{thread.index = '${thread.index}'\n}"
10791b654882SGreg Clayton     "{thread.name = '${thread.name}'\n}"
10801b654882SGreg Clayton     "{thread.queue = '${thread.queue}'\n}"
10811b654882SGreg Clayton     "{thread.stop-reason = '${thread.stop-reason}'\n}"
10821b654882SGreg Clayton     "{target.arch = '${target.arch}'\n}"
10831b654882SGreg Clayton     "{module.file.basename = '${module.file.basename}'\n}"
10841b654882SGreg Clayton     "{module.file.fullpath = '${module.file.fullpath}'\n}"
10851b654882SGreg Clayton     "{file.basename = '${file.basename}'\n}"
10861b654882SGreg Clayton     "{file.fullpath = '${file.fullpath}'\n}"
10871b654882SGreg Clayton     "{frame.index = '${frame.index}'\n}"
10881b654882SGreg Clayton     "{frame.pc = '${frame.pc}'\n}"
10891b654882SGreg Clayton     "{frame.sp = '${frame.sp}'\n}"
10901b654882SGreg Clayton     "{frame.fp = '${frame.fp}'\n}"
10911b654882SGreg Clayton     "{frame.flags = '${frame.flags}'\n}"
10921b654882SGreg Clayton     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
10931b654882SGreg Clayton     "{frame.reg.rip = '${frame.reg.rip}'\n}"
10941b654882SGreg Clayton     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
10951b654882SGreg Clayton     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
10961b654882SGreg Clayton     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
10971b654882SGreg Clayton     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
10981b654882SGreg Clayton     "{frame.reg.carp = '${frame.reg.carp}'\n}"
10991b654882SGreg Clayton     "{function.id = '${function.id}'\n}"
11001b654882SGreg Clayton     "{function.name = '${function.name}'\n}"
1101ccbc08e6SGreg Clayton     "{function.name-with-args = '${function.name-with-args}'\n}"
11021b654882SGreg Clayton     "{function.addr-offset = '${function.addr-offset}'\n}"
11031b654882SGreg Clayton     "{function.line-offset = '${function.line-offset}'\n}"
11041b654882SGreg Clayton     "{function.pc-offset = '${function.pc-offset}'\n}"
11051b654882SGreg Clayton     "{line.file.basename = '${line.file.basename}'\n}"
11061b654882SGreg Clayton     "{line.file.fullpath = '${line.file.fullpath}'\n}"
11071b654882SGreg Clayton     "{line.number = '${line.number}'\n}"
11081b654882SGreg Clayton     "{line.start-addr = '${line.start-addr}'\n}"
11091b654882SGreg Clayton     "{line.end-addr = '${line.end-addr}'\n}"
11101b654882SGreg Clayton ;
11111b654882SGreg Clayton 
11121b654882SGreg Clayton     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
11131b654882SGreg Clayton     ExecutionContext exe_ctx;
11140603aa9dSGreg Clayton     frame->CalculateExecutionContext(exe_ctx);
11151b654882SGreg Clayton     const char *end = NULL;
11161b654882SGreg Clayton     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end))
11171b654882SGreg Clayton     {
11181b654882SGreg Clayton         printf("%s\n", s.GetData());
11191b654882SGreg Clayton     }
11201b654882SGreg Clayton     else
11211b654882SGreg Clayton     {
11221b654882SGreg Clayton         printf ("error: at '%s'\n", end);
11231b654882SGreg Clayton         printf ("what we got: %s\n", s.GetData());
11241b654882SGreg Clayton     }
11251b654882SGreg Clayton }
11261b654882SGreg Clayton 
11279fc1944eSEnrico Granata static bool
11289fc1944eSEnrico Granata ScanFormatDescriptor (const char* var_name_begin,
11299fc1944eSEnrico Granata                       const char* var_name_end,
11309fc1944eSEnrico Granata                       const char** var_name_final,
11319fc1944eSEnrico Granata                       const char** percent_position,
11324d122c40SGreg Clayton                       Format* custom_format,
11339fc1944eSEnrico Granata                       ValueObject::ValueObjectRepresentationStyle* val_obj_display)
11349fc1944eSEnrico Granata {
11355160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
11369fc1944eSEnrico Granata     *percent_position = ::strchr(var_name_begin,'%');
11379fc1944eSEnrico Granata     if (!*percent_position || *percent_position > var_name_end)
1138e992a089SEnrico Granata     {
1139e992a089SEnrico Granata         if (log)
1140d228483dSEnrico Granata             log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
11419fc1944eSEnrico Granata         *var_name_final = var_name_end;
1142e992a089SEnrico Granata     }
11439fc1944eSEnrico Granata     else
11449fc1944eSEnrico Granata     {
11459fc1944eSEnrico Granata         *var_name_final = *percent_position;
114636aa5ae6SEnrico Granata         std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
1147e992a089SEnrico Granata         if (log)
114836aa5ae6SEnrico Granata             log->Printf("ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
114936aa5ae6SEnrico Granata         if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
11509fc1944eSEnrico Granata                                                   true,
11519fc1944eSEnrico Granata                                                   *custom_format) )
11529fc1944eSEnrico Granata         {
1153e992a089SEnrico Granata             if (log)
115436aa5ae6SEnrico Granata                 log->Printf("ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
115536aa5ae6SEnrico Granata 
115636aa5ae6SEnrico Granata             switch (format_name.front())
115736aa5ae6SEnrico Granata             {
115836aa5ae6SEnrico Granata                 case '@':             // if this is an @ sign, print ObjC description
115986cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
116036aa5ae6SEnrico Granata                     break;
116136aa5ae6SEnrico Granata                 case 'V': // if this is a V, print the value using the default format
116286cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
116336aa5ae6SEnrico Granata                     break;
116436aa5ae6SEnrico Granata                 case 'L': // if this is an L, print the location of the value
116586cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
116636aa5ae6SEnrico Granata                     break;
116736aa5ae6SEnrico Granata                 case 'S': // if this is an S, print the summary after all
116886cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
116936aa5ae6SEnrico Granata                     break;
117036aa5ae6SEnrico Granata                 case '#': // if this is a '#', print the number of children
117186cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
117236aa5ae6SEnrico Granata                     break;
117336aa5ae6SEnrico Granata                 case 'T': // if this is a 'T', print the type
117486cc9829SEnrico Granata                     *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
117536aa5ae6SEnrico Granata                     break;
117636aa5ae6SEnrico Granata                 default:
1177*5c42d8a8SJim Ingham                     if (log)
117836aa5ae6SEnrico Granata                         log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
117936aa5ae6SEnrico Granata                     break;
118036aa5ae6SEnrico Granata             }
11819fc1944eSEnrico Granata         }
11829fc1944eSEnrico Granata         // a good custom format tells us to print the value using it
11839fc1944eSEnrico Granata         else
1184e992a089SEnrico Granata         {
1185e992a089SEnrico Granata             if (log)
1186d228483dSEnrico Granata                 log->Printf("ScanFormatDescriptor] will display value for this VO");
118786cc9829SEnrico Granata             *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1188e992a089SEnrico Granata         }
11899fc1944eSEnrico Granata     }
1190e992a089SEnrico Granata     if (log)
1191d228483dSEnrico Granata         log->Printf("ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
1192e992a089SEnrico Granata                     *custom_format,
1193e992a089SEnrico Granata                     *val_obj_display);
11949fc1944eSEnrico Granata     return true;
11959fc1944eSEnrico Granata }
11969fc1944eSEnrico Granata 
11979fc1944eSEnrico Granata static bool
11989fc1944eSEnrico Granata ScanBracketedRange (const char* var_name_begin,
11999fc1944eSEnrico Granata                     const char* var_name_end,
12009fc1944eSEnrico Granata                     const char* var_name_final,
12019fc1944eSEnrico Granata                     const char** open_bracket_position,
12029fc1944eSEnrico Granata                     const char** separator_position,
12039fc1944eSEnrico Granata                     const char** close_bracket_position,
12049fc1944eSEnrico Granata                     const char** var_name_final_if_array_range,
12059fc1944eSEnrico Granata                     int64_t* index_lower,
12069fc1944eSEnrico Granata                     int64_t* index_higher)
12079fc1944eSEnrico Granata {
12085160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
12099fc1944eSEnrico Granata     *open_bracket_position = ::strchr(var_name_begin,'[');
12109fc1944eSEnrico Granata     if (*open_bracket_position && *open_bracket_position < var_name_final)
12119fc1944eSEnrico Granata     {
12129fc1944eSEnrico Granata         *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
12139fc1944eSEnrico Granata         *close_bracket_position = ::strchr(*open_bracket_position,']');
12149fc1944eSEnrico Granata         // as usual, we assume that [] will come before %
12159fc1944eSEnrico Granata         //printf("trying to expand a []\n");
12169fc1944eSEnrico Granata         *var_name_final_if_array_range = *open_bracket_position;
12179fc1944eSEnrico Granata         if (*close_bracket_position - *open_bracket_position == 1)
12189fc1944eSEnrico Granata         {
1219e992a089SEnrico Granata             if (log)
1220d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
12219fc1944eSEnrico Granata             *index_lower = 0;
12229fc1944eSEnrico Granata         }
12239fc1944eSEnrico Granata         else if (*separator_position == NULL || *separator_position > var_name_end)
12249fc1944eSEnrico Granata         {
12259fc1944eSEnrico Granata             char *end = NULL;
12269fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12279fc1944eSEnrico Granata             *index_higher = *index_lower;
1228e992a089SEnrico Granata             if (log)
1229d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
12309fc1944eSEnrico Granata         }
12319fc1944eSEnrico Granata         else if (*close_bracket_position && *close_bracket_position < var_name_end)
12329fc1944eSEnrico Granata         {
12339fc1944eSEnrico Granata             char *end = NULL;
12349fc1944eSEnrico Granata             *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
12359fc1944eSEnrico Granata             *index_higher = ::strtoul (*separator_position+1, &end, 0);
1236e992a089SEnrico Granata             if (log)
1237d01b2953SDaniel Malea                 log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
12389fc1944eSEnrico Granata         }
12399fc1944eSEnrico Granata         else
1240e992a089SEnrico Granata         {
1241e992a089SEnrico Granata             if (log)
1242d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
12439fc1944eSEnrico Granata             return false;
1244e992a089SEnrico Granata         }
12459fc1944eSEnrico Granata         if (*index_lower > *index_higher && *index_higher > 0)
12469fc1944eSEnrico Granata         {
1247e992a089SEnrico Granata             if (log)
1248d228483dSEnrico Granata                 log->Printf("[ScanBracketedRange] swapping indices");
1249c7bece56SGreg Clayton             int64_t temp = *index_lower;
12509fc1944eSEnrico Granata             *index_lower = *index_higher;
12519fc1944eSEnrico Granata             *index_higher = temp;
12529fc1944eSEnrico Granata         }
12539fc1944eSEnrico Granata     }
1254e992a089SEnrico Granata     else if (log)
1255d228483dSEnrico Granata             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
12569fc1944eSEnrico Granata     return true;
12579fc1944eSEnrico Granata }
12589fc1944eSEnrico Granata 
12599fc1944eSEnrico Granata static ValueObjectSP
1260c482a192SEnrico Granata ExpandIndexedExpression (ValueObject* valobj,
1261c7bece56SGreg Clayton                          size_t index,
12629fc1944eSEnrico Granata                          StackFrame* frame,
1263fc7a7f3bSEnrico Granata                          bool deref_pointer)
12649fc1944eSEnrico Granata {
12655160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1266fc7a7f3bSEnrico Granata     const char* ptr_deref_format = "[%d]";
1267599171adSEnrico Granata     std::string ptr_deref_buffer(10,0);
1268599171adSEnrico Granata     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
1269e992a089SEnrico Granata     if (log)
1270599171adSEnrico Granata         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
1271fc7a7f3bSEnrico Granata     const char* first_unparsed;
1272fc7a7f3bSEnrico Granata     ValueObject::GetValueForExpressionPathOptions options;
1273fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathEndResultType final_value_type;
1274fc7a7f3bSEnrico Granata     ValueObject::ExpressionPathScanEndReason reason_to_stop;
127586cc9829SEnrico Granata     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1276599171adSEnrico Granata     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
1277fc7a7f3bSEnrico Granata                                                           &first_unparsed,
1278fc7a7f3bSEnrico Granata                                                           &reason_to_stop,
1279fc7a7f3bSEnrico Granata                                                           &final_value_type,
1280fc7a7f3bSEnrico Granata                                                           options,
1281fc7a7f3bSEnrico Granata                                                           &what_next);
1282fc7a7f3bSEnrico Granata     if (!item)
1283fc7a7f3bSEnrico Granata     {
1284e992a089SEnrico Granata         if (log)
1285d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
1286e992a089SEnrico Granata                " final_value_type %d",
1287fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
1288fc7a7f3bSEnrico Granata     }
12899fc1944eSEnrico Granata     else
12909fc1944eSEnrico Granata     {
1291e992a089SEnrico Granata         if (log)
1292d228483dSEnrico Granata             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1293e992a089SEnrico Granata                " final_value_type %d",
1294fc7a7f3bSEnrico Granata                first_unparsed, reason_to_stop, final_value_type);
12959fc1944eSEnrico Granata     }
12969fc1944eSEnrico Granata     return item;
12979fc1944eSEnrico Granata }
12989fc1944eSEnrico Granata 
12991b654882SGreg Clayton bool
13001b654882SGreg Clayton Debugger::FormatPrompt
13011b654882SGreg Clayton (
13021b654882SGreg Clayton     const char *format,
13031b654882SGreg Clayton     const SymbolContext *sc,
13041b654882SGreg Clayton     const ExecutionContext *exe_ctx,
13051b654882SGreg Clayton     const Address *addr,
13061b654882SGreg Clayton     Stream &s,
13074becb37eSEnrico Granata     const char **end,
1308c482a192SEnrico Granata     ValueObject* valobj
13091b654882SGreg Clayton )
13101b654882SGreg Clayton {
1311c482a192SEnrico Granata     ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
13121b654882SGreg Clayton     bool success = true;
13131b654882SGreg Clayton     const char *p;
13145160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
13151b654882SGreg Clayton     for (p = format; *p != '\0'; ++p)
13161b654882SGreg Clayton     {
1317c482a192SEnrico Granata         if (realvalobj)
13184becb37eSEnrico Granata         {
1319c482a192SEnrico Granata             valobj = realvalobj;
1320c482a192SEnrico Granata             realvalobj = NULL;
13214becb37eSEnrico Granata         }
13221b654882SGreg Clayton         size_t non_special_chars = ::strcspn (p, "${}\\");
13231b654882SGreg Clayton         if (non_special_chars > 0)
13241b654882SGreg Clayton         {
13251b654882SGreg Clayton             if (success)
13261b654882SGreg Clayton                 s.Write (p, non_special_chars);
13271b654882SGreg Clayton             p += non_special_chars;
13281b654882SGreg Clayton         }
13291b654882SGreg Clayton 
13301b654882SGreg Clayton         if (*p == '\0')
13311b654882SGreg Clayton         {
13321b654882SGreg Clayton             break;
13331b654882SGreg Clayton         }
13341b654882SGreg Clayton         else if (*p == '{')
13351b654882SGreg Clayton         {
13361b654882SGreg Clayton             // Start a new scope that must have everything it needs if it is to
13371b654882SGreg Clayton             // to make it into the final output stream "s". If you want to make
13381b654882SGreg Clayton             // a format that only prints out the function or symbol name if there
13391b654882SGreg Clayton             // is one in the symbol context you can use:
13401b654882SGreg Clayton             //      "{function =${function.name}}"
13411b654882SGreg Clayton             // The first '{' starts a new scope that end with the matching '}' at
13421b654882SGreg Clayton             // the end of the string. The contents "function =${function.name}"
13431b654882SGreg Clayton             // will then be evaluated and only be output if there is a function
13441b654882SGreg Clayton             // or symbol with a valid name.
13451b654882SGreg Clayton             StreamString sub_strm;
13461b654882SGreg Clayton 
13471b654882SGreg Clayton             ++p;  // Skip the '{'
13481b654882SGreg Clayton 
1349c482a192SEnrico Granata             if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
13501b654882SGreg Clayton             {
13511b654882SGreg Clayton                 // The stream had all it needed
13521b654882SGreg Clayton                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
13531b654882SGreg Clayton             }
13541b654882SGreg Clayton             if (*p != '}')
13551b654882SGreg Clayton             {
13561b654882SGreg Clayton                 success = false;
13571b654882SGreg Clayton                 break;
13581b654882SGreg Clayton             }
13591b654882SGreg Clayton         }
13601b654882SGreg Clayton         else if (*p == '}')
13611b654882SGreg Clayton         {
13621b654882SGreg Clayton             // End of a enclosing scope
13631b654882SGreg Clayton             break;
13641b654882SGreg Clayton         }
13651b654882SGreg Clayton         else if (*p == '$')
13661b654882SGreg Clayton         {
13671b654882SGreg Clayton             // We have a prompt variable to print
13681b654882SGreg Clayton             ++p;
13691b654882SGreg Clayton             if (*p == '{')
13701b654882SGreg Clayton             {
13711b654882SGreg Clayton                 ++p;
13721b654882SGreg Clayton                 const char *var_name_begin = p;
13731b654882SGreg Clayton                 const char *var_name_end = ::strchr (p, '}');
13741b654882SGreg Clayton 
13751b654882SGreg Clayton                 if (var_name_end && var_name_begin < var_name_end)
13761b654882SGreg Clayton                 {
13771b654882SGreg Clayton                     // if we have already failed to parse, skip this variable
13781b654882SGreg Clayton                     if (success)
13791b654882SGreg Clayton                     {
13801b654882SGreg Clayton                         const char *cstr = NULL;
13811b654882SGreg Clayton                         Address format_addr;
13821b654882SGreg Clayton                         bool calculate_format_addr_function_offset = false;
13831b654882SGreg Clayton                         // Set reg_kind and reg_num to invalid values
13841b654882SGreg Clayton                         RegisterKind reg_kind = kNumRegisterKinds;
13851b654882SGreg Clayton                         uint32_t reg_num = LLDB_INVALID_REGNUM;
13861b654882SGreg Clayton                         FileSpec format_file_spec;
1387e0d378b3SGreg Clayton                         const RegisterInfo *reg_info = NULL;
13881b654882SGreg Clayton                         RegisterContext *reg_ctx = NULL;
13899fc1944eSEnrico Granata                         bool do_deref_pointer = false;
139086cc9829SEnrico Granata                         ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
139186cc9829SEnrico Granata                         ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
13921b654882SGreg Clayton 
13931b654882SGreg Clayton                         // Each variable must set success to true below...
13941b654882SGreg Clayton                         bool var_success = false;
13951b654882SGreg Clayton                         switch (var_name_begin[0])
13961b654882SGreg Clayton                         {
13974becb37eSEnrico Granata                         case '*':
13986f3533fbSEnrico Granata                         case 'v':
13996f3533fbSEnrico Granata                         case 's':
14004becb37eSEnrico Granata                             {
1401c482a192SEnrico Granata                                 if (!valobj)
140234132754SGreg Clayton                                     break;
14036f3533fbSEnrico Granata 
1404c3e320a7SEnrico Granata                                 if (log)
1405d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1406c3e320a7SEnrico Granata 
14076f3533fbSEnrico Granata                                 // check for *var and *svar
14086f3533fbSEnrico Granata                                 if (*var_name_begin == '*')
14096f3533fbSEnrico Granata                                 {
14109fc1944eSEnrico Granata                                     do_deref_pointer = true;
14119fc1944eSEnrico Granata                                     var_name_begin++;
14129fc1944eSEnrico Granata                                 }
1413c3e320a7SEnrico Granata 
1414c3e320a7SEnrico Granata                                 if (log)
1415d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1416c3e320a7SEnrico Granata 
14176f3533fbSEnrico Granata                                 if (*var_name_begin == 's')
14184becb37eSEnrico Granata                                 {
1419c5bc412cSEnrico Granata                                     if (!valobj->IsSynthetic())
142086cc9829SEnrico Granata                                         valobj = valobj->GetSyntheticValue().get();
142186cc9829SEnrico Granata                                     if (!valobj)
142286cc9829SEnrico Granata                                         break;
14236f3533fbSEnrico Granata                                     var_name_begin++;
14246f3533fbSEnrico Granata                                 }
14256f3533fbSEnrico Granata 
1426c3e320a7SEnrico Granata                                 if (log)
1427d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1428c3e320a7SEnrico Granata 
14296f3533fbSEnrico Granata                                 // should be a 'v' by now
14306f3533fbSEnrico Granata                                 if (*var_name_begin != 'v')
14316f3533fbSEnrico Granata                                     break;
14326f3533fbSEnrico Granata 
1433c3e320a7SEnrico Granata                                 if (log)
1434d228483dSEnrico Granata                                     log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
1435c3e320a7SEnrico Granata 
1436fc7a7f3bSEnrico Granata                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
143786cc9829SEnrico Granata                                                                                   ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
1438fc7a7f3bSEnrico Granata                                 ValueObject::GetValueForExpressionPathOptions options;
14398c9d3560SEnrico Granata                                 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
144086cc9829SEnrico Granata                                 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
144134132754SGreg Clayton                                 ValueObject* target = NULL;
14424d122c40SGreg Clayton                                 Format custom_format = eFormatInvalid;
144334132754SGreg Clayton                                 const char* var_name_final = NULL;
14449fc1944eSEnrico Granata                                 const char* var_name_final_if_array_range = NULL;
144534132754SGreg Clayton                                 const char* close_bracket_position = NULL;
144634132754SGreg Clayton                                 int64_t index_lower = -1;
144734132754SGreg Clayton                                 int64_t index_higher = -1;
14489fc1944eSEnrico Granata                                 bool is_array_range = false;
1449fc7a7f3bSEnrico Granata                                 const char* first_unparsed;
145085933ed4SEnrico Granata                                 bool was_plain_var = false;
145185933ed4SEnrico Granata                                 bool was_var_format = false;
1452a777dc2aSEnrico Granata                                 bool was_var_indexed = false;
1453fc7a7f3bSEnrico Granata 
1454c482a192SEnrico Granata                                 if (!valobj) break;
1455c482a192SEnrico Granata                                 // simplest case ${var}, just print valobj's value
14569fc1944eSEnrico Granata                                 if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0)
14570a3958e0SEnrico Granata                                 {
145885933ed4SEnrico Granata                                     was_plain_var = true;
1459c482a192SEnrico Granata                                     target = valobj;
146086cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
14610a3958e0SEnrico Granata                                 }
14629fc1944eSEnrico Granata                                 else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0)
14639fc1944eSEnrico Granata                                 {
146485933ed4SEnrico Granata                                     was_var_format = true;
14659fc1944eSEnrico Granata                                     // this is a variable with some custom format applied to it
14669fc1944eSEnrico Granata                                     const char* percent_position;
1467c482a192SEnrico Granata                                     target = valobj;
146886cc9829SEnrico Granata                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
14699fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
14709fc1944eSEnrico Granata                                                           var_name_end,
14719fc1944eSEnrico Granata                                                           &var_name_final,
14729fc1944eSEnrico Granata                                                           &percent_position,
14739fc1944eSEnrico Granata                                                           &custom_format,
14749fc1944eSEnrico Granata                                                           &val_obj_display);
14750a3958e0SEnrico Granata                                 }
14769fc1944eSEnrico Granata                                     // this is ${var.something} or multiple .something nested
14779fc1944eSEnrico Granata                                 else if (::strncmp (var_name_begin, "var", strlen("var")) == 0)
14789fc1944eSEnrico Granata                                 {
1479a777dc2aSEnrico Granata                                     if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0)
1480a777dc2aSEnrico Granata                                         was_var_indexed = true;
14819fc1944eSEnrico Granata                                     const char* percent_position;
14829fc1944eSEnrico Granata                                     ScanFormatDescriptor (var_name_begin,
14839fc1944eSEnrico Granata                                                           var_name_end,
14849fc1944eSEnrico Granata                                                           &var_name_final,
14859fc1944eSEnrico Granata                                                           &percent_position,
14869fc1944eSEnrico Granata                                                           &custom_format,
14879fc1944eSEnrico Granata                                                           &val_obj_display);
14889fc1944eSEnrico Granata 
14899fc1944eSEnrico Granata                                     const char* open_bracket_position;
14909fc1944eSEnrico Granata                                     const char* separator_position;
14919fc1944eSEnrico Granata                                     ScanBracketedRange (var_name_begin,
14929fc1944eSEnrico Granata                                                         var_name_end,
14939fc1944eSEnrico Granata                                                         var_name_final,
14949fc1944eSEnrico Granata                                                         &open_bracket_position,
14959fc1944eSEnrico Granata                                                         &separator_position,
14969fc1944eSEnrico Granata                                                         &close_bracket_position,
14979fc1944eSEnrico Granata                                                         &var_name_final_if_array_range,
14989fc1944eSEnrico Granata                                                         &index_lower,
14999fc1944eSEnrico Granata                                                         &index_higher);
15009fc1944eSEnrico Granata 
15019fc1944eSEnrico Granata                                     Error error;
15029fc1944eSEnrico Granata 
1503599171adSEnrico Granata                                     std::string expr_path(var_name_final-var_name_begin-1,0);
1504599171adSEnrico Granata                                     memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
1505fc7a7f3bSEnrico Granata 
1506e992a089SEnrico Granata                                     if (log)
1507599171adSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
1508fc7a7f3bSEnrico Granata 
1509599171adSEnrico Granata                                     target = valobj->GetValueForExpressionPath(expr_path.c_str(),
1510fc7a7f3bSEnrico Granata                                                                              &first_unparsed,
1511fc7a7f3bSEnrico Granata                                                                              &reason_to_stop,
1512fc7a7f3bSEnrico Granata                                                                              &final_value_type,
1513fc7a7f3bSEnrico Granata                                                                              options,
1514fc7a7f3bSEnrico Granata                                                                              &what_next).get();
1515fc7a7f3bSEnrico Granata 
1516fc7a7f3bSEnrico Granata                                     if (!target)
15179fc1944eSEnrico Granata                                     {
1518e992a089SEnrico Granata                                         if (log)
1519d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
1520e992a089SEnrico Granata                                                " final_value_type %d",
1521fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1522fc7a7f3bSEnrico Granata                                         break;
15230a3958e0SEnrico Granata                                     }
1524a7187d00SEnrico Granata                                     else
1525fc7a7f3bSEnrico Granata                                     {
1526e992a089SEnrico Granata                                         if (log)
1527d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1528e992a089SEnrico Granata                                                " final_value_type %d",
1529fc7a7f3bSEnrico Granata                                                first_unparsed, reason_to_stop, final_value_type);
1530a7187d00SEnrico Granata                                     }
15310a3958e0SEnrico Granata                                 }
15320a3958e0SEnrico Granata                                 else
15330a3958e0SEnrico Granata                                     break;
15349fc1944eSEnrico Granata 
153586cc9829SEnrico Granata                                 is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
153686cc9829SEnrico Granata                                                   final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
1537fc7a7f3bSEnrico Granata 
153886cc9829SEnrico Granata                                 do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
1539fc7a7f3bSEnrico Granata 
1540a7187d00SEnrico Granata                                 if (do_deref_pointer && !is_array_range)
15410a3958e0SEnrico Granata                                 {
15429fc1944eSEnrico Granata                                     // I have not deref-ed yet, let's do it
15439fc1944eSEnrico Granata                                     // this happens when we are not going through GetValueForVariableExpressionPath
15449fc1944eSEnrico Granata                                     // to get to the target ValueObject
15459fc1944eSEnrico Granata                                     Error error;
15469fc1944eSEnrico Granata                                     target = target->Dereference(error).get();
1547dc940730SEnrico Granata                                     if (error.Fail())
1548dc940730SEnrico Granata                                     {
1549dc940730SEnrico Granata                                         if (log)
1550d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
1551dc940730SEnrico Granata                                         break;
1552dc940730SEnrico Granata                                     }
15539fc1944eSEnrico Granata                                     do_deref_pointer = false;
15540a3958e0SEnrico Granata                                 }
15550a3958e0SEnrico Granata 
1556a777dc2aSEnrico Granata                                 // <rdar://problem/11338654>
1557a777dc2aSEnrico Granata                                 // we do not want to use the summary for a bitfield of type T:n
1558a777dc2aSEnrico Granata                                 // if we were originally dealing with just a T - that would get
1559a777dc2aSEnrico Granata                                 // us into an endless recursion
1560a777dc2aSEnrico Granata                                 if (target->IsBitfield() && was_var_indexed)
1561a777dc2aSEnrico Granata                                 {
1562a777dc2aSEnrico Granata                                     // TODO: check for a (T:n)-specific summary - we should still obey that
1563a777dc2aSEnrico Granata                                     StreamString bitfield_name;
1564a777dc2aSEnrico Granata                                     bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
1565a777dc2aSEnrico Granata                                     lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
1566a777dc2aSEnrico Granata                                     if (!DataVisualization::GetSummaryForType(type_sp))
1567a777dc2aSEnrico Granata                                         val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
1568a777dc2aSEnrico Granata                                 }
1569a777dc2aSEnrico Granata 
157085933ed4SEnrico Granata                                 // TODO use flags for these
15714ef877f5SGreg Clayton                                 bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL);
1572f4efecd9SEnrico Granata                                 bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
157385933ed4SEnrico Granata                                 bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
1574f4efecd9SEnrico Granata 
157586cc9829SEnrico Granata                                 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
1576f4efecd9SEnrico Granata                                 {
157785933ed4SEnrico Granata                                     StreamString str_temp;
1578e992a089SEnrico Granata                                     if (log)
1579d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
1580d64d0bc0SEnrico Granata 
15815088c486SGreg Clayton                                     if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
1582d64d0bc0SEnrico Granata                                     {
1583f4efecd9SEnrico Granata                                         // try to use the special cases
158485933ed4SEnrico Granata                                         var_success = target->DumpPrintableRepresentation(str_temp,
158585933ed4SEnrico Granata                                                                                           val_obj_display,
158685933ed4SEnrico Granata                                                                                           custom_format);
1587e992a089SEnrico Granata                                         if (log)
1588d228483dSEnrico Granata                                             log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
1589d64d0bc0SEnrico Granata 
1590d64d0bc0SEnrico Granata                                         // should not happen
15915088c486SGreg Clayton                                         if (var_success)
159285933ed4SEnrico Granata                                             s << str_temp.GetData();
1593d64d0bc0SEnrico Granata                                         var_success = true;
1594d64d0bc0SEnrico Granata                                         break;
1595d64d0bc0SEnrico Granata                                     }
1596d64d0bc0SEnrico Granata                                     else
1597d64d0bc0SEnrico Granata                                     {
159888da35f8SEnrico Granata                                         if (was_plain_var) // if ${var}
1599d64d0bc0SEnrico Granata                                         {
1600d64d0bc0SEnrico Granata                                             s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1601d64d0bc0SEnrico Granata                                         }
160288da35f8SEnrico Granata                                         else if (is_pointer) // if pointer, value is the address stored
160388da35f8SEnrico Granata                                         {
160423f59509SGreg Clayton                                             target->DumpPrintableRepresentation (s,
160588da35f8SEnrico Granata                                                                                  val_obj_display,
160686cc9829SEnrico Granata                                                                                  custom_format,
160786cc9829SEnrico Granata                                                                                  ValueObject::ePrintableRepresentationSpecialCasesDisable);
160888da35f8SEnrico Granata                                         }
1609d64d0bc0SEnrico Granata                                         var_success = true;
1610d64d0bc0SEnrico Granata                                         break;
1611d64d0bc0SEnrico Granata                                     }
1612d64d0bc0SEnrico Granata                                 }
1613d64d0bc0SEnrico Granata 
1614d64d0bc0SEnrico Granata                                 // if directly trying to print ${var}, and this is an aggregate, display a nice
1615d64d0bc0SEnrico Granata                                 // type @ location message
1616d64d0bc0SEnrico Granata                                 if (is_aggregate && was_plain_var)
1617d64d0bc0SEnrico Granata                                 {
1618d64d0bc0SEnrico Granata                                     s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1619d64d0bc0SEnrico Granata                                     var_success = true;
162085933ed4SEnrico Granata                                     break;
162185933ed4SEnrico Granata                                 }
162285933ed4SEnrico Granata 
1623d64d0bc0SEnrico Granata                                 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
162486cc9829SEnrico Granata                                 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
162585933ed4SEnrico Granata                                 {
162685933ed4SEnrico Granata                                     s << "<invalid use of aggregate type>";
162785933ed4SEnrico Granata                                     var_success = true;
1628f4efecd9SEnrico Granata                                     break;
1629f4efecd9SEnrico Granata                                 }
1630f4efecd9SEnrico Granata 
16319fc1944eSEnrico Granata                                 if (!is_array_range)
1632e992a089SEnrico Granata                                 {
1633e992a089SEnrico Granata                                     if (log)
1634d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
16359fc1944eSEnrico Granata                                     var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1636e992a089SEnrico Granata                                 }
16379fc1944eSEnrico Granata                                 else
16389fc1944eSEnrico Granata                                 {
1639e992a089SEnrico Granata                                     if (log)
1640d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
16419fc1944eSEnrico Granata                                     if (!is_array && !is_pointer)
16429fc1944eSEnrico Granata                                         break;
1643e992a089SEnrico Granata                                     if (log)
1644d228483dSEnrico Granata                                         log->Printf("[Debugger::FormatPrompt] handle as array");
1645fc7a7f3bSEnrico Granata                                     const char* special_directions = NULL;
1646fc7a7f3bSEnrico Granata                                     StreamString special_directions_writer;
16470a3958e0SEnrico Granata                                     if (close_bracket_position && (var_name_end-close_bracket_position > 1))
16480a3958e0SEnrico Granata                                     {
1649fc7a7f3bSEnrico Granata                                         ConstString additional_data;
1650fc7a7f3bSEnrico Granata                                         additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1651fc7a7f3bSEnrico Granata                                         special_directions_writer.Printf("${%svar%s}",
1652fc7a7f3bSEnrico Granata                                                                          do_deref_pointer ? "*" : "",
1653fc7a7f3bSEnrico Granata                                                                          additional_data.GetCString());
1654fc7a7f3bSEnrico Granata                                         special_directions = special_directions_writer.GetData();
16550a3958e0SEnrico Granata                                     }
16560a3958e0SEnrico Granata 
16570a3958e0SEnrico Granata                                     // let us display items index_lower thru index_higher of this array
16580a3958e0SEnrico Granata                                     s.PutChar('[');
16590a3958e0SEnrico Granata                                     var_success = true;
16600a3958e0SEnrico Granata 
16619fc1944eSEnrico Granata                                     if (index_higher < 0)
1662c482a192SEnrico Granata                                         index_higher = valobj->GetNumChildren() - 1;
16630a3958e0SEnrico Granata 
1664cc4d0146SGreg Clayton                                     uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
166522c55d18SEnrico Granata 
16660a3958e0SEnrico Granata                                     for (;index_lower<=index_higher;index_lower++)
16670a3958e0SEnrico Granata                                     {
1668fc7a7f3bSEnrico Granata                                         ValueObject* item = ExpandIndexedExpression (target,
16699fc1944eSEnrico Granata                                                                                      index_lower,
1670c14ee32dSGreg Clayton                                                                                      exe_ctx->GetFramePtr(),
1671fc7a7f3bSEnrico Granata                                                                                      false).get();
16720a3958e0SEnrico Granata 
1673fc7a7f3bSEnrico Granata                                         if (!item)
1674fc7a7f3bSEnrico Granata                                         {
1675e992a089SEnrico Granata                                             if (log)
1676d01b2953SDaniel Malea                                                 log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
1677fc7a7f3bSEnrico Granata                                         }
1678fc7a7f3bSEnrico Granata                                         else
1679fc7a7f3bSEnrico Granata                                         {
1680e992a089SEnrico Granata                                             if (log)
1681d228483dSEnrico Granata                                                 log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
1682fc7a7f3bSEnrico Granata                                         }
1683fc7a7f3bSEnrico Granata 
16840a3958e0SEnrico Granata                                         if (!special_directions)
16859fc1944eSEnrico Granata                                             var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
16860a3958e0SEnrico Granata                                         else
16870a3958e0SEnrico Granata                                             var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item);
16880a3958e0SEnrico Granata 
168922c55d18SEnrico Granata                                         if (--max_num_children == 0)
169022c55d18SEnrico Granata                                         {
169122c55d18SEnrico Granata                                             s.PutCString(", ...");
169222c55d18SEnrico Granata                                             break;
169322c55d18SEnrico Granata                                         }
169422c55d18SEnrico Granata 
16950a3958e0SEnrico Granata                                         if (index_lower < index_higher)
16960a3958e0SEnrico Granata                                             s.PutChar(',');
16970a3958e0SEnrico Granata                                     }
16980a3958e0SEnrico Granata                                     s.PutChar(']');
16994becb37eSEnrico Granata                                 }
17004becb37eSEnrico Granata                             }
170134132754SGreg Clayton                             break;
17021b654882SGreg Clayton                         case 'a':
17031b654882SGreg Clayton                             if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
17041b654882SGreg Clayton                             {
17051b654882SGreg Clayton                                 if (addr && addr->IsValid())
17061b654882SGreg Clayton                                 {
17071b654882SGreg Clayton                                     var_success = true;
17081b654882SGreg Clayton                                     format_addr = *addr;
17091b654882SGreg Clayton                                 }
17101b654882SGreg Clayton                             }
17115a31471eSGreg Clayton                             else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0)
17125a31471eSGreg Clayton                             {
17135a31471eSGreg Clayton                                 var_success = true;
17145a31471eSGreg Clayton                                 var_name_begin += strlen("ansi."); // Skip the "ansi."
17155a31471eSGreg Clayton                                 if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0)
17165a31471eSGreg Clayton                                 {
17175a31471eSGreg Clayton                                     var_name_begin += strlen("fg."); // Skip the "fg."
17185a31471eSGreg Clayton                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
17195a31471eSGreg Clayton                                     {
17205a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17215a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17225a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_black,
17235a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17245a31471eSGreg Clayton                                     }
17255a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
17265a31471eSGreg Clayton                                     {
17275a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17285a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17295a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_red,
17305a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17315a31471eSGreg Clayton                                     }
17325a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
17335a31471eSGreg Clayton                                     {
17345a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17355a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17365a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_green,
17375a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17385a31471eSGreg Clayton                                     }
17395a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
17405a31471eSGreg Clayton                                     {
17415a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17425a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17435a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_yellow,
17445a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17455a31471eSGreg Clayton                                     }
17465a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
17475a31471eSGreg Clayton                                     {
17485a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17495a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17505a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_blue,
17515a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17525a31471eSGreg Clayton                                     }
17535a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
17545a31471eSGreg Clayton                                     {
17555a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17565a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17575a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_purple,
17585a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17595a31471eSGreg Clayton                                     }
17605a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
17615a31471eSGreg Clayton                                     {
17625a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17635a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17645a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_cyan,
17655a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17665a31471eSGreg Clayton                                     }
17675a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
17685a31471eSGreg Clayton                                     {
17695a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17705a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17715a31471eSGreg Clayton                                                   lldb_utility::ansi::k_fg_white,
17725a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17735a31471eSGreg Clayton                                     }
17745a31471eSGreg Clayton                                     else
17755a31471eSGreg Clayton                                     {
17765a31471eSGreg Clayton                                         var_success = false;
17775a31471eSGreg Clayton                                     }
17785a31471eSGreg Clayton                                 }
17795a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0)
17805a31471eSGreg Clayton                                 {
17815a31471eSGreg Clayton                                     var_name_begin += strlen("bg."); // Skip the "bg."
17825a31471eSGreg Clayton                                     if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
17835a31471eSGreg Clayton                                     {
17845a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17855a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17865a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_black,
17875a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17885a31471eSGreg Clayton                                     }
17895a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
17905a31471eSGreg Clayton                                     {
17915a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17925a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
17935a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_red,
17945a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
17955a31471eSGreg Clayton                                     }
17965a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
17975a31471eSGreg Clayton                                     {
17985a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
17995a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18005a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_green,
18015a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18025a31471eSGreg Clayton                                     }
18035a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
18045a31471eSGreg Clayton                                     {
18055a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18065a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18075a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_yellow,
18085a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18095a31471eSGreg Clayton                                     }
18105a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
18115a31471eSGreg Clayton                                     {
18125a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18135a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18145a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_blue,
18155a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18165a31471eSGreg Clayton                                     }
18175a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
18185a31471eSGreg Clayton                                     {
18195a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18205a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18215a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_purple,
18225a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18235a31471eSGreg Clayton                                     }
18245a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
18255a31471eSGreg Clayton                                     {
18265a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18275a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18285a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_cyan,
18295a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18305a31471eSGreg Clayton                                     }
18315a31471eSGreg Clayton                                     else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
18325a31471eSGreg Clayton                                     {
18335a31471eSGreg Clayton                                         s.Printf ("%s%s%s",
18345a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_start,
18355a31471eSGreg Clayton                                                   lldb_utility::ansi::k_bg_white,
18365a31471eSGreg Clayton                                                   lldb_utility::ansi::k_escape_end);
18375a31471eSGreg Clayton                                     }
18385a31471eSGreg Clayton                                     else
18395a31471eSGreg Clayton                                     {
18405a31471eSGreg Clayton                                         var_success = false;
18415a31471eSGreg Clayton                                     }
18425a31471eSGreg Clayton                                 }
18435a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0)
18445a31471eSGreg Clayton                                 {
18455a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18465a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18475a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_normal,
18485a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18495a31471eSGreg Clayton                                 }
18505a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0)
18515a31471eSGreg Clayton                                 {
18525a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18535a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18545a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_bold,
18555a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18565a31471eSGreg Clayton                                 }
18575a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0)
18585a31471eSGreg Clayton                                 {
18595a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18605a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18615a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_faint,
18625a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18635a31471eSGreg Clayton                                 }
18645a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0)
18655a31471eSGreg Clayton                                 {
18665a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18675a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18685a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_italic,
18695a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18705a31471eSGreg Clayton                                 }
18715a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0)
18725a31471eSGreg Clayton                                 {
18735a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18745a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18755a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_underline,
18765a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18775a31471eSGreg Clayton                                 }
18785a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0)
18795a31471eSGreg Clayton                                 {
18805a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18815a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18825a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_slow_blink,
18835a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18845a31471eSGreg Clayton                                 }
18855a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0)
18865a31471eSGreg Clayton                                 {
18875a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18885a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18895a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_fast_blink,
18905a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18915a31471eSGreg Clayton                                 }
18925a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0)
18935a31471eSGreg Clayton                                 {
18945a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
18955a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
18965a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_negative,
18975a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
18985a31471eSGreg Clayton                                 }
18995a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0)
19005a31471eSGreg Clayton                                 {
19015a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
19025a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
19035a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_conceal,
19045a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
19055a31471eSGreg Clayton 
19065a31471eSGreg Clayton                                 }
19075a31471eSGreg Clayton                                 else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0)
19085a31471eSGreg Clayton                                 {
19095a31471eSGreg Clayton                                     s.Printf ("%s%s%s",
19105a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_start,
19115a31471eSGreg Clayton                                               lldb_utility::ansi::k_ctrl_crossed_out,
19125a31471eSGreg Clayton                                               lldb_utility::ansi::k_escape_end);
19135a31471eSGreg Clayton                                 }
19145a31471eSGreg Clayton                                 else
19155a31471eSGreg Clayton                                 {
19165a31471eSGreg Clayton                                     var_success = false;
19175a31471eSGreg Clayton                                 }
19185a31471eSGreg Clayton                             }
19191b654882SGreg Clayton                             break;
19201b654882SGreg Clayton 
19211b654882SGreg Clayton                         case 'p':
19221b654882SGreg Clayton                             if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
19231b654882SGreg Clayton                             {
1924c14ee32dSGreg Clayton                                 if (exe_ctx)
1925c14ee32dSGreg Clayton                                 {
1926c14ee32dSGreg Clayton                                     Process *process = exe_ctx->GetProcessPtr();
1927c14ee32dSGreg Clayton                                     if (process)
19281b654882SGreg Clayton                                     {
19291b654882SGreg Clayton                                         var_name_begin += ::strlen ("process.");
19301b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
19311b654882SGreg Clayton                                         {
1932d01b2953SDaniel Malea                                             s.Printf("%" PRIu64, process->GetID());
19331b654882SGreg Clayton                                             var_success = true;
19341b654882SGreg Clayton                                         }
19351b654882SGreg Clayton                                         else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
19361b654882SGreg Clayton                                                  (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
19371b654882SGreg Clayton                                                  (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
19381b654882SGreg Clayton                                         {
1939c14ee32dSGreg Clayton                                             Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1940aa149cbdSGreg Clayton                                             if (exe_module)
19411b654882SGreg Clayton                                             {
19421b654882SGreg Clayton                                                 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
19431b654882SGreg Clayton                                                 {
1944aa149cbdSGreg Clayton                                                     format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
19451b654882SGreg Clayton                                                     var_success = format_file_spec;
19461b654882SGreg Clayton                                                 }
19471b654882SGreg Clayton                                                 else
19481b654882SGreg Clayton                                                 {
1949aa149cbdSGreg Clayton                                                     format_file_spec = exe_module->GetFileSpec();
19501b654882SGreg Clayton                                                     var_success = format_file_spec;
19511b654882SGreg Clayton                                                 }
19521b654882SGreg Clayton                                             }
19531b654882SGreg Clayton                                         }
19541b654882SGreg Clayton                                     }
19551b654882SGreg Clayton                                 }
1956c14ee32dSGreg Clayton                             }
19571b654882SGreg Clayton                             break;
19581b654882SGreg Clayton 
19591b654882SGreg Clayton                         case 't':
19601b654882SGreg Clayton                             if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
19611b654882SGreg Clayton                             {
1962c14ee32dSGreg Clayton                                 if (exe_ctx)
1963c14ee32dSGreg Clayton                                 {
1964c14ee32dSGreg Clayton                                     Thread *thread = exe_ctx->GetThreadPtr();
1965c14ee32dSGreg Clayton                                     if (thread)
19661b654882SGreg Clayton                                     {
19671b654882SGreg Clayton                                         var_name_begin += ::strlen ("thread.");
19681b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
19691b654882SGreg Clayton                                         {
1970d01b2953SDaniel Malea                                             s.Printf("0x%4.4" PRIx64, thread->GetID());
19711b654882SGreg Clayton                                             var_success = true;
19721b654882SGreg Clayton                                         }
1973160c9d81SGreg Clayton                                         else if (::strncmp (var_name_begin, "protocol_id}", strlen("protocol_id}")) == 0)
1974160c9d81SGreg Clayton                                         {
1975160c9d81SGreg Clayton                                             s.Printf("0x%4.4" PRIx64, thread->GetProtocolID());
1976160c9d81SGreg Clayton                                             var_success = true;
1977160c9d81SGreg Clayton                                         }
19781b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
19791b654882SGreg Clayton                                         {
1980c14ee32dSGreg Clayton                                             s.Printf("%u", thread->GetIndexID());
19811b654882SGreg Clayton                                             var_success = true;
19821b654882SGreg Clayton                                         }
19831b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
19841b654882SGreg Clayton                                         {
1985c14ee32dSGreg Clayton                                             cstr = thread->GetName();
19861b654882SGreg Clayton                                             var_success = cstr && cstr[0];
19871b654882SGreg Clayton                                             if (var_success)
19881b654882SGreg Clayton                                                 s.PutCString(cstr);
19891b654882SGreg Clayton                                         }
19901b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
19911b654882SGreg Clayton                                         {
1992c14ee32dSGreg Clayton                                             cstr = thread->GetQueueName();
19931b654882SGreg Clayton                                             var_success = cstr && cstr[0];
19941b654882SGreg Clayton                                             if (var_success)
19951b654882SGreg Clayton                                                 s.PutCString(cstr);
19961b654882SGreg Clayton                                         }
19971b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
19981b654882SGreg Clayton                                         {
1999c14ee32dSGreg Clayton                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
20005d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
20011b654882SGreg Clayton                                             {
2002b15bfc75SJim Ingham                                                 cstr = stop_info_sp->GetDescription();
20031b654882SGreg Clayton                                                 if (cstr && cstr[0])
20041b654882SGreg Clayton                                                 {
20051b654882SGreg Clayton                                                     s.PutCString(cstr);
20061b654882SGreg Clayton                                                     var_success = true;
20071b654882SGreg Clayton                                                 }
20081b654882SGreg Clayton                                             }
20091b654882SGreg Clayton                                         }
201073ca05a2SJim Ingham                                         else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0)
201173ca05a2SJim Ingham                                         {
201273ca05a2SJim Ingham                                             StopInfoSP stop_info_sp = thread->GetStopInfo ();
20135d88a068SJim Ingham                                             if (stop_info_sp && stop_info_sp->IsValid())
201473ca05a2SJim Ingham                                             {
201573ca05a2SJim Ingham                                                 ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
201673ca05a2SJim Ingham                                                 if (return_valobj_sp)
201773ca05a2SJim Ingham                                                 {
20189fb5ab55SEnrico Granata                                                     ValueObject::DumpValueObject (s, return_valobj_sp.get());
201973ca05a2SJim Ingham                                                     var_success = true;
202073ca05a2SJim Ingham                                                 }
202173ca05a2SJim Ingham                                             }
202273ca05a2SJim Ingham                                         }
202373ca05a2SJim Ingham                                     }
20241b654882SGreg Clayton                                 }
20251b654882SGreg Clayton                             }
20261b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
20271b654882SGreg Clayton                             {
202867cc0636SGreg Clayton                                 // TODO: hookup properties
202967cc0636SGreg Clayton //                                if (!target_properties_sp)
203067cc0636SGreg Clayton //                                {
203167cc0636SGreg Clayton //                                    Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
203267cc0636SGreg Clayton //                                    if (target)
203367cc0636SGreg Clayton //                                        target_properties_sp = target->GetProperties();
203467cc0636SGreg Clayton //                                }
203567cc0636SGreg Clayton //
203667cc0636SGreg Clayton //                                if (target_properties_sp)
203767cc0636SGreg Clayton //                                {
203867cc0636SGreg Clayton //                                    var_name_begin += ::strlen ("target.");
203967cc0636SGreg Clayton //                                    const char *end_property = strchr(var_name_begin, '}');
204067cc0636SGreg Clayton //                                    if (end_property)
204167cc0636SGreg Clayton //                                    {
204267cc0636SGreg Clayton //                                        ConstString property_name(var_name_begin, end_property - var_name_begin);
204367cc0636SGreg Clayton //                                        std::string property_value (target_properties_sp->GetPropertyValue(property_name));
204467cc0636SGreg Clayton //                                        if (!property_value.empty())
204567cc0636SGreg Clayton //                                        {
204667cc0636SGreg Clayton //                                            s.PutCString (property_value.c_str());
204767cc0636SGreg Clayton //                                            var_success = true;
204867cc0636SGreg Clayton //                                        }
204967cc0636SGreg Clayton //                                    }
205067cc0636SGreg Clayton //                                }
20510603aa9dSGreg Clayton                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
20520603aa9dSGreg Clayton                                 if (target)
20531b654882SGreg Clayton                                 {
20541b654882SGreg Clayton                                     var_name_begin += ::strlen ("target.");
20551b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
20561b654882SGreg Clayton                                     {
20571b654882SGreg Clayton                                         ArchSpec arch (target->GetArchitecture ());
20581b654882SGreg Clayton                                         if (arch.IsValid())
20591b654882SGreg Clayton                                         {
206064195a2cSGreg Clayton                                             s.PutCString (arch.GetArchitectureName());
20611b654882SGreg Clayton                                             var_success = true;
20621b654882SGreg Clayton                                         }
20631b654882SGreg Clayton                                     }
20641b654882SGreg Clayton                                 }
20651b654882SGreg Clayton                             }
20661b654882SGreg Clayton                             break;
20671b654882SGreg Clayton 
20681b654882SGreg Clayton 
20691b654882SGreg Clayton                         case 'm':
20701b654882SGreg Clayton                             if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
20711b654882SGreg Clayton                             {
20720603aa9dSGreg Clayton                                 if (sc && sc->module_sp.get())
20731b654882SGreg Clayton                                 {
20740603aa9dSGreg Clayton                                     Module *module = sc->module_sp.get();
20751b654882SGreg Clayton                                     var_name_begin += ::strlen ("module.");
20761b654882SGreg Clayton 
20771b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
20781b654882SGreg Clayton                                     {
20791b654882SGreg Clayton                                         if (module->GetFileSpec())
20801b654882SGreg Clayton                                         {
20811b654882SGreg Clayton                                             var_name_begin += ::strlen ("file.");
20821b654882SGreg Clayton 
20831b654882SGreg Clayton                                             if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
20841b654882SGreg Clayton                                             {
20851b654882SGreg Clayton                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
20861b654882SGreg Clayton                                                 var_success = format_file_spec;
20871b654882SGreg Clayton                                             }
20881b654882SGreg Clayton                                             else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
20891b654882SGreg Clayton                                             {
20901b654882SGreg Clayton                                                 format_file_spec = module->GetFileSpec();
20911b654882SGreg Clayton                                                 var_success = format_file_spec;
20921b654882SGreg Clayton                                             }
20931b654882SGreg Clayton                                         }
20941b654882SGreg Clayton                                     }
20951b654882SGreg Clayton                                 }
20961b654882SGreg Clayton                             }
20971b654882SGreg Clayton                             break;
20981b654882SGreg Clayton 
20991b654882SGreg Clayton 
21001b654882SGreg Clayton                         case 'f':
21011b654882SGreg Clayton                             if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
21021b654882SGreg Clayton                             {
21031b654882SGreg Clayton                                 if (sc && sc->comp_unit != NULL)
21041b654882SGreg Clayton                                 {
21051b654882SGreg Clayton                                     var_name_begin += ::strlen ("file.");
21061b654882SGreg Clayton 
21071b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
21081b654882SGreg Clayton                                     {
21091b654882SGreg Clayton                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
21101b654882SGreg Clayton                                         var_success = format_file_spec;
21111b654882SGreg Clayton                                     }
21121b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
21131b654882SGreg Clayton                                     {
21141b654882SGreg Clayton                                         format_file_spec = *sc->comp_unit;
21151b654882SGreg Clayton                                         var_success = format_file_spec;
21161b654882SGreg Clayton                                     }
21171b654882SGreg Clayton                                 }
21181b654882SGreg Clayton                             }
21191b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
21201b654882SGreg Clayton                             {
2121c14ee32dSGreg Clayton                                 if (exe_ctx)
2122c14ee32dSGreg Clayton                                 {
2123c14ee32dSGreg Clayton                                     StackFrame *frame = exe_ctx->GetFramePtr();
2124c14ee32dSGreg Clayton                                     if (frame)
21251b654882SGreg Clayton                                     {
21261b654882SGreg Clayton                                         var_name_begin += ::strlen ("frame.");
21271b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
21281b654882SGreg Clayton                                         {
2129c14ee32dSGreg Clayton                                             s.Printf("%u", frame->GetFrameIndex());
21301b654882SGreg Clayton                                             var_success = true;
21311b654882SGreg Clayton                                         }
21321b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
21331b654882SGreg Clayton                                         {
21341b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21351b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_PC;
21361b654882SGreg Clayton                                             var_success = true;
21371b654882SGreg Clayton                                         }
21381b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
21391b654882SGreg Clayton                                         {
21401b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21411b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_SP;
21421b654882SGreg Clayton                                             var_success = true;
21431b654882SGreg Clayton                                         }
21441b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
21451b654882SGreg Clayton                                         {
21461b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21471b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FP;
21481b654882SGreg Clayton                                             var_success = true;
21491b654882SGreg Clayton                                         }
21501b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
21511b654882SGreg Clayton                                         {
21521b654882SGreg Clayton                                             reg_kind = eRegisterKindGeneric;
21531b654882SGreg Clayton                                             reg_num = LLDB_REGNUM_GENERIC_FLAGS;
21541b654882SGreg Clayton                                             var_success = true;
21551b654882SGreg Clayton                                         }
21561b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
21571b654882SGreg Clayton                                         {
2158c14ee32dSGreg Clayton                                             reg_ctx = frame->GetRegisterContext().get();
21591b654882SGreg Clayton                                             if (reg_ctx)
21601b654882SGreg Clayton                                             {
21611b654882SGreg Clayton                                                 var_name_begin += ::strlen ("reg.");
21621b654882SGreg Clayton                                                 if (var_name_begin < var_name_end)
21631b654882SGreg Clayton                                                 {
21641b654882SGreg Clayton                                                     std::string reg_name (var_name_begin, var_name_end);
21651b654882SGreg Clayton                                                     reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
21661b654882SGreg Clayton                                                     if (reg_info)
21671b654882SGreg Clayton                                                         var_success = true;
21681b654882SGreg Clayton                                                 }
21691b654882SGreg Clayton                                             }
21701b654882SGreg Clayton                                         }
21711b654882SGreg Clayton                                     }
21721b654882SGreg Clayton                                 }
2173c14ee32dSGreg Clayton                             }
21741b654882SGreg Clayton                             else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
21751b654882SGreg Clayton                             {
21761b654882SGreg Clayton                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
21771b654882SGreg Clayton                                 {
21781b654882SGreg Clayton                                     var_name_begin += ::strlen ("function.");
21791b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
21801b654882SGreg Clayton                                     {
21811b654882SGreg Clayton                                         if (sc->function)
2182d01b2953SDaniel Malea                                             s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
21831b654882SGreg Clayton                                         else
21841b654882SGreg Clayton                                             s.Printf("symbol[%u]", sc->symbol->GetID());
21851b654882SGreg Clayton 
21861b654882SGreg Clayton                                         var_success = true;
21871b654882SGreg Clayton                                     }
21881b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
21891b654882SGreg Clayton                                     {
21901b654882SGreg Clayton                                         if (sc->function)
21911b654882SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
21921b654882SGreg Clayton                                         else if (sc->symbol)
21931b654882SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
21941b654882SGreg Clayton                                         if (cstr)
21951b654882SGreg Clayton                                         {
21961b654882SGreg Clayton                                             s.PutCString(cstr);
21970d9c9934SGreg Clayton 
21980d9c9934SGreg Clayton                                             if (sc->block)
21990d9c9934SGreg Clayton                                             {
22000d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
22010d9c9934SGreg Clayton                                                 if (inline_block)
22020d9c9934SGreg Clayton                                                 {
22030d9c9934SGreg Clayton                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
22040d9c9934SGreg Clayton                                                     if (inline_info)
22050d9c9934SGreg Clayton                                                     {
22060d9c9934SGreg Clayton                                                         s.PutCString(" [inlined] ");
22070d9c9934SGreg Clayton                                                         inline_info->GetName().Dump(&s);
22080d9c9934SGreg Clayton                                                     }
22090d9c9934SGreg Clayton                                                 }
22100d9c9934SGreg Clayton                                             }
22111b654882SGreg Clayton                                             var_success = true;
22121b654882SGreg Clayton                                         }
22131b654882SGreg Clayton                                     }
22146d3dbf51SGreg Clayton                                     else if (::strncmp (var_name_begin, "name-with-args}", strlen("name-with-args}")) == 0)
22156d3dbf51SGreg Clayton                                     {
22166d3dbf51SGreg Clayton                                         // Print the function name with arguments in it
22176d3dbf51SGreg Clayton 
22186d3dbf51SGreg Clayton                                         if (sc->function)
22196d3dbf51SGreg Clayton                                         {
22206d3dbf51SGreg Clayton                                             var_success = true;
22216d3dbf51SGreg Clayton                                             ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
22226d3dbf51SGreg Clayton                                             cstr = sc->function->GetName().AsCString (NULL);
22236d3dbf51SGreg Clayton                                             if (cstr)
22246d3dbf51SGreg Clayton                                             {
22256d3dbf51SGreg Clayton                                                 const InlineFunctionInfo *inline_info = NULL;
22266d3dbf51SGreg Clayton                                                 VariableListSP variable_list_sp;
22276d3dbf51SGreg Clayton                                                 bool get_function_vars = true;
22286d3dbf51SGreg Clayton                                                 if (sc->block)
22296d3dbf51SGreg Clayton                                                 {
22306d3dbf51SGreg Clayton                                                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
22316d3dbf51SGreg Clayton 
22326d3dbf51SGreg Clayton                                                     if (inline_block)
22336d3dbf51SGreg Clayton                                                     {
22346d3dbf51SGreg Clayton                                                         get_function_vars = false;
22356d3dbf51SGreg Clayton                                                         inline_info = sc->block->GetInlinedFunctionInfo();
22366d3dbf51SGreg Clayton                                                         if (inline_info)
22376d3dbf51SGreg Clayton                                                             variable_list_sp = inline_block->GetBlockVariableList (true);
22386d3dbf51SGreg Clayton                                                     }
22396d3dbf51SGreg Clayton                                                 }
22406d3dbf51SGreg Clayton 
22416d3dbf51SGreg Clayton                                                 if (get_function_vars)
22426d3dbf51SGreg Clayton                                                 {
22436d3dbf51SGreg Clayton                                                     variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
22446d3dbf51SGreg Clayton                                                 }
22456d3dbf51SGreg Clayton 
22466d3dbf51SGreg Clayton                                                 if (inline_info)
22476d3dbf51SGreg Clayton                                                 {
22486d3dbf51SGreg Clayton                                                     s.PutCString (cstr);
22496d3dbf51SGreg Clayton                                                     s.PutCString (" [inlined] ");
22506d3dbf51SGreg Clayton                                                     cstr = inline_info->GetName().GetCString();
22516d3dbf51SGreg Clayton                                                 }
22526d3dbf51SGreg Clayton 
22536d3dbf51SGreg Clayton                                                 VariableList args;
22546d3dbf51SGreg Clayton                                                 if (variable_list_sp)
2255cc7f9bf5SEnrico Granata                                                     variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
22566d3dbf51SGreg Clayton                                                 if (args.GetSize() > 0)
22576d3dbf51SGreg Clayton                                                 {
22586d3dbf51SGreg Clayton                                                     const char *open_paren = strchr (cstr, '(');
22596d3dbf51SGreg Clayton                                                     const char *close_paren = NULL;
22606d3dbf51SGreg Clayton                                                     if (open_paren)
2261855958caSGreg Clayton                                                     {
2262855958caSGreg Clayton                                                         if (strncmp(open_paren, "(anonymous namespace)", strlen("(anonymous namespace)")) == 0)
2263855958caSGreg Clayton                                                         {
2264855958caSGreg Clayton                                                             open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
2265855958caSGreg Clayton                                                             if (open_paren)
22666d3dbf51SGreg Clayton                                                                 close_paren = strchr (open_paren, ')');
2267855958caSGreg Clayton                                                         }
2268855958caSGreg Clayton                                                         else
2269855958caSGreg Clayton                                                             close_paren = strchr (open_paren, ')');
2270855958caSGreg Clayton                                                     }
22716d3dbf51SGreg Clayton 
22726d3dbf51SGreg Clayton                                                     if (open_paren)
22736d3dbf51SGreg Clayton                                                         s.Write(cstr, open_paren - cstr + 1);
22746d3dbf51SGreg Clayton                                                     else
22756d3dbf51SGreg Clayton                                                     {
22766d3dbf51SGreg Clayton                                                         s.PutCString (cstr);
22776d3dbf51SGreg Clayton                                                         s.PutChar ('(');
22786d3dbf51SGreg Clayton                                                     }
22795b6889b1SGreg Clayton                                                     const size_t num_args = args.GetSize();
22806d3dbf51SGreg Clayton                                                     for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
22816d3dbf51SGreg Clayton                                                     {
22826d3dbf51SGreg Clayton                                                         VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
22836d3dbf51SGreg Clayton                                                         ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
22846d3dbf51SGreg Clayton                                                         const char *var_name = var_value_sp->GetName().GetCString();
22856d3dbf51SGreg Clayton                                                         const char *var_value = var_value_sp->GetValueAsCString();
22866d3dbf51SGreg Clayton                                                         if (arg_idx > 0)
22876d3dbf51SGreg Clayton                                                             s.PutCString (", ");
22883b188b17SGreg Clayton                                                         if (var_value_sp->GetError().Success())
2289cc7f9bf5SEnrico Granata                                                         {
2290cc7f9bf5SEnrico Granata                                                             if (var_value)
22916d3dbf51SGreg Clayton                                                                 s.Printf ("%s=%s", var_name, var_value);
22923b188b17SGreg Clayton                                                             else
2293cc7f9bf5SEnrico Granata                                                                 s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
2294cc7f9bf5SEnrico Granata                                                         }
2295cc7f9bf5SEnrico Granata                                                         else
22963b188b17SGreg Clayton                                                             s.Printf ("%s=<unavailable>", var_name);
22976d3dbf51SGreg Clayton                                                     }
22986d3dbf51SGreg Clayton 
22996d3dbf51SGreg Clayton                                                     if (close_paren)
23006d3dbf51SGreg Clayton                                                         s.PutCString (close_paren);
23016d3dbf51SGreg Clayton                                                     else
23026d3dbf51SGreg Clayton                                                         s.PutChar(')');
23036d3dbf51SGreg Clayton 
23046d3dbf51SGreg Clayton                                                 }
23056d3dbf51SGreg Clayton                                                 else
23066d3dbf51SGreg Clayton                                                 {
23076d3dbf51SGreg Clayton                                                     s.PutCString(cstr);
23086d3dbf51SGreg Clayton                                                 }
23096d3dbf51SGreg Clayton                                             }
23106d3dbf51SGreg Clayton                                         }
23116d3dbf51SGreg Clayton                                         else if (sc->symbol)
23126d3dbf51SGreg Clayton                                         {
23136d3dbf51SGreg Clayton                                             cstr = sc->symbol->GetName().AsCString (NULL);
23146d3dbf51SGreg Clayton                                             if (cstr)
23156d3dbf51SGreg Clayton                                             {
23166d3dbf51SGreg Clayton                                                 s.PutCString(cstr);
23176d3dbf51SGreg Clayton                                                 var_success = true;
23186d3dbf51SGreg Clayton                                             }
23196d3dbf51SGreg Clayton                                         }
23206d3dbf51SGreg Clayton                                     }
23211b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
23221b654882SGreg Clayton                                     {
23231b654882SGreg Clayton                                         var_success = addr != NULL;
23241b654882SGreg Clayton                                         if (var_success)
23251b654882SGreg Clayton                                         {
23261b654882SGreg Clayton                                             format_addr = *addr;
23271b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23281b654882SGreg Clayton                                         }
23291b654882SGreg Clayton                                     }
23301b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
23311b654882SGreg Clayton                                     {
23321b654882SGreg Clayton                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
23331b654882SGreg Clayton                                         if (var_success)
23341b654882SGreg Clayton                                         {
23351b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
23361b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23371b654882SGreg Clayton                                         }
23381b654882SGreg Clayton                                     }
23391b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
23401b654882SGreg Clayton                                     {
2341c14ee32dSGreg Clayton                                         StackFrame *frame = exe_ctx->GetFramePtr();
2342c14ee32dSGreg Clayton                                         var_success = frame != NULL;
23431b654882SGreg Clayton                                         if (var_success)
23441b654882SGreg Clayton                                         {
2345c14ee32dSGreg Clayton                                             format_addr = frame->GetFrameCodeAddress();
23461b654882SGreg Clayton                                             calculate_format_addr_function_offset = true;
23471b654882SGreg Clayton                                         }
23481b654882SGreg Clayton                                     }
23491b654882SGreg Clayton                                 }
23501b654882SGreg Clayton                             }
23511b654882SGreg Clayton                             break;
23521b654882SGreg Clayton 
23531b654882SGreg Clayton                         case 'l':
23541b654882SGreg Clayton                             if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
23551b654882SGreg Clayton                             {
23561b654882SGreg Clayton                                 if (sc && sc->line_entry.IsValid())
23571b654882SGreg Clayton                                 {
23581b654882SGreg Clayton                                     var_name_begin += ::strlen ("line.");
23591b654882SGreg Clayton                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
23601b654882SGreg Clayton                                     {
23611b654882SGreg Clayton                                         var_name_begin += ::strlen ("file.");
23621b654882SGreg Clayton 
23631b654882SGreg Clayton                                         if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
23641b654882SGreg Clayton                                         {
23651b654882SGreg Clayton                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
23661b654882SGreg Clayton                                             var_success = format_file_spec;
23671b654882SGreg Clayton                                         }
23681b654882SGreg Clayton                                         else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
23691b654882SGreg Clayton                                         {
23701b654882SGreg Clayton                                             format_file_spec = sc->line_entry.file;
23711b654882SGreg Clayton                                             var_success = format_file_spec;
23721b654882SGreg Clayton                                         }
23731b654882SGreg Clayton                                     }
23741b654882SGreg Clayton                                     else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
23751b654882SGreg Clayton                                     {
23761b654882SGreg Clayton                                         var_success = true;
23771b654882SGreg Clayton                                         s.Printf("%u", sc->line_entry.line);
23781b654882SGreg Clayton                                     }
23791b654882SGreg Clayton                                     else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
23801b654882SGreg Clayton                                              (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
23811b654882SGreg Clayton                                     {
23821b654882SGreg Clayton                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
23831b654882SGreg Clayton                                         if (var_success)
23841b654882SGreg Clayton                                         {
23851b654882SGreg Clayton                                             format_addr = sc->line_entry.range.GetBaseAddress();
23861b654882SGreg Clayton                                             if (var_name_begin[0] == 'e')
23871b654882SGreg Clayton                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
23881b654882SGreg Clayton                                         }
23891b654882SGreg Clayton                                     }
23901b654882SGreg Clayton                                 }
23911b654882SGreg Clayton                             }
23921b654882SGreg Clayton                             break;
23931b654882SGreg Clayton                         }
23941b654882SGreg Clayton 
23951b654882SGreg Clayton                         if (var_success)
23961b654882SGreg Clayton                         {
23971b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
23981b654882SGreg Clayton                             if (reg_num != LLDB_INVALID_REGNUM)
23991b654882SGreg Clayton                             {
2400c14ee32dSGreg Clayton                                 StackFrame *frame = exe_ctx->GetFramePtr();
24011b654882SGreg Clayton                                 // We have a register value to display...
24021b654882SGreg Clayton                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
24031b654882SGreg Clayton                                 {
2404c14ee32dSGreg Clayton                                     format_addr = frame->GetFrameCodeAddress();
24051b654882SGreg Clayton                                 }
24061b654882SGreg Clayton                                 else
24071b654882SGreg Clayton                                 {
24081b654882SGreg Clayton                                     if (reg_ctx == NULL)
2409c14ee32dSGreg Clayton                                         reg_ctx = frame->GetRegisterContext().get();
24101b654882SGreg Clayton 
24111b654882SGreg Clayton                                     if (reg_ctx)
24121b654882SGreg Clayton                                     {
24131b654882SGreg Clayton                                         if (reg_kind != kNumRegisterKinds)
24141b654882SGreg Clayton                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
24151b654882SGreg Clayton                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
24161b654882SGreg Clayton                                         var_success = reg_info != NULL;
24171b654882SGreg Clayton                                     }
24181b654882SGreg Clayton                                 }
24191b654882SGreg Clayton                             }
24201b654882SGreg Clayton 
24211b654882SGreg Clayton                             if (reg_info != NULL)
24221b654882SGreg Clayton                             {
24237349bd90SGreg Clayton                                 RegisterValue reg_value;
24247349bd90SGreg Clayton                                 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
24257349bd90SGreg Clayton                                 if (var_success)
24261b654882SGreg Clayton                                 {
24279a8fa916SGreg Clayton                                     reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
24281b654882SGreg Clayton                                 }
24291b654882SGreg Clayton                             }
24301b654882SGreg Clayton 
24311b654882SGreg Clayton                             if (format_file_spec)
24321b654882SGreg Clayton                             {
24331b654882SGreg Clayton                                 s << format_file_spec;
24341b654882SGreg Clayton                             }
24351b654882SGreg Clayton 
24361b654882SGreg Clayton                             // If format addr is valid, then we need to print an address
24371b654882SGreg Clayton                             if (format_addr.IsValid())
24381b654882SGreg Clayton                             {
24390603aa9dSGreg Clayton                                 var_success = false;
24400603aa9dSGreg Clayton 
24411b654882SGreg Clayton                                 if (calculate_format_addr_function_offset)
24421b654882SGreg Clayton                                 {
24431b654882SGreg Clayton                                     Address func_addr;
24440603aa9dSGreg Clayton 
24450603aa9dSGreg Clayton                                     if (sc)
24460603aa9dSGreg Clayton                                     {
24471b654882SGreg Clayton                                         if (sc->function)
24480d9c9934SGreg Clayton                                         {
24491b654882SGreg Clayton                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
24500d9c9934SGreg Clayton                                             if (sc->block)
24510d9c9934SGreg Clayton                                             {
24520d9c9934SGreg Clayton                                                 // Check to make sure we aren't in an inline
24530d9c9934SGreg Clayton                                                 // function. If we are, use the inline block
24540d9c9934SGreg Clayton                                                 // range that contains "format_addr" since
24550d9c9934SGreg Clayton                                                 // blocks can be discontiguous.
24560d9c9934SGreg Clayton                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
24570d9c9934SGreg Clayton                                                 AddressRange inline_range;
24580d9c9934SGreg Clayton                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
24590d9c9934SGreg Clayton                                                     func_addr = inline_range.GetBaseAddress();
24600d9c9934SGreg Clayton                                             }
24610d9c9934SGreg Clayton                                         }
2462e7612134SGreg Clayton                                         else if (sc->symbol && sc->symbol->ValueIsAddress())
2463e7612134SGreg Clayton                                             func_addr = sc->symbol->GetAddress();
24640603aa9dSGreg Clayton                                     }
24651b654882SGreg Clayton 
24660603aa9dSGreg Clayton                                     if (func_addr.IsValid())
24671b654882SGreg Clayton                                     {
24681b654882SGreg Clayton                                         if (func_addr.GetSection() == format_addr.GetSection())
24691b654882SGreg Clayton                                         {
24701b654882SGreg Clayton                                             addr_t func_file_addr = func_addr.GetFileAddress();
24711b654882SGreg Clayton                                             addr_t addr_file_addr = format_addr.GetFileAddress();
24721b654882SGreg Clayton                                             if (addr_file_addr > func_file_addr)
2473d01b2953SDaniel Malea                                                 s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
24741b654882SGreg Clayton                                             else if (addr_file_addr < func_file_addr)
2475d01b2953SDaniel Malea                                                 s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
24760603aa9dSGreg Clayton                                             var_success = true;
24771b654882SGreg Clayton                                         }
24781b654882SGreg Clayton                                         else
24790603aa9dSGreg Clayton                                         {
24800603aa9dSGreg Clayton                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
24810603aa9dSGreg Clayton                                             if (target)
24820603aa9dSGreg Clayton                                             {
24830603aa9dSGreg Clayton                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
24840603aa9dSGreg Clayton                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
24850603aa9dSGreg Clayton                                                 if (addr_load_addr > func_load_addr)
2486d01b2953SDaniel Malea                                                     s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
24870603aa9dSGreg Clayton                                                 else if (addr_load_addr < func_load_addr)
2488d01b2953SDaniel Malea                                                     s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
24890603aa9dSGreg Clayton                                                 var_success = true;
24900603aa9dSGreg Clayton                                             }
24910603aa9dSGreg Clayton                                         }
24921b654882SGreg Clayton                                     }
24931b654882SGreg Clayton                                 }
24941b654882SGreg Clayton                                 else
24951b654882SGreg Clayton                                 {
24960603aa9dSGreg Clayton                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
24971b654882SGreg Clayton                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
24980603aa9dSGreg Clayton                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
24990603aa9dSGreg Clayton                                         vaddr = format_addr.GetLoadAddress (target);
25001b654882SGreg Clayton                                     if (vaddr == LLDB_INVALID_ADDRESS)
25011b654882SGreg Clayton                                         vaddr = format_addr.GetFileAddress ();
25021b654882SGreg Clayton 
25031b654882SGreg Clayton                                     if (vaddr != LLDB_INVALID_ADDRESS)
25040603aa9dSGreg Clayton                                     {
2505514487e8SGreg Clayton                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
250635f1a0d5SGreg Clayton                                         if (addr_width == 0)
250735f1a0d5SGreg Clayton                                             addr_width = 16;
2508d01b2953SDaniel Malea                                         s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
25090603aa9dSGreg Clayton                                         var_success = true;
25100603aa9dSGreg Clayton                                     }
25111b654882SGreg Clayton                                 }
25121b654882SGreg Clayton                             }
25131b654882SGreg Clayton                         }
25141b654882SGreg Clayton 
25151b654882SGreg Clayton                         if (var_success == false)
25161b654882SGreg Clayton                             success = false;
25171b654882SGreg Clayton                     }
25181b654882SGreg Clayton                     p = var_name_end;
25191b654882SGreg Clayton                 }
25201b654882SGreg Clayton                 else
25211b654882SGreg Clayton                     break;
25221b654882SGreg Clayton             }
25231b654882SGreg Clayton             else
25241b654882SGreg Clayton             {
25251b654882SGreg Clayton                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
25261b654882SGreg Clayton                 s.PutChar(*p);
25271b654882SGreg Clayton             }
25281b654882SGreg Clayton         }
25291b654882SGreg Clayton         else if (*p == '\\')
25301b654882SGreg Clayton         {
25311b654882SGreg Clayton             ++p; // skip the slash
25321b654882SGreg Clayton             switch (*p)
25331b654882SGreg Clayton             {
25341b654882SGreg Clayton             case 'a': s.PutChar ('\a'); break;
25351b654882SGreg Clayton             case 'b': s.PutChar ('\b'); break;
25361b654882SGreg Clayton             case 'f': s.PutChar ('\f'); break;
25371b654882SGreg Clayton             case 'n': s.PutChar ('\n'); break;
25381b654882SGreg Clayton             case 'r': s.PutChar ('\r'); break;
25391b654882SGreg Clayton             case 't': s.PutChar ('\t'); break;
25401b654882SGreg Clayton             case 'v': s.PutChar ('\v'); break;
25411b654882SGreg Clayton             case '\'': s.PutChar ('\''); break;
25421b654882SGreg Clayton             case '\\': s.PutChar ('\\'); break;
25431b654882SGreg Clayton             case '0':
25441b654882SGreg Clayton                 // 1 to 3 octal chars
25451b654882SGreg Clayton                 {
25460603aa9dSGreg Clayton                     // Make a string that can hold onto the initial zero char,
25470603aa9dSGreg Clayton                     // up to 3 octal digits, and a terminating NULL.
25480603aa9dSGreg Clayton                     char oct_str[5] = { 0, 0, 0, 0, 0 };
25490603aa9dSGreg Clayton 
25500603aa9dSGreg Clayton                     int i;
25510603aa9dSGreg Clayton                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
25520603aa9dSGreg Clayton                         oct_str[i] = p[i];
25530603aa9dSGreg Clayton 
25540603aa9dSGreg Clayton                     // We don't want to consume the last octal character since
25550603aa9dSGreg Clayton                     // the main for loop will do this for us, so we advance p by
25560603aa9dSGreg Clayton                     // one less than i (even if i is zero)
25570603aa9dSGreg Clayton                     p += i - 1;
25580603aa9dSGreg Clayton                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
25590603aa9dSGreg Clayton                     if (octal_value <= UINT8_MAX)
25601b654882SGreg Clayton                     {
2561c7bece56SGreg Clayton                         s.PutChar((char)octal_value);
25621b654882SGreg Clayton                     }
25631b654882SGreg Clayton                 }
25641b654882SGreg Clayton                 break;
25651b654882SGreg Clayton 
25661b654882SGreg Clayton             case 'x':
25671b654882SGreg Clayton                 // hex number in the format
25680603aa9dSGreg Clayton                 if (isxdigit(p[1]))
25691b654882SGreg Clayton                 {
25700603aa9dSGreg Clayton                     ++p;    // Skip the 'x'
25711b654882SGreg Clayton 
25720603aa9dSGreg Clayton                     // Make a string that can hold onto two hex chars plus a
25730603aa9dSGreg Clayton                     // NULL terminator
25741b654882SGreg Clayton                     char hex_str[3] = { 0,0,0 };
25751b654882SGreg Clayton                     hex_str[0] = *p;
25760603aa9dSGreg Clayton                     if (isxdigit(p[1]))
25770603aa9dSGreg Clayton                     {
25780603aa9dSGreg Clayton                         ++p; // Skip the first of the two hex chars
25791b654882SGreg Clayton                         hex_str[1] = *p;
25800603aa9dSGreg Clayton                     }
25810603aa9dSGreg Clayton 
25821b654882SGreg Clayton                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
25830603aa9dSGreg Clayton                     if (hex_value <= UINT8_MAX)
2584c7bece56SGreg Clayton                         s.PutChar ((char)hex_value);
25851b654882SGreg Clayton                 }
25861b654882SGreg Clayton                 else
25871b654882SGreg Clayton                 {
25880603aa9dSGreg Clayton                     s.PutChar('x');
25891b654882SGreg Clayton                 }
25901b654882SGreg Clayton                 break;
25911b654882SGreg Clayton 
25921b654882SGreg Clayton             default:
25930603aa9dSGreg Clayton                 // Just desensitize any other character by just printing what
25940603aa9dSGreg Clayton                 // came after the '\'
25950603aa9dSGreg Clayton                 s << *p;
25961b654882SGreg Clayton                 break;
25971b654882SGreg Clayton 
25981b654882SGreg Clayton             }
25991b654882SGreg Clayton 
26001b654882SGreg Clayton         }
26011b654882SGreg Clayton     }
26021b654882SGreg Clayton     if (end)
26031b654882SGreg Clayton         *end = p;
26041b654882SGreg Clayton     return success;
26051b654882SGreg Clayton }
26061b654882SGreg Clayton 
2607228063cdSJim Ingham void
2608228063cdSJim Ingham Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
2609228063cdSJim Ingham {
26104f02b22dSJim Ingham     // For simplicity's sake, I am not going to deal with how to close down any
26114f02b22dSJim Ingham     // open logging streams, I just redirect everything from here on out to the
26124f02b22dSJim Ingham     // callback.
2613228063cdSJim Ingham     m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
2614228063cdSJim Ingham }
2615228063cdSJim Ingham 
2616228063cdSJim Ingham bool
2617228063cdSJim Ingham Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
2618228063cdSJim Ingham {
2619228063cdSJim Ingham     Log::Callbacks log_callbacks;
2620228063cdSJim Ingham 
2621228063cdSJim Ingham     StreamSP log_stream_sp;
26229a028519SSean Callanan     if (m_log_callback_stream_sp)
2623228063cdSJim Ingham     {
2624228063cdSJim Ingham         log_stream_sp = m_log_callback_stream_sp;
2625228063cdSJim Ingham         // For now when using the callback mode you always get thread & timestamp.
2626228063cdSJim Ingham         log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
2627228063cdSJim Ingham     }
2628228063cdSJim Ingham     else if (log_file == NULL || *log_file == '\0')
2629228063cdSJim Ingham     {
2630228063cdSJim Ingham         log_stream_sp.reset(new StreamFile(GetOutputFile().GetDescriptor(), false));
2631228063cdSJim Ingham     }
2632228063cdSJim Ingham     else
2633228063cdSJim Ingham     {
2634228063cdSJim Ingham         LogStreamMap::iterator pos = m_log_streams.find(log_file);
2635c1b2ccfdSGreg Clayton         if (pos != m_log_streams.end())
2636c1b2ccfdSGreg Clayton             log_stream_sp = pos->second.lock();
2637c1b2ccfdSGreg Clayton         if (!log_stream_sp)
2638228063cdSJim Ingham         {
2639228063cdSJim Ingham             log_stream_sp.reset (new StreamFile (log_file));
2640228063cdSJim Ingham             m_log_streams[log_file] = log_stream_sp;
2641228063cdSJim Ingham         }
2642228063cdSJim Ingham     }
2643228063cdSJim Ingham     assert (log_stream_sp.get());
2644228063cdSJim Ingham 
2645228063cdSJim Ingham     if (log_options == 0)
2646228063cdSJim Ingham         log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
2647228063cdSJim Ingham 
264857abc5d6SGreg Clayton     if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
2649228063cdSJim Ingham     {
2650228063cdSJim Ingham         log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
2651228063cdSJim Ingham         return true;
2652228063cdSJim Ingham     }
2653228063cdSJim Ingham     else
2654228063cdSJim Ingham     {
2655228063cdSJim Ingham         LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
2656228063cdSJim Ingham         if (log_channel_sp)
2657228063cdSJim Ingham         {
2658228063cdSJim Ingham             if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
2659228063cdSJim Ingham             {
2660228063cdSJim Ingham                 return true;
2661228063cdSJim Ingham             }
2662228063cdSJim Ingham             else
2663228063cdSJim Ingham             {
2664228063cdSJim Ingham                 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2665228063cdSJim Ingham                 return false;
2666228063cdSJim Ingham             }
2667228063cdSJim Ingham         }
2668228063cdSJim Ingham         else
2669228063cdSJim Ingham         {
2670228063cdSJim Ingham             error_stream.Printf ("Invalid log channel '%s'.\n", channel);
2671228063cdSJim Ingham             return false;
2672228063cdSJim Ingham         }
2673228063cdSJim Ingham     }
2674228063cdSJim Ingham     return false;
2675228063cdSJim Ingham }
2676228063cdSJim Ingham 
26779585fbfcSGreg Clayton SourceManager &
26789585fbfcSGreg Clayton Debugger::GetSourceManager ()
26799585fbfcSGreg Clayton {
26809585fbfcSGreg Clayton     if (m_source_manager_ap.get() == NULL)
26819585fbfcSGreg Clayton         m_source_manager_ap.reset (new SourceManager (shared_from_this()));
26829585fbfcSGreg Clayton     return *m_source_manager_ap;
26839585fbfcSGreg Clayton }
26849585fbfcSGreg Clayton 
26859585fbfcSGreg Clayton 
2686