]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Core/FormatEntity.cpp
Import LLDB as of upstream SVN 228549 (git 39760838)
[FreeBSD/FreeBSD.git] / source / Core / FormatEntity.cpp
1 //===-- FormatEntity.cpp ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/ADT/StringRef.h"
11
12 #include "lldb/Core/FormatEntity.h"
13
14 #include "lldb/Core/Address.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/Stream.h"
18 #include "lldb/Core/StreamString.h"
19 #include "lldb/Core/ValueObject.h"
20 #include "lldb/Core/ValueObjectVariable.h"
21 #include "lldb/DataFormatters/DataVisualization.h"
22 #include "lldb/DataFormatters/FormatManager.h"
23 #include "lldb/Host/FileSpec.h"
24 #include "lldb/Interpreter/CommandInterpreter.h"
25 #include "lldb/Symbol/Block.h"
26 #include "lldb/Symbol/CompileUnit.h"
27 #include "lldb/Symbol/Function.h"
28 #include "lldb/Symbol/LineEntry.h"
29 #include "lldb/Symbol/Symbol.h"
30 #include "lldb/Symbol/VariableList.h"
31 #include "lldb/Target/ExecutionContext.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/RegisterContext.h"
34 #include "lldb/Target/SectionLoadList.h"
35 #include "lldb/Target/StackFrame.h"
36 #include "lldb/Target/StopInfo.h"
37 #include "lldb/Target/Target.h"
38 #include "lldb/Target/Thread.h"
39 #include "lldb/Utility/AnsiTerminal.h"
40
41 using namespace lldb;
42 using namespace lldb_private;
43
44
45 enum FileKind
46 {
47     FileError = 0,
48     Basename,
49     Dirname,
50     Fullpath
51 };
52
53 #define ENTRY(n,t,f)            { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,0,NULL, false}
54 #define ENTRY_VALUE(n,t,f,v)    { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, v,0,NULL, false}
55 #define ENTRY_CHILDREN(n,t,f,c) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,llvm::array_lengthof(c),c, false}
56 #define ENTRY_CHILDREN_KEEP_SEP(n,t,f,c) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,llvm::array_lengthof(c),c, true}
57 #define ENTRY_STRING(n,s)       { n, s, FormatEntity::Entry::Type::InsertString, FormatEntity::Entry::FormatType::None, 0,0, NULL, false}
58 static FormatEntity::Entry::Definition g_string_entry[] =
59 {
60     ENTRY("*", ParentString, None)
61 };
62
63 static FormatEntity::Entry::Definition g_addr_entries[] =
64 {
65     ENTRY ("load", AddressLoad      , UInt64),
66     ENTRY ("file", AddressFile      , UInt64),
67     ENTRY ("load", AddressLoadOrFile, UInt64),
68 };
69
70 static FormatEntity::Entry::Definition g_file_child_entries[] =
71 {
72     ENTRY_VALUE("basename", ParentNumber, CString, FileKind::Basename),
73     ENTRY_VALUE("dirname", ParentNumber, CString, FileKind::Dirname),
74     ENTRY_VALUE("fullpath", ParentNumber, CString, FileKind::Fullpath)
75 };
76
77 static FormatEntity::Entry::Definition g_frame_child_entries[] =
78 {
79     
80     ENTRY ("index", FrameIndex        , UInt32),
81     ENTRY ("pc"   , FrameRegisterPC   , UInt64),
82     ENTRY ("fp"   , FrameRegisterFP   , UInt64),
83     ENTRY ("sp"   , FrameRegisterSP   , UInt64),
84     ENTRY ("flags", FrameRegisterFlags, UInt64),
85     ENTRY_CHILDREN ("reg", FrameRegisterByName, UInt64, g_string_entry),
86 };
87
88 static FormatEntity::Entry::Definition g_function_child_entries[] =
89 {
90     ENTRY ("id"                  , FunctionID             , UInt64),
91     ENTRY ("name"                , FunctionName           , CString),
92     ENTRY ("name-without-args"   , FunctionNameNoArgs     , CString),
93     ENTRY ("name-with-args"      , FunctionNameWithArgs   , CString),
94     ENTRY ("addr-offset"         , FunctionAddrOffset     , UInt64),
95     ENTRY ("concrete-only-addr-offset-no-padding", FunctionAddrOffsetConcrete, UInt64),
96     ENTRY ("line-offset"         , FunctionLineOffset     , UInt64),
97     ENTRY ("pc-offset"           , FunctionPCOffset       , UInt64)
98 };
99
100 static FormatEntity::Entry::Definition g_line_child_entries[] =
101 {
102     ENTRY_CHILDREN("file", LineEntryFile        , None  , g_file_child_entries),
103     ENTRY("number"       , LineEntryLineNumber  , UInt32),
104     ENTRY("start-addr"   , LineEntryStartAddress, UInt64),
105     ENTRY("end-addr"     , LineEntryEndAddress  , UInt64),
106 };
107
108 static FormatEntity::Entry::Definition g_module_child_entries[] =
109 {
110     ENTRY_CHILDREN("file", ModuleFile, None, g_file_child_entries),
111 };
112
113 static FormatEntity::Entry::Definition g_process_child_entries[] =
114 {
115     ENTRY           ( "id"      , ProcessID     , UInt64    ),
116     ENTRY_VALUE     ( "name"    , ProcessFile   , CString   , FileKind::Basename),
117     ENTRY_CHILDREN  ( "file"    , ProcessFile   , None      , g_file_child_entries),
118 };
119
120 static FormatEntity::Entry::Definition g_svar_child_entries[] =
121 {
122     ENTRY           ( "*"       , ParentString  , None)
123 };
124
125 static FormatEntity::Entry::Definition g_var_child_entries[] =
126 {
127     ENTRY           ( "*"       , ParentString  , None)
128 };
129
130 static FormatEntity::Entry::Definition g_thread_child_entries[] =
131 {
132     ENTRY           ( "id"                  , ThreadID                   , UInt64   ),
133     ENTRY           ( "protocol_id"         , ThreadProtocolID           , UInt64   ),
134     ENTRY           ( "index"               , ThreadIndexID              , UInt32   ),
135     ENTRY_CHILDREN  ( "info"                , ThreadInfo                 , None     , g_string_entry),
136     ENTRY           ( "queue"               , ThreadQueue                , CString  ),
137     ENTRY           ( "name"                , ThreadName                 , CString  ),
138     ENTRY           ( "stop-reason"         , ThreadStopReason           , CString  ),
139     ENTRY           ( "return-value"        , ThreadReturnValue          , CString  ),
140     ENTRY           ( "completed-expression", ThreadCompletedExpression  , CString  ),
141 };
142
143 static FormatEntity::Entry::Definition g_target_child_entries[] =
144 {
145     ENTRY           ( "arch"    , TargetArch    , CString   ),
146 };
147
148 #define _TO_STR2(_val) #_val
149 #define _TO_STR(_val) _TO_STR2(_val)
150
151 static FormatEntity::Entry::Definition g_ansi_fg_entries[] =
152 {
153     ENTRY_STRING ("black"   , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK)      ANSI_ESC_END),
154     ENTRY_STRING ("red"     , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED)        ANSI_ESC_END),
155     ENTRY_STRING ("green"   , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN)      ANSI_ESC_END),
156     ENTRY_STRING ("yellow"  , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW)     ANSI_ESC_END),
157     ENTRY_STRING ("blue"    , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE)       ANSI_ESC_END),
158     ENTRY_STRING ("purple"  , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE)     ANSI_ESC_END),
159     ENTRY_STRING ("cyan"    , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN)       ANSI_ESC_END),
160     ENTRY_STRING ("white"   , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE)      ANSI_ESC_END),
161 };
162
163 static FormatEntity::Entry::Definition g_ansi_bg_entries[] =
164 {
165     ENTRY_STRING ("black"   , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK)      ANSI_ESC_END),
166     ENTRY_STRING ("red"     , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED)        ANSI_ESC_END),
167     ENTRY_STRING ("green"   , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN)      ANSI_ESC_END),
168     ENTRY_STRING ("yellow"  , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW)     ANSI_ESC_END),
169     ENTRY_STRING ("blue"    , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE)       ANSI_ESC_END),
170     ENTRY_STRING ("purple"  , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE)     ANSI_ESC_END),
171     ENTRY_STRING ("cyan"    , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN)       ANSI_ESC_END),
172     ENTRY_STRING ("white"   , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE)      ANSI_ESC_END),
173 };
174
175 static FormatEntity::Entry::Definition g_ansi_entries[] =
176 {
177     ENTRY_CHILDREN  ( "fg"          , Invalid  , None      , g_ansi_fg_entries),
178     ENTRY_CHILDREN  ( "bg"          , Invalid  , None      , g_ansi_bg_entries),
179     ENTRY_STRING    ( "normal"      , ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL)         ANSI_ESC_END),
180     ENTRY_STRING    ( "bold"        , ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD)           ANSI_ESC_END),
181     ENTRY_STRING    ( "faint"       , ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT)          ANSI_ESC_END),
182     ENTRY_STRING    ( "italic"      , ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC)         ANSI_ESC_END),
183     ENTRY_STRING    ( "underline"   , ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE)      ANSI_ESC_END),
184     ENTRY_STRING    ( "slow-blink"  , ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK)     ANSI_ESC_END),
185     ENTRY_STRING    ( "fast-blink"  , ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK)     ANSI_ESC_END),
186     ENTRY_STRING    ( "negative"    , ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END),
187     ENTRY_STRING    ( "conceal"     , ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL)        ANSI_ESC_END),
188     ENTRY_STRING    ( "crossed-out" , ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT)    ANSI_ESC_END),
189
190 };
191
192 static FormatEntity::Entry::Definition g_script_child_entries[] =
193 {
194     ENTRY  ( "frame"   , ScriptFrame               , None),
195     ENTRY  ( "process" , ScriptProcess             , None),
196     ENTRY  ( "target"  , ScriptTarget              , None),
197     ENTRY  ( "thread"  , ScriptThread              , None),
198     ENTRY  ( "var"     , ScriptVariable            , None),
199     ENTRY  ( "svar"    , ScriptVariableSynthetic   , None),
200     ENTRY  ( "thread"  , ScriptThread              , None),
201 };
202
203 static FormatEntity::Entry::Definition g_top_level_entries[] =
204 {
205     ENTRY_CHILDREN          ("addr"                , AddressLoadOrFile      , UInt64    , g_addr_entries),
206     ENTRY                   ("addr-file-or-load"   , AddressLoadOrFile      , UInt64    ),
207     ENTRY_CHILDREN          ("ansi"                , Invalid                , None      , g_ansi_entries),
208     ENTRY                   ("current-pc-arrow"    , CurrentPCArrow         , CString   ),
209     ENTRY_CHILDREN          ("file"                , File                   , CString   , g_file_child_entries),
210     ENTRY_CHILDREN          ("frame"               , Invalid                , None      , g_frame_child_entries),
211     ENTRY_CHILDREN          ("function"            , Invalid                , None      , g_function_child_entries),
212     ENTRY_CHILDREN          ("line"                , Invalid                , None      , g_line_child_entries),
213     ENTRY_CHILDREN          ("module"              , Invalid                , None      , g_module_child_entries),
214     ENTRY_CHILDREN          ("process"             , Invalid                , None      , g_process_child_entries),
215     ENTRY_CHILDREN          ("script"              , Invalid                , None      , g_script_child_entries),
216     ENTRY_CHILDREN_KEEP_SEP ("svar"                , VariableSynthetic      , None      , g_svar_child_entries),
217     ENTRY_CHILDREN          ("thread"              , Invalid                , None      , g_thread_child_entries),
218     ENTRY_CHILDREN          ("target"              , Invalid                , None      , g_target_child_entries),
219     ENTRY_CHILDREN_KEEP_SEP ("var"                 , Variable               , None      , g_var_child_entries),
220 };
221
222 static FormatEntity::Entry::Definition g_root = ENTRY_CHILDREN ("<root>", Root, None, g_top_level_entries);
223
224
225 FormatEntity::Entry::Entry (llvm::StringRef s) :
226     string (s.data(), s.size()),
227     printf_format (),
228     children (),
229     definition (NULL),
230     type (Type::String),
231     fmt (lldb::eFormatDefault),
232     number (0),
233     deref (false)
234 {
235 }
236
237 FormatEntity::Entry::Entry (char ch) :
238     string (1, ch),
239     printf_format (),
240     children (),
241     definition (NULL),
242     type (Type::String),
243     fmt (lldb::eFormatDefault),
244     number (0),
245     deref (false)
246 {
247 }
248
249 void
250 FormatEntity::Entry::AppendChar (char ch)
251 {
252     if (children.empty() || children.back().type != Entry::Type::String)
253         children.push_back(Entry(ch));
254     else
255         children.back().string.append(1, ch);
256 }
257
258 void
259 FormatEntity::Entry::AppendText (const llvm::StringRef &s)
260 {
261     if (children.empty() || children.back().type != Entry::Type::String)
262         children.push_back(Entry(s));
263     else
264         children.back().string.append(s.data(), s.size());
265 }
266
267 void
268 FormatEntity::Entry::AppendText (const char *cstr)
269 {
270     return AppendText (llvm::StringRef(cstr));
271 }
272
273
274 Error
275 FormatEntity::Parse (const llvm::StringRef &format_str, Entry &entry)
276 {
277     entry.Clear();
278     entry.type = Entry::Type::Root;
279     llvm::StringRef modifiable_format (format_str);
280     return ParseInternal (modifiable_format, entry, 0);
281 }
282
283 #define ENUM_TO_CSTR(eee) case FormatEntity::Entry::Type::eee: return #eee
284
285 const char *
286 FormatEntity::Entry::TypeToCString (Type t)
287 {
288     switch (t)
289     {
290     ENUM_TO_CSTR(Invalid);
291     ENUM_TO_CSTR(ParentNumber);
292     ENUM_TO_CSTR(ParentString);
293     ENUM_TO_CSTR(InsertString);
294     ENUM_TO_CSTR(Root);
295     ENUM_TO_CSTR(String);
296     ENUM_TO_CSTR(Scope);
297     ENUM_TO_CSTR(Variable);
298     ENUM_TO_CSTR(VariableSynthetic);
299     ENUM_TO_CSTR(ScriptVariable);
300     ENUM_TO_CSTR(ScriptVariableSynthetic);
301     ENUM_TO_CSTR(AddressLoad);
302     ENUM_TO_CSTR(AddressFile);
303     ENUM_TO_CSTR(AddressLoadOrFile);
304     ENUM_TO_CSTR(ProcessID);
305     ENUM_TO_CSTR(ProcessFile);
306     ENUM_TO_CSTR(ScriptProcess);
307     ENUM_TO_CSTR(ThreadID);
308     ENUM_TO_CSTR(ThreadProtocolID);
309     ENUM_TO_CSTR(ThreadIndexID);
310     ENUM_TO_CSTR(ThreadName);
311     ENUM_TO_CSTR(ThreadQueue);
312     ENUM_TO_CSTR(ThreadStopReason);
313     ENUM_TO_CSTR(ThreadReturnValue);
314     ENUM_TO_CSTR(ThreadCompletedExpression);
315     ENUM_TO_CSTR(ScriptThread);
316     ENUM_TO_CSTR(ThreadInfo);
317     ENUM_TO_CSTR(TargetArch);
318     ENUM_TO_CSTR(ScriptTarget);
319     ENUM_TO_CSTR(ModuleFile);
320     ENUM_TO_CSTR(File);
321     ENUM_TO_CSTR(FrameIndex);
322     ENUM_TO_CSTR(FrameRegisterPC);
323     ENUM_TO_CSTR(FrameRegisterSP);
324     ENUM_TO_CSTR(FrameRegisterFP);
325     ENUM_TO_CSTR(FrameRegisterFlags);
326     ENUM_TO_CSTR(FrameRegisterByName);
327     ENUM_TO_CSTR(ScriptFrame);
328     ENUM_TO_CSTR(FunctionID);
329     ENUM_TO_CSTR(FunctionDidChange);
330     ENUM_TO_CSTR(FunctionInitialFunction);
331     ENUM_TO_CSTR(FunctionName);
332     ENUM_TO_CSTR(FunctionNameWithArgs);
333     ENUM_TO_CSTR(FunctionNameNoArgs);
334     ENUM_TO_CSTR(FunctionAddrOffset);
335     ENUM_TO_CSTR(FunctionAddrOffsetConcrete);
336     ENUM_TO_CSTR(FunctionLineOffset);
337     ENUM_TO_CSTR(FunctionPCOffset);
338     ENUM_TO_CSTR(LineEntryFile);
339     ENUM_TO_CSTR(LineEntryLineNumber);
340     ENUM_TO_CSTR(LineEntryStartAddress);
341     ENUM_TO_CSTR(LineEntryEndAddress);
342     ENUM_TO_CSTR(CurrentPCArrow);
343     }
344     return "???";
345 }
346
347 #undef ENUM_TO_CSTR
348
349 void
350 FormatEntity::Entry::Dump (Stream &s, int depth) const
351 {
352     s.Printf ("%*.*s%-20s: ", depth * 2, depth * 2, "", TypeToCString(type));
353     if (fmt != eFormatDefault)
354         s.Printf ("lldb-format = %s, ", FormatManager::GetFormatAsCString (fmt));
355     if (!string.empty())
356         s.Printf ("string = \"%s\"", string.c_str());
357     if (!printf_format.empty())
358         s.Printf ("printf_format = \"%s\"", printf_format.c_str());
359     if (number != 0)
360         s.Printf ("number = %" PRIu64 " (0x%" PRIx64 "), ", number, number);
361     if (deref)
362         s.Printf ("deref = true, ");
363     s.EOL();
364     for (const auto &child : children)
365     {
366         child.Dump(s, depth + 1);
367     }
368 }
369
370
371 template <typename T>
372 static bool RunScriptFormatKeyword(Stream &s,
373                                    const SymbolContext *sc,
374                                    const ExecutionContext *exe_ctx,
375                                    T t,
376                                    const char *script_function_name)
377 {
378     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
379
380     if (target)
381     {
382         ScriptInterpreter *script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
383         if (script_interpreter)
384         {
385             Error error;
386             std::string script_output;
387
388             if (script_interpreter->RunScriptFormatKeyword(script_function_name, t, script_output, error) && error.Success())
389             {
390                 s.Printf("%s", script_output.c_str());
391                 return true;
392             }
393             else
394             {
395                 s.Printf("<error: %s>",error.AsCString());
396             }
397         }
398     }
399     return false;
400 }
401
402 static bool
403 DumpAddress (Stream &s,
404              const SymbolContext *sc,
405              const ExecutionContext *exe_ctx,
406              const Address &addr,
407              bool print_file_addr_or_load_addr)
408 {
409     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
410     addr_t vaddr = LLDB_INVALID_ADDRESS;
411     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
412         vaddr = addr.GetLoadAddress (target);
413     if (vaddr == LLDB_INVALID_ADDRESS)
414         vaddr = addr.GetFileAddress ();
415
416     if (vaddr != LLDB_INVALID_ADDRESS)
417     {
418         int addr_width = 0;
419         if (exe_ctx && target)
420         {
421             addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
422         }
423         if (addr_width == 0)
424             addr_width = 16;
425         if (print_file_addr_or_load_addr)
426         {
427             ExecutionContextScope *exe_scope = NULL;
428             if (exe_ctx)
429                 exe_scope = exe_ctx->GetBestExecutionContextScope();
430             addr.Dump (&s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
431         }
432         else
433         {
434             s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
435         }
436         return true;
437     }
438     return false;
439 }
440
441 static bool
442 DumpAddressOffsetFromFunction (Stream &s,
443                                const SymbolContext *sc,
444                                const ExecutionContext *exe_ctx,
445                                const Address &format_addr,
446                                bool concrete_only,
447                                bool no_padding)
448 {
449     if (format_addr.IsValid())
450     {
451         Address func_addr;
452         
453         if (sc)
454         {
455             if (sc->function)
456             {
457                 func_addr = sc->function->GetAddressRange().GetBaseAddress();
458                 if (sc->block && !concrete_only)
459                 {
460                     // Check to make sure we aren't in an inline
461                     // function. If we are, use the inline block
462                     // range that contains "format_addr" since
463                     // blocks can be discontiguous.
464                     Block *inline_block = sc->block->GetContainingInlinedBlock ();
465                     AddressRange inline_range;
466                     if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
467                         func_addr = inline_range.GetBaseAddress();
468                 }
469             }
470             else if (sc->symbol && sc->symbol->ValueIsAddress())
471                 func_addr = sc->symbol->GetAddress();
472         }
473
474         if (func_addr.IsValid())
475         {
476             const char *addr_offset_padding = no_padding ? "" : " ";
477
478             if (func_addr.GetSection() == format_addr.GetSection())
479             {
480                 addr_t func_file_addr = func_addr.GetFileAddress();
481                 addr_t addr_file_addr = format_addr.GetFileAddress();
482                 if (addr_file_addr > func_file_addr)
483                     s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
484                 else if (addr_file_addr < func_file_addr)
485                     s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
486                 return true;
487             }
488             else
489             {
490                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
491                 if (target)
492                 {
493                     addr_t func_load_addr = func_addr.GetLoadAddress (target);
494                     addr_t addr_load_addr = format_addr.GetLoadAddress (target);
495                     if (addr_load_addr > func_load_addr)
496                         s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
497                     else if (addr_load_addr < func_load_addr)
498                         s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
499                     return true;
500                 }
501             }
502         }
503     }
504     return false;
505 }
506
507 static bool
508 ScanBracketedRange (llvm::StringRef subpath,
509                     size_t& close_bracket_index,
510                     const char*& var_name_final_if_array_range,
511                     int64_t& index_lower,
512                     int64_t& index_higher)
513 {
514     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
515     close_bracket_index = llvm::StringRef::npos;
516     const size_t open_bracket_index = subpath.find('[');
517     if (open_bracket_index == llvm::StringRef::npos)
518     {
519         if (log)
520             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
521         return false;
522     }
523
524     close_bracket_index = subpath.find(']', open_bracket_index + 1);
525
526     if (close_bracket_index == llvm::StringRef::npos)
527     {
528         if (log)
529             log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
530         return false;
531     }
532     else
533     {
534         var_name_final_if_array_range = subpath.data() + open_bracket_index;
535
536         if (close_bracket_index - open_bracket_index == 1)
537         {
538             if (log)
539                 log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
540             index_lower = 0;
541         }
542         else
543         {
544             const size_t separator_index = subpath.find('-', open_bracket_index + 1);
545
546             if (separator_index == llvm::StringRef::npos)
547             {
548                 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
549                 index_lower = ::strtoul (index_lower_cstr, NULL, 0);
550                 index_higher = index_lower;
551                 if (log)
552                     log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", index_lower);
553             }
554             else
555             {
556                 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
557                 const char *index_higher_cstr = subpath.data() + separator_index + 1;
558                 index_lower = ::strtoul (index_lower_cstr, NULL, 0);
559                 index_higher = ::strtoul (index_higher_cstr, NULL, 0);
560                 if (log)
561                     log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", index_lower, index_higher);
562             }
563             if (index_lower > index_higher && index_higher > 0)
564             {
565                 if (log)
566                     log->Printf("[ScanBracketedRange] swapping indices");
567                 const int64_t temp = index_lower;
568                 index_lower = index_higher;
569                 index_higher = temp;
570             }
571         }
572     }
573     return true;
574 }
575
576 static bool
577 DumpFile (Stream &s, const FileSpec &file, FileKind file_kind)
578 {
579     switch (file_kind)
580     {
581     case FileKind::FileError:
582         break;
583
584     case FileKind::Basename:
585         if (file.GetFilename())
586         {
587             s << file.GetFilename();
588             return true;
589         }
590         break;
591
592     case FileKind::Dirname:
593         if (file.GetDirectory())
594         {
595             s << file.GetDirectory();
596             return true;
597         }
598         break;
599
600     case FileKind::Fullpath:
601         if (file)
602         {
603             s << file;
604             return true;
605         }
606         break;
607     }
608     return false;
609 }
610
611 static bool
612 DumpRegister (Stream &s,
613               StackFrame *frame,
614               RegisterKind reg_kind,
615               uint32_t reg_num,
616               Format format)
617
618 {
619     if (frame)
620     {
621         RegisterContext *reg_ctx = frame->GetRegisterContext().get();
622
623         if (reg_ctx)
624         {
625             const uint32_t lldb_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
626             if (lldb_reg_num != LLDB_INVALID_REGNUM)
627             {
628                 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (lldb_reg_num);
629                 if (reg_info)
630                 {
631                     RegisterValue reg_value;
632                     if (reg_ctx->ReadRegister (reg_info, reg_value))
633                     {
634                         reg_value.Dump(&s, reg_info, false, false, format);
635                         return true;
636                     }
637                 }
638             }
639         }
640     }
641     return false;
642 }
643
644
645 static ValueObjectSP
646 ExpandIndexedExpression (ValueObject* valobj,
647                          size_t index,
648                          StackFrame* frame,
649                          bool deref_pointer)
650 {
651     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
652     const char* ptr_deref_format = "[%d]";
653     std::string ptr_deref_buffer(10,0);
654     ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
655     if (log)
656         log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
657     const char* first_unparsed;
658     ValueObject::GetValueForExpressionPathOptions options;
659     ValueObject::ExpressionPathEndResultType final_value_type;
660     ValueObject::ExpressionPathScanEndReason reason_to_stop;
661     ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
662     ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
663                                                             &first_unparsed,
664                                                             &reason_to_stop,
665                                                             &final_value_type,
666                                                             options,
667                                                             &what_next);
668     if (!item)
669     {
670         if (log)
671             log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
672                         " final_value_type %d",
673                         first_unparsed, reason_to_stop, final_value_type);
674     }
675     else
676     {
677         if (log)
678             log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
679                         " final_value_type %d",
680                         first_unparsed, reason_to_stop, final_value_type);
681     }
682     return item;
683 }
684
685 static char
686 ConvertValueObjectStyleToChar(ValueObject::ValueObjectRepresentationStyle style)
687 {
688     switch (style)
689     {
690         case ValueObject::eValueObjectRepresentationStyleLanguageSpecific:  return '@';
691         case ValueObject::eValueObjectRepresentationStyleValue:             return 'V';
692         case ValueObject::eValueObjectRepresentationStyleLocation:          return 'L';
693         case ValueObject::eValueObjectRepresentationStyleSummary:           return 'S';
694         case ValueObject::eValueObjectRepresentationStyleChildrenCount:     return '#';
695         case ValueObject::eValueObjectRepresentationStyleType:              return 'T';
696         case ValueObject::eValueObjectRepresentationStyleName:              return 'N';
697         case ValueObject::eValueObjectRepresentationStyleExpressionPath:    return '>';
698     }
699     return '\0';
700 }
701
702 static bool
703 DumpValue (Stream &s,
704            const SymbolContext *sc,
705            const ExecutionContext *exe_ctx,
706            const FormatEntity::Entry &entry,
707            ValueObject *valobj)
708 {
709     if (valobj == NULL)
710         return false;
711
712     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
713     Format custom_format = eFormatInvalid;
714     ValueObject::ValueObjectRepresentationStyle val_obj_display = entry.string.empty() ? ValueObject::eValueObjectRepresentationStyleValue : ValueObject::eValueObjectRepresentationStyleSummary;
715
716     bool do_deref_pointer = entry.deref;
717     bool is_script = false;
718     switch (entry.type)
719     {
720         case FormatEntity::Entry::Type::ScriptVariable:
721             is_script = true;
722             break;
723
724         case FormatEntity::Entry::Type::Variable:
725             custom_format = entry.fmt;
726             val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
727             break;
728
729         case FormatEntity::Entry::Type::ScriptVariableSynthetic:
730             is_script = true;
731             // Fall through
732         case FormatEntity::Entry::Type::VariableSynthetic:
733             custom_format = entry.fmt;
734             val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
735             if (!valobj->IsSynthetic())
736             {
737                 valobj = valobj->GetSyntheticValue().get();
738                 if (valobj == nullptr)
739                     return false;
740             }
741             break;
742
743         default:
744             return false;
745     }
746
747     if (valobj == NULL)
748         return false;
749
750     ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
751                                                       ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
752     ValueObject::GetValueForExpressionPathOptions options;
753     options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
754     ValueObject* target = NULL;
755     const char* var_name_final_if_array_range = NULL;
756     size_t close_bracket_index = llvm::StringRef::npos;
757     int64_t index_lower = -1;
758     int64_t index_higher = -1;
759     bool is_array_range = false;
760     const char* first_unparsed;
761     bool was_plain_var = false;
762     bool was_var_format = false;
763     bool was_var_indexed = false;
764     ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
765     ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
766
767     if (is_script)
768     {
769         return RunScriptFormatKeyword (s, sc, exe_ctx, valobj, entry.string.c_str());
770     }
771
772     llvm::StringRef subpath (entry.string);
773     // simplest case ${var}, just print valobj's value
774     if (entry.string.empty())
775     {
776         if (entry.printf_format.empty() && entry.fmt == eFormatDefault && entry.number == ValueObject::eValueObjectRepresentationStyleValue)
777             was_plain_var = true;
778         else
779             was_var_format = true;
780         target = valobj;
781     }
782     else    // this is ${var.something} or multiple .something nested
783     {
784         if (entry.string[0] == '[')
785             was_var_indexed = true;
786         ScanBracketedRange (subpath,
787                             close_bracket_index,
788                             var_name_final_if_array_range,
789                             index_lower,
790                             index_higher);
791
792         Error error;
793
794         const std::string &expr_path = entry.string;
795
796         if (log)
797             log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
798
799         target = valobj->GetValueForExpressionPath(expr_path.c_str(),
800                                                    &first_unparsed,
801                                                    &reason_to_stop,
802                                                    &final_value_type,
803                                                    options,
804                                                    &what_next).get();
805
806         if (!target)
807         {
808             if (log)
809                 log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
810                             " final_value_type %d",
811                             first_unparsed, reason_to_stop, final_value_type);
812             return false;
813         }
814         else
815         {
816             if (log)
817                 log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
818                             " final_value_type %d",
819                             first_unparsed, reason_to_stop, final_value_type);
820             target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get();
821         }
822     }
823
824
825     is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
826                       final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
827
828     do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
829
830     if (do_deref_pointer && !is_array_range)
831     {
832         // I have not deref-ed yet, let's do it
833         // this happens when we are not going through GetValueForVariableExpressionPath
834         // to get to the target ValueObject
835         Error error;
836         target = target->Dereference(error).get();
837         if (error.Fail())
838         {
839             if (log)
840                 log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
841             return false;
842         }
843         do_deref_pointer = false;
844     }
845
846     if (!target)
847     {
848         if (log)
849             log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
850         return false;
851     }
852
853     // we do not want to use the summary for a bitfield of type T:n
854     // if we were originally dealing with just a T - that would get
855     // us into an endless recursion
856     if (target->IsBitfield() && was_var_indexed)
857     {
858         // TODO: check for a (T:n)-specific summary - we should still obey that
859         StreamString bitfield_name;
860         bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
861         lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
862         if (val_obj_display == ValueObject::eValueObjectRepresentationStyleSummary && !DataVisualization::GetSummaryForType(type_sp))
863             val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
864     }
865
866     // TODO use flags for these
867     const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
868     bool is_array = (type_info_flags & eTypeIsArray) != 0;
869     bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
870     bool is_aggregate = target->GetClangType().IsAggregateType();
871
872     if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
873     {
874         StreamString str_temp;
875         if (log)
876             log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
877
878         if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
879         {
880             // try to use the special cases
881             bool success = target->DumpPrintableRepresentation(str_temp,
882                                                                val_obj_display,
883                                                                custom_format);
884             if (log)
885                 log->Printf("[Debugger::FormatPrompt] special cases did%s match", success ? "" : "n't");
886
887             // should not happen
888             if (success)
889                 s << str_temp.GetData();
890             return true;
891         }
892         else
893         {
894             if (was_plain_var) // if ${var}
895             {
896                 s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
897             }
898             else if (is_pointer) // if pointer, value is the address stored
899             {
900                 target->DumpPrintableRepresentation (s,
901                                                      val_obj_display,
902                                                      custom_format,
903                                                      ValueObject::ePrintableRepresentationSpecialCasesDisable);
904             }
905             return true;
906         }
907     }
908
909     // if directly trying to print ${var}, and this is an aggregate, display a nice
910     // type @ location message
911     if (is_aggregate && was_plain_var)
912     {
913         s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
914         return true;
915     }
916
917     // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
918     if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
919     {
920         s << "<invalid use of aggregate type>";
921         return true;
922     }
923
924     if (!is_array_range)
925     {
926         if (log)
927             log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
928         return target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
929     }
930     else
931     {
932         if (log)
933             log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
934         if (!is_array && !is_pointer)
935             return false;
936         if (log)
937             log->Printf("[Debugger::FormatPrompt] handle as array");
938         llvm::StringRef special_directions;
939         if (close_bracket_index != llvm::StringRef::npos && subpath.size() > close_bracket_index)
940         {
941             ConstString additional_data (subpath.drop_front(close_bracket_index+1));
942             StreamString special_directions_stream;
943             special_directions_stream.Printf("${%svar%s",
944                                              do_deref_pointer ? "*" : "",
945                                              additional_data.GetCString());
946
947             if (entry.fmt != eFormatDefault)
948             {
949                 const char format_char = FormatManager::GetFormatAsFormatChar(entry.fmt);
950                 if (format_char != '\0')
951                     special_directions_stream.Printf("%%%c", format_char);
952                 else
953                 {
954                     const char *format_cstr = FormatManager::GetFormatAsCString(entry.fmt);
955                     special_directions_stream.Printf("%%%s", format_cstr);
956                 }
957             }
958             else if (entry.number != 0)
959             {
960                 const char style_char = ConvertValueObjectStyleToChar ((ValueObject::ValueObjectRepresentationStyle)entry.number);
961                 if (style_char)
962                     special_directions_stream.Printf("%%%c", style_char);
963             }
964             special_directions_stream.PutChar('}');
965             special_directions = llvm::StringRef(special_directions_stream.GetString());
966         }
967
968         // let us display items index_lower thru index_higher of this array
969         s.PutChar('[');
970
971         if (index_higher < 0)
972             index_higher = valobj->GetNumChildren() - 1;
973
974         uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
975
976         bool success = true;
977         for (int64_t index = index_lower;index<=index_higher; ++index)
978         {
979             ValueObject* item = ExpandIndexedExpression (target,
980                                                          index,
981                                                          exe_ctx->GetFramePtr(),
982                                                          false).get();
983
984             if (!item)
985             {
986                 if (log)
987                     log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index);
988             }
989             else
990             {
991                 if (log)
992                     log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions.data() ? special_directions.data() : "");
993             }
994
995             if (special_directions.empty())
996             {
997                 success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
998             }
999             else
1000             {
1001                 success &= FormatEntity::FormatStringRef(special_directions, s, sc, exe_ctx, NULL, item, false, false);
1002             }
1003
1004             if (--max_num_children == 0)
1005             {
1006                 s.PutCString(", ...");
1007                 break;
1008             }
1009
1010             if (index < index_higher)
1011                 s.PutChar(',');
1012         }
1013         s.PutChar(']');
1014         return success;
1015     }
1016
1017 }
1018
1019 static bool
1020 DumpRegister (Stream &s,
1021               StackFrame *frame,
1022               const char *reg_name,
1023               Format format)
1024
1025 {
1026     if (frame)
1027     {
1028         RegisterContext *reg_ctx = frame->GetRegisterContext().get();
1029
1030         if (reg_ctx)
1031         {
1032             const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
1033             if (reg_info)
1034             {
1035                 RegisterValue reg_value;
1036                 if (reg_ctx->ReadRegister (reg_info, reg_value))
1037                 {
1038                     reg_value.Dump(&s, reg_info, false, false, format);
1039                     return true;
1040                 }
1041             }
1042         }
1043     }
1044     return false;
1045 }
1046
1047 static bool
1048 FormatThreadExtendedInfoRecurse(const FormatEntity::Entry &entry,
1049                                 const StructuredData::ObjectSP &thread_info_dictionary,
1050                                 const SymbolContext *sc,
1051                                 const ExecutionContext *exe_ctx,
1052                                 Stream &s)
1053 {
1054     llvm::StringRef path(entry.string);
1055
1056     StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
1057
1058     if (value.get())
1059     {
1060         if (value->GetType() == StructuredData::Type::eTypeInteger)
1061         {
1062             const char *token_format = "0x%4.4" PRIx64;
1063             if (!entry.printf_format.empty())
1064                 token_format = entry.printf_format.c_str();
1065             s.Printf(token_format, value->GetAsInteger()->GetValue());
1066             return true;
1067         }
1068         else if (value->GetType() == StructuredData::Type::eTypeFloat)
1069         {
1070             s.Printf ("%f", value->GetAsFloat()->GetValue());
1071             return true;
1072         }
1073         else if (value->GetType() == StructuredData::Type::eTypeString)
1074         {
1075             s.Printf("%s", value->GetAsString()->GetValue().c_str());
1076             return true;
1077         }
1078         else if (value->GetType() == StructuredData::Type::eTypeArray)
1079         {
1080             if (value->GetAsArray()->GetSize() > 0)
1081             {
1082                 s.Printf ("%zu", value->GetAsArray()->GetSize());
1083                 return true;
1084             }
1085         }
1086         else if (value->GetType() == StructuredData::Type::eTypeDictionary)
1087         {
1088             s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1089             return true;
1090         }
1091     }
1092
1093     return false;
1094 }
1095
1096
1097 static inline bool
1098 IsToken(const char *var_name_begin, const char *var)
1099 {
1100     return (::strncmp (var_name_begin, var, strlen(var)) == 0);
1101 }
1102
1103 bool
1104 FormatEntity::FormatStringRef (const llvm::StringRef &format_str,
1105                                Stream &s,
1106                                const SymbolContext *sc,
1107                                const ExecutionContext *exe_ctx,
1108                                const Address *addr,
1109                                ValueObject* valobj,
1110                                bool function_changed,
1111                                bool initial_function)
1112 {
1113     if (!format_str.empty())
1114     {
1115         FormatEntity::Entry root;
1116         Error error = FormatEntity::Parse(format_str, root);
1117         if (error.Success())
1118         {
1119             return FormatEntity::Format (root,
1120                                          s,
1121                                          sc,
1122                                          exe_ctx,
1123                                          addr,
1124                                          valobj,
1125                                          function_changed,
1126                                          initial_function);
1127         }
1128     }
1129     return false;
1130
1131 }
1132 bool
1133 FormatEntity::FormatCString (const char *format,
1134                              Stream &s,
1135                              const SymbolContext *sc,
1136                              const ExecutionContext *exe_ctx,
1137                              const Address *addr,
1138                              ValueObject* valobj,
1139                              bool function_changed,
1140                              bool initial_function)
1141 {
1142     if (format && format[0])
1143     {
1144         FormatEntity::Entry root;
1145         llvm::StringRef format_str(format);
1146         Error error = FormatEntity::Parse(format_str, root);
1147         if (error.Success())
1148         {
1149             return FormatEntity::Format (root,
1150                                          s,
1151                                          sc,
1152                                          exe_ctx,
1153                                          addr,
1154                                          valobj,
1155                                          function_changed,
1156                                          initial_function);
1157         }
1158     }
1159     return false;
1160 }
1161
1162 bool
1163 FormatEntity::Format (const Entry &entry,
1164                       Stream &s,
1165                       const SymbolContext *sc,
1166                       const ExecutionContext *exe_ctx,
1167                       const Address *addr,
1168                       ValueObject* valobj,
1169                       bool function_changed,
1170                       bool initial_function)
1171 {
1172     switch (entry.type)
1173     {
1174         case Entry::Type::Invalid:
1175         case Entry::Type::ParentNumber: // Only used for FormatEntity::Entry::Definition encoding
1176         case Entry::Type::ParentString: // Only used for FormatEntity::Entry::Definition encoding
1177         case Entry::Type::InsertString: // Only used for FormatEntity::Entry::Definition encoding
1178             return false;
1179
1180         case Entry::Type::Root:
1181             for (const auto &child : entry.children)
1182             {
1183                 if (Format (child,
1184                             s,
1185                             sc,
1186                             exe_ctx,
1187                             addr,
1188                             valobj,
1189                             function_changed,
1190                             initial_function) == false)
1191                 {
1192                     return false; // If any item of root fails, then the formatting fails
1193                 }
1194             }
1195             return true; // Only return true if all items succeeded
1196
1197         case Entry::Type::String:
1198             s.PutCString(entry.string.c_str());
1199             return true;
1200
1201         case Entry::Type::Scope:
1202             {
1203                 StreamString scope_stream;
1204                 bool success = false;
1205                 for (const auto &child : entry.children)
1206                 {
1207                     success = Format (child, scope_stream, sc, exe_ctx, addr, valobj, function_changed, initial_function);
1208                     if (!success)
1209                         break;
1210                 }
1211                 // Only if all items in a scope succeed, then do we
1212                 // print the output into the main stream
1213                 if (success)
1214                     s.Write(scope_stream.GetString().data(), scope_stream.GetString().size());
1215             }
1216             return true; // Scopes always successfully print themselves
1217
1218         case Entry::Type::Variable:
1219         case Entry::Type::VariableSynthetic:
1220         case Entry::Type::ScriptVariable:
1221         case Entry::Type::ScriptVariableSynthetic:
1222             if (DumpValue(s, sc, exe_ctx, entry, valobj))
1223                 return true;
1224             return false;
1225
1226         case Entry::Type::AddressFile:
1227         case Entry::Type::AddressLoad:
1228         case Entry::Type::AddressLoadOrFile:
1229             if (addr && addr->IsValid() && DumpAddress(s, sc, exe_ctx, *addr, entry.type == Entry::Type::AddressLoadOrFile))
1230                 return true;
1231             return false;
1232
1233         case Entry::Type::ProcessID:
1234             if (exe_ctx)
1235             {
1236                 Process *process = exe_ctx->GetProcessPtr();
1237                 if (process)
1238                 {
1239                     const char *format = "%" PRIu64;
1240                     if (!entry.printf_format.empty())
1241                         format = entry.printf_format.c_str();
1242                     s.Printf(format, process->GetID());
1243                     return true;
1244                 }
1245             }
1246             return false;
1247
1248         case Entry::Type::ProcessFile:
1249             if (exe_ctx)
1250             {
1251                 Process *process = exe_ctx->GetProcessPtr();
1252                 if (process)
1253                 {
1254                     Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1255                     if (exe_module)
1256                     {
1257                         if (DumpFile(s, exe_module->GetFileSpec(), (FileKind)entry.number))
1258                             return true;
1259                     }
1260                 }
1261             }
1262             return false;
1263
1264         case Entry::Type::ScriptProcess:
1265             if (exe_ctx)
1266             {
1267                 Process *process = exe_ctx->GetProcessPtr();
1268                 if (process)
1269                     return RunScriptFormatKeyword (s, sc, exe_ctx, process, entry.string.c_str());
1270             }
1271             return false;
1272
1273
1274         case Entry::Type::ThreadID:
1275             if (exe_ctx)
1276             {
1277                 Thread *thread = exe_ctx->GetThreadPtr();
1278                 if (thread)
1279                 {
1280                     const char *format = "0x%4.4" PRIx64;
1281                     if (!entry.printf_format.empty())
1282                     {
1283                         // Watch for the special "tid" format...
1284                         if (entry.printf_format == "tid")
1285                         {
1286                             bool handled = false;
1287                             Target &target = thread->GetProcess()->GetTarget();
1288                             ArchSpec arch (target.GetArchitecture ());
1289                             llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
1290                             if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
1291                             {
1292                                 handled = true;
1293                                 format = "%" PRIu64;
1294                             }
1295                         }
1296                         else
1297                         {
1298                             format = entry.printf_format.c_str();
1299                         }
1300                     }
1301                     s.Printf(format, thread->GetID());
1302                     return true;
1303                 }
1304             }
1305             return false;
1306
1307         case Entry::Type::ThreadProtocolID:
1308             if (exe_ctx)
1309             {
1310                 Thread *thread = exe_ctx->GetThreadPtr();
1311                 if (thread)
1312                 {
1313                     const char *format = "0x%4.4" PRIx64;
1314                     if (!entry.printf_format.empty())
1315                         format = entry.printf_format.c_str();
1316                     s.Printf(format, thread->GetProtocolID());
1317                     return true;
1318                 }
1319             }
1320             return false;
1321
1322         case Entry::Type::ThreadIndexID:
1323             if (exe_ctx)
1324             {
1325                 Thread *thread = exe_ctx->GetThreadPtr();
1326                 if (thread)
1327                 {
1328                     const char *format = "%" PRIu32;
1329                     if (!entry.printf_format.empty())
1330                         format = entry.printf_format.c_str();
1331                     s.Printf(format, thread->GetIndexID());
1332                     return true;
1333                 }
1334             }
1335             return false;
1336
1337         case Entry::Type::ThreadName:
1338             if (exe_ctx)
1339             {
1340                 Thread *thread = exe_ctx->GetThreadPtr();
1341                 if (thread)
1342                 {
1343                     const char *cstr = thread->GetName();
1344                     if (cstr && cstr[0])
1345                     {
1346                         s.PutCString(cstr);
1347                         return true;
1348                     }
1349                 }
1350             }
1351             return false;
1352
1353         case Entry::Type::ThreadQueue:
1354             if (exe_ctx)
1355             {
1356                 Thread *thread = exe_ctx->GetThreadPtr();
1357                 if (thread)
1358                 {
1359                     const char *cstr = thread->GetQueueName();
1360                     if (cstr && cstr[0])
1361                     {
1362                         s.PutCString(cstr);
1363                         return true;
1364                     }
1365                 }
1366             }
1367             return false;
1368
1369         case Entry::Type::ThreadStopReason:
1370             if (exe_ctx)
1371             {
1372                 Thread *thread = exe_ctx->GetThreadPtr();
1373                 if (thread)
1374                 {
1375                     StopInfoSP stop_info_sp = thread->GetStopInfo ();
1376                     if (stop_info_sp && stop_info_sp->IsValid())
1377                     {
1378                         const char *cstr = stop_info_sp->GetDescription();
1379                         if (cstr && cstr[0])
1380                         {
1381                             s.PutCString(cstr);
1382                             return true;
1383                         }
1384                     }
1385                 }
1386             }
1387             return false;
1388
1389         case Entry::Type::ThreadReturnValue:
1390             if (exe_ctx)
1391             {
1392                 Thread *thread = exe_ctx->GetThreadPtr();
1393                 if (thread)
1394                 {
1395                     StopInfoSP stop_info_sp = thread->GetStopInfo ();
1396                     if (stop_info_sp && stop_info_sp->IsValid())
1397                     {
1398                         ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
1399                         if (return_valobj_sp)
1400                         {
1401                             return_valobj_sp->Dump(s);
1402                             return true;
1403                         }
1404                     }
1405                 }
1406             }
1407             return false;
1408
1409         case Entry::Type::ThreadCompletedExpression:
1410             if (exe_ctx)
1411             {
1412                 Thread *thread = exe_ctx->GetThreadPtr();
1413                 if (thread)
1414                 {
1415                     StopInfoSP stop_info_sp = thread->GetStopInfo ();
1416                     if (stop_info_sp && stop_info_sp->IsValid())
1417                     {
1418                         ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
1419                         if (expression_var_sp && expression_var_sp->GetValueObject())
1420                         {
1421                             expression_var_sp->GetValueObject()->Dump(s);
1422                             return true;
1423                         }
1424                     }
1425                 }
1426             }
1427             return false;
1428
1429         case Entry::Type::ScriptThread:
1430             if (exe_ctx)
1431             {
1432                 Thread *thread = exe_ctx->GetThreadPtr();
1433                 if (thread)
1434                     return RunScriptFormatKeyword (s, sc, exe_ctx, thread, entry.string.c_str());
1435             }
1436             return false;
1437
1438         case Entry::Type::ThreadInfo:
1439             if (exe_ctx)
1440             {
1441                 Thread *thread = exe_ctx->GetThreadPtr();
1442                 if (thread)
1443                 {
1444                     StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
1445                     if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
1446                     {
1447                         if (FormatThreadExtendedInfoRecurse (entry, object_sp, sc, exe_ctx, s))
1448                             return true;
1449                     }
1450                 }
1451             }
1452             return false;
1453
1454         case Entry::Type::TargetArch:
1455             if (exe_ctx)
1456             {
1457                 Target *target = exe_ctx->GetTargetPtr();
1458                 if (target)
1459                 {
1460                     const ArchSpec &arch = target->GetArchitecture ();
1461                     if (arch.IsValid())
1462                     {
1463                         s.PutCString (arch.GetArchitectureName());
1464                         return true;
1465                     }
1466                 }
1467             }
1468             return false;
1469
1470         case Entry::Type::ScriptTarget:
1471             if (exe_ctx)
1472             {
1473                 Target *target = exe_ctx->GetTargetPtr();
1474                 if (target)
1475                     return RunScriptFormatKeyword (s, sc, exe_ctx, target, entry.string.c_str());
1476             }
1477             return false;
1478
1479         case Entry::Type::ModuleFile:
1480             if (sc)
1481             {
1482                 Module *module = sc->module_sp.get();
1483                 if (module)
1484                 {
1485                     if (DumpFile(s, module->GetFileSpec(), (FileKind)entry.number))
1486                         return true;
1487                 }
1488             }
1489             return false;
1490
1491         case Entry::Type::File:
1492             if (sc)
1493             {
1494                 CompileUnit *cu = sc->comp_unit;
1495                 if (cu)
1496                 {
1497                     // CompileUnit is a FileSpec
1498                     if (DumpFile(s, *cu, (FileKind)entry.number))
1499                         return true;
1500                 }
1501             }
1502             return false;
1503
1504         case Entry::Type::FrameIndex:
1505             if (exe_ctx)
1506             {
1507                 StackFrame *frame = exe_ctx->GetFramePtr();
1508                 if (frame)
1509                 {
1510                     const char *format = "%" PRIu32;
1511                     if (!entry.printf_format.empty())
1512                         format = entry.printf_format.c_str();
1513                     s.Printf(format, frame->GetFrameIndex());
1514                     return true;
1515                 }
1516             }
1517             return false;
1518
1519         case Entry::Type::FrameRegisterPC:
1520             if (exe_ctx)
1521             {
1522                 StackFrame *frame = exe_ctx->GetFramePtr();
1523                 if (frame)
1524                 {
1525                     const Address &pc_addr = frame->GetFrameCodeAddress();
1526                     if (pc_addr.IsValid())
1527                     {
1528                         if (DumpAddress(s, sc, exe_ctx, pc_addr, false))
1529                             return true;
1530                     }
1531                 }
1532             }
1533             return false;
1534
1535         case Entry::Type::FrameRegisterSP:
1536             if (exe_ctx)
1537             {
1538                 StackFrame *frame = exe_ctx->GetFramePtr();
1539                 if (frame)
1540                 {
1541                     if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, (lldb::Format)entry.number))
1542                         return true;
1543                 }
1544             }
1545             return false;
1546
1547         case Entry::Type::FrameRegisterFP:
1548             if (exe_ctx)
1549             {
1550                 StackFrame *frame = exe_ctx->GetFramePtr();
1551                 if (frame)
1552                 {
1553                     if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, (lldb::Format)entry.number))
1554                         return true;
1555                 }
1556             }
1557             return false;
1558
1559         case Entry::Type::FrameRegisterFlags:
1560             if (exe_ctx)
1561             {
1562                 StackFrame *frame = exe_ctx->GetFramePtr();
1563                 if (frame)
1564                 {
1565                     if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, (lldb::Format)entry.number))
1566                         return true;
1567                 }
1568             }
1569             return false;
1570
1571
1572         case Entry::Type::FrameRegisterByName:
1573             if (exe_ctx)
1574             {
1575                 StackFrame *frame = exe_ctx->GetFramePtr();
1576                 if (frame)
1577                 {
1578                     if (DumpRegister (s, frame, entry.string.c_str(), (lldb::Format)entry.number))
1579                         return true;
1580                 }
1581             }
1582             return false;
1583
1584         case Entry::Type::ScriptFrame:
1585             if (exe_ctx)
1586             {
1587                 StackFrame *frame = exe_ctx->GetFramePtr();
1588                 if (frame)
1589                     return RunScriptFormatKeyword (s, sc, exe_ctx, frame, entry.string.c_str());
1590             }
1591             return false;
1592
1593         case Entry::Type::FunctionID:
1594             if (sc)
1595             {
1596                 if (sc->function)
1597                 {
1598                     s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
1599                     return true;
1600                 }
1601                 else if (sc->symbol)
1602                 {
1603                     s.Printf("symbol[%u]", sc->symbol->GetID());
1604                     return true;
1605                 }
1606             }
1607             return false;
1608
1609         case Entry::Type::FunctionDidChange:
1610             return function_changed;
1611
1612         case Entry::Type::FunctionInitialFunction:
1613             return initial_function;
1614
1615         case Entry::Type::FunctionName:
1616             {
1617                 const char *name = NULL;
1618                 if (sc->function)
1619                     name = sc->function->GetName().AsCString (NULL);
1620                 else if (sc->symbol)
1621                     name = sc->symbol->GetName().AsCString (NULL);
1622                 if (name)
1623                 {
1624                     s.PutCString(name);
1625
1626                     if (sc->block)
1627                     {
1628                         Block *inline_block = sc->block->GetContainingInlinedBlock ();
1629                         if (inline_block)
1630                         {
1631                             const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
1632                             if (inline_info)
1633                             {
1634                                 s.PutCString(" [inlined] ");
1635                                 inline_info->GetName().Dump(&s);
1636                             }
1637                         }
1638                     }
1639                     return true;
1640                 }
1641             }
1642             return false;
1643
1644         case Entry::Type::FunctionNameNoArgs:
1645             {
1646                 ConstString name;
1647                 if (sc->function)
1648                     name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
1649                 else if (sc->symbol)
1650                     name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
1651                 if (name)
1652                 {
1653                     s.PutCString(name.GetCString());
1654                     return true;
1655                 }
1656             }
1657             return false;
1658
1659         case Entry::Type::FunctionNameWithArgs:
1660             {
1661                 // Print the function name with arguments in it
1662                 if (sc->function)
1663                 {
1664                     ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
1665                     const char *cstr = sc->function->GetName().AsCString (NULL);
1666                     if (cstr)
1667                     {
1668                         const InlineFunctionInfo *inline_info = NULL;
1669                         VariableListSP variable_list_sp;
1670                         bool get_function_vars = true;
1671                         if (sc->block)
1672                         {
1673                             Block *inline_block = sc->block->GetContainingInlinedBlock ();
1674
1675                             if (inline_block)
1676                             {
1677                                 get_function_vars = false;
1678                                 inline_info = sc->block->GetInlinedFunctionInfo();
1679                                 if (inline_info)
1680                                     variable_list_sp = inline_block->GetBlockVariableList (true);
1681                             }
1682                         }
1683
1684                         if (get_function_vars)
1685                         {
1686                             variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
1687                         }
1688
1689                         if (inline_info)
1690                         {
1691                             s.PutCString (cstr);
1692                             s.PutCString (" [inlined] ");
1693                             cstr = inline_info->GetName().GetCString();
1694                         }
1695
1696                         VariableList args;
1697                         if (variable_list_sp)
1698                             variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
1699                         if (args.GetSize() > 0)
1700                         {
1701                             const char *open_paren = strchr (cstr, '(');
1702                             const char *close_paren = nullptr;
1703                             const char *generic = strchr(cstr, '<');
1704                             // if before the arguments list begins there is a template sign
1705                             // then scan to the end of the generic args before you try to find
1706                             // the arguments list
1707                             if (generic && open_paren && generic < open_paren)
1708                             {
1709                                 int generic_depth = 1;
1710                                 ++generic;
1711                                 for (;
1712                                      *generic && generic_depth > 0;
1713                                      generic++)
1714                                 {
1715                                     if (*generic == '<')
1716                                         generic_depth++;
1717                                     if (*generic == '>')
1718                                         generic_depth--;
1719                                 }
1720                                 if (*generic)
1721                                     open_paren = strchr(generic, '(');
1722                                 else
1723                                     open_paren = nullptr;
1724                             }
1725                             if (open_paren)
1726                             {
1727                                 if (IsToken (open_paren, "(anonymous namespace)"))
1728                                 {
1729                                     open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
1730                                     if (open_paren)
1731                                         close_paren = strchr (open_paren, ')');
1732                                 }
1733                                 else
1734                                     close_paren = strchr (open_paren, ')');
1735                             }
1736
1737                             if (open_paren)
1738                                 s.Write(cstr, open_paren - cstr + 1);
1739                             else
1740                             {
1741                                 s.PutCString (cstr);
1742                                 s.PutChar ('(');
1743                             }
1744                             const size_t num_args = args.GetSize();
1745                             for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
1746                             {
1747                                 std::string buffer;
1748
1749                                 VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
1750                                 ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
1751                                 const char *var_representation = nullptr;
1752                                 const char *var_name = var_value_sp->GetName().GetCString();
1753                                 if (var_value_sp->GetClangType().IsAggregateType() &&
1754                                     DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
1755                                 {
1756                                     static StringSummaryFormat format(TypeSummaryImpl::Flags()
1757                                                                       .SetHideItemNames(false)
1758                                                                       .SetShowMembersOneLiner(true),
1759                                                                       "");
1760                                     format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
1761                                     var_representation = buffer.c_str();
1762                                 }
1763                                 else
1764                                     var_representation = var_value_sp->GetValueAsCString();
1765                                 if (arg_idx > 0)
1766                                     s.PutCString (", ");
1767                                 if (var_value_sp->GetError().Success())
1768                                 {
1769                                     if (var_representation)
1770                                         s.Printf ("%s=%s", var_name, var_representation);
1771                                     else
1772                                         s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
1773                                 }
1774                                 else
1775                                     s.Printf ("%s=<unavailable>", var_name);
1776                             }
1777
1778                             if (close_paren)
1779                                 s.PutCString (close_paren);
1780                             else
1781                                 s.PutChar(')');
1782
1783                         }
1784                         else
1785                         {
1786                             s.PutCString(cstr);
1787                         }
1788                         return true;
1789                     }
1790                 }
1791                 else if (sc->symbol)
1792                 {
1793                     const char *cstr = sc->symbol->GetName().AsCString (NULL);
1794                     if (cstr)
1795                     {
1796                         s.PutCString(cstr);
1797                         return true;
1798                     }
1799                 }
1800             }
1801             return false;
1802
1803         case Entry::Type::FunctionAddrOffset:
1804             if (addr)
1805             {
1806                 if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, false, false))
1807                     return true;
1808             }
1809             return false;
1810
1811         case Entry::Type::FunctionAddrOffsetConcrete:
1812             if (addr)
1813             {
1814                 if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, true, true))
1815                     return true;
1816             }
1817             return false;
1818
1819         case Entry::Type::FunctionLineOffset:
1820             if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false))
1821                 return true;
1822             return false;
1823
1824         case Entry::Type::FunctionPCOffset:
1825             if (exe_ctx)
1826             {
1827                 StackFrame *frame = exe_ctx->GetFramePtr();
1828                 if (frame)
1829                 {
1830                     if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, frame->GetFrameCodeAddress(), false, false))
1831                         return true;
1832                 }
1833             }
1834             return false;
1835
1836         case Entry::Type::LineEntryFile:
1837             if (sc && sc->line_entry.IsValid())
1838             {
1839                 Module *module = sc->module_sp.get();
1840                 if (module)
1841                 {
1842                     if (DumpFile(s, sc->line_entry.file, (FileKind)entry.number))
1843                         return true;
1844                 }
1845             }
1846             return false;
1847
1848         case Entry::Type::LineEntryLineNumber:
1849             if (sc && sc->line_entry.IsValid())
1850             {
1851                 const char *format = "%" PRIu32;
1852                 if (!entry.printf_format.empty())
1853                     format = entry.printf_format.c_str();
1854                 s.Printf(format, sc->line_entry.line);
1855                 return true;
1856             }
1857             return false;
1858
1859         case Entry::Type::LineEntryStartAddress:
1860         case Entry::Type::LineEntryEndAddress:
1861             if (sc && sc->line_entry.range.GetBaseAddress().IsValid())
1862             {
1863                 Address addr = sc->line_entry.range.GetBaseAddress();
1864
1865                 if (entry.type == Entry::Type::LineEntryEndAddress)
1866                     addr.Slide(sc->line_entry.range.GetByteSize());
1867                 if (DumpAddress(s, sc, exe_ctx, addr, false))
1868                     return true;
1869             }
1870             return false;
1871
1872         case Entry::Type::CurrentPCArrow:
1873             if (addr && exe_ctx && exe_ctx->GetFramePtr())
1874             {
1875                 RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
1876                 if (reg_ctx.get())
1877                 {
1878                     addr_t pc_loadaddr = reg_ctx->GetPC();
1879                     if (pc_loadaddr != LLDB_INVALID_ADDRESS)
1880                     {
1881                         Address pc;
1882                         pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
1883                         if (pc == *addr)
1884                         {
1885                             s.Printf ("-> ");
1886                             return true;
1887                         }
1888                     }
1889                 }
1890                 s.Printf("   ");
1891                 return true;
1892             }
1893             return false;
1894     }
1895     return false;
1896 }
1897
1898 static bool
1899 DumpCommaSeparatedChildEntryNames (Stream &s, const FormatEntity::Entry::Definition *parent)
1900 {
1901     if (parent->children)
1902     {
1903         const size_t n = parent->num_children;
1904         for (size_t i=0; i<n; ++i)
1905         {
1906             if (i > 0)
1907                 s.PutCString(", ");
1908             s.Printf ("\"%s\"", parent->children[i].name);
1909         }
1910         return true;
1911     }
1912     return false;
1913 }
1914
1915
1916 static Error
1917 ParseEntry (const llvm::StringRef &format_str,
1918             const FormatEntity::Entry::Definition *parent,
1919             FormatEntity::Entry &entry)
1920 {
1921     Error error;
1922
1923     const size_t sep_pos = format_str.find_first_of(".[:");
1924     const char sep_char = (sep_pos == llvm::StringRef::npos) ? '\0' : format_str[sep_pos];
1925     llvm::StringRef key = format_str.substr(0, sep_pos);
1926
1927     const size_t n = parent->num_children;
1928     for (size_t i=0; i<n; ++i)
1929     {
1930         const FormatEntity::Entry::Definition *entry_def = parent->children + i;
1931         if (key.equals(entry_def->name) || entry_def->name[0] == '*')
1932         {
1933             llvm::StringRef value;
1934             if (sep_char)
1935                 value = format_str.substr(sep_pos + (entry_def->keep_separator ? 0 : 1));
1936             switch (entry_def->type)
1937             {
1938                 case FormatEntity::Entry::Type::ParentString:
1939                     entry.string = std::move(format_str.str());
1940                     return error; // Success
1941
1942                 case FormatEntity::Entry::Type::ParentNumber:
1943                     entry.number = entry_def->data;
1944                     return error; // Success
1945
1946                 case FormatEntity::Entry::Type::InsertString:
1947                     entry.type = entry_def->type;
1948                     entry.string = entry_def->string;
1949                     return error; // Success
1950
1951                 default:
1952                     entry.type = entry_def->type;
1953                     break;
1954             }
1955
1956             if (value.empty())
1957             {
1958                 if (entry_def->type == FormatEntity::Entry::Type::Invalid)
1959                 {
1960                     if (entry_def->children)
1961                     {
1962                         StreamString error_strm;
1963                         error_strm.Printf("'%s' can't be specified on its own, you must access one of its children: ", entry_def->name);
1964                         DumpCommaSeparatedChildEntryNames (error_strm, entry_def);
1965                         error.SetErrorStringWithFormat("%s", error_strm.GetString().c_str());
1966                     }
1967                     else if (sep_char == ':')
1968                     {
1969                         // Any value whose separator is a with a ':' means this value has a string argument
1970                         // that needs to be stored in the entry (like "${script.var:}").
1971                         // In this case the string value is the empty string which is ok.
1972                     }
1973                     else
1974                     {
1975                         error.SetErrorStringWithFormat("%s", "invalid entry definitions");
1976                     }
1977                 }
1978             }
1979             else
1980             {
1981                 if (entry_def->children)
1982                 {
1983                     error = ParseEntry (value, entry_def, entry);
1984                 }
1985                 else if (sep_char == ':')
1986                 {
1987                     // Any value whose separator is a with a ':' means this value has a string argument
1988                     // that needs to be stored in the entry (like "${script.var:modulename.function}")
1989                     entry.string = std::move(value.str());
1990                 }
1991                 else
1992                 {
1993                     error.SetErrorStringWithFormat("'%s' followed by '%s' but it has no children",
1994                                                    key.str().c_str(),
1995                                                    value.str().c_str());
1996                 }
1997             }
1998             return error;
1999         }
2000     }
2001     StreamString error_strm;
2002     if (parent->type == FormatEntity::Entry::Type::Root)
2003         error_strm.Printf("invalid top level item '%s'. Valid top level items are: ", key.str().c_str());
2004     else
2005         error_strm.Printf("invalid member '%s' in '%s'. Valid members are: ", key.str().c_str(), parent->name);
2006     DumpCommaSeparatedChildEntryNames (error_strm, parent);
2007     error.SetErrorStringWithFormat("%s", error_strm.GetString().c_str());
2008     return error;
2009 }
2010
2011
2012 static const FormatEntity::Entry::Definition *
2013 FindEntry (const llvm::StringRef &format_str, const FormatEntity::Entry::Definition *parent, llvm::StringRef &remainder)
2014 {
2015     Error error;
2016     
2017     std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split('.');
2018     const size_t n = parent->num_children;
2019     for (size_t i=0; i<n; ++i)
2020     {
2021         const FormatEntity::Entry::Definition *entry_def = parent->children + i;
2022         if (p.first.equals(entry_def->name) || entry_def->name[0] == '*')
2023         {
2024             if (p.second.empty())
2025             {
2026                 if (format_str.back() == '.')
2027                     remainder = format_str.drop_front(format_str.size() - 1);
2028                 else
2029                     remainder = llvm::StringRef(); // Exact match
2030                 return entry_def;
2031             }
2032             else
2033             {
2034                 if (entry_def->children)
2035                 {
2036                     return FindEntry (p.second, entry_def, remainder);
2037                 }
2038                 else
2039                 {
2040                     remainder = p.second;
2041                     return entry_def;
2042                 }
2043             }
2044         }
2045     }
2046     remainder = format_str;
2047     return parent;
2048 }
2049
2050 Error
2051 FormatEntity::ParseInternal (llvm::StringRef &format, Entry &parent_entry, uint32_t depth)
2052 {
2053     Error error;
2054     while (!format.empty() && error.Success())
2055     {
2056         const size_t non_special_chars = format.find_first_of("${}\\");
2057
2058         if (non_special_chars == llvm::StringRef::npos)
2059         {
2060             // No special characters, just string bytes so add them and we are done
2061             parent_entry.AppendText(format);
2062             return error;
2063         }
2064
2065         if (non_special_chars > 0)
2066         {
2067             // We have a special character, so add all characters before these as a plain string
2068             parent_entry.AppendText(format.substr(0,non_special_chars));
2069             format = format.drop_front(non_special_chars);
2070         }
2071
2072         switch (format[0])
2073         {
2074             case '\0':
2075                 return error;
2076
2077             case '{':
2078                 {
2079                     format = format.drop_front(); // Skip the '{'
2080                     Entry scope_entry(Entry::Type::Scope);
2081                     error = FormatEntity::ParseInternal (format, scope_entry, depth+1);
2082                     if (error.Fail())
2083                         return error;
2084                     parent_entry.AppendEntry(std::move(scope_entry));
2085                 }
2086                 break;
2087
2088             case '}':
2089                 if (depth == 0)
2090                     error.SetErrorString("unmatched '}' character");
2091                 else
2092                     format = format.drop_front(); // Skip the '}' as we are at the end of the scope
2093                 return error;
2094
2095             case '\\':
2096                 {
2097                     format = format.drop_front(); // Skip the '\' character
2098                     if (format.empty())
2099                     {
2100                         error.SetErrorString("'\\' character was not followed by another character");
2101                         return error;
2102                     }
2103
2104                     const char desens_char = format[0];
2105                     format = format.drop_front(); // Skip the desensitized char character
2106                     switch (desens_char)
2107                     {
2108                         case 'a': parent_entry.AppendChar('\a'); break;
2109                         case 'b': parent_entry.AppendChar('\b'); break;
2110                         case 'f': parent_entry.AppendChar('\f'); break;
2111                         case 'n': parent_entry.AppendChar('\n'); break;
2112                         case 'r': parent_entry.AppendChar('\r'); break;
2113                         case 't': parent_entry.AppendChar('\t'); break;
2114                         case 'v': parent_entry.AppendChar('\v'); break;
2115                         case '\'': parent_entry.AppendChar('\''); break;
2116                         case '\\': parent_entry.AppendChar('\\'); break;
2117                         case '0':
2118                             // 1 to 3 octal chars
2119                         {
2120                             // Make a string that can hold onto the initial zero char,
2121                             // up to 3 octal digits, and a terminating NULL.
2122                             char oct_str[5] = { 0, 0, 0, 0, 0 };
2123
2124                             int i;
2125                             for (i=0; (format[i] >= '0' && format[i] <= '7') && i<4; ++i)
2126                                 oct_str[i] = format[i];
2127
2128                             // We don't want to consume the last octal character since
2129                             // the main for loop will do this for us, so we advance p by
2130                             // one less than i (even if i is zero)
2131                             format = format.drop_front(i);
2132                             unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
2133                             if (octal_value <= UINT8_MAX)
2134                             {
2135                                 parent_entry.AppendChar((char)octal_value);
2136                             }
2137                             else
2138                             {
2139                                 error.SetErrorString("octal number is larger than a single byte");
2140                                 return error;
2141                             }
2142                         }
2143                             break;
2144
2145                         case 'x':
2146                             // hex number in the format
2147                             if (isxdigit(format[0]))
2148                             {
2149                                 // Make a string that can hold onto two hex chars plus a
2150                                 // NULL terminator
2151                                 char hex_str[3] = { 0,0,0 };
2152                                 hex_str[0] = format[0];
2153
2154                                 format = format.drop_front();
2155
2156                                 if (isxdigit(format[0]))
2157                                 {
2158                                     hex_str[1] = format[0];
2159                                     format = format.drop_front();
2160                                 }
2161
2162                                 unsigned long hex_value = strtoul (hex_str, NULL, 16);
2163                                 if (hex_value <= UINT8_MAX)
2164                                 {
2165                                     parent_entry.AppendChar((char)hex_value);
2166                                 }
2167                                 else
2168                                 {
2169                                     error.SetErrorString("hex number is larger than a single byte");
2170                                     return error;
2171                                 }
2172                             }
2173                             else
2174                             {
2175                                 parent_entry.AppendChar(desens_char);
2176                             }
2177                             break;
2178
2179                         default:
2180                             // Just desensitize any other character by just printing what
2181                             // came after the '\'
2182                             parent_entry.AppendChar(desens_char);
2183                             break;
2184                     }
2185                 }
2186                 break;
2187
2188             case '$':
2189                 if (format.size() == 1)
2190                 {
2191                     // '$' at the end of a format string, just print the '$'
2192                     parent_entry.AppendText("$");
2193                 }
2194                 else
2195                 {
2196                     format = format.drop_front(); // Skip the '$'
2197
2198                     if (format[0] == '{')
2199                     {
2200                         format = format.drop_front(); // Skip the '{'
2201
2202                         llvm::StringRef variable, variable_format;
2203                         error = FormatEntity::ExtractVariableInfo (format, variable, variable_format);
2204                         if (error.Fail())
2205                             return error;
2206                         bool verify_is_thread_id = false;
2207                         Entry entry;
2208                         if (!variable_format.empty())
2209                         {
2210                             entry.printf_format = std::move(variable_format.str());
2211                             
2212                             // If the format contains a '%' we are going to assume this is
2213                             // a printf style format. So if you want to format your thread ID
2214                             // using "0x%llx" you can use:
2215                             // ${thread.id%0x%llx}
2216                             //
2217                             // If there is no '%' in the format, then it is assumed to be a
2218                             // LLDB format name, or one of the extended formats specified in
2219                             // the switch statement below.
2220                             
2221                             if (entry.printf_format.find('%') == std::string::npos)
2222                             {
2223                                 bool clear_printf = false;
2224
2225                                 if (FormatManager::GetFormatFromCString(entry.printf_format.c_str(),
2226                                                                         false,
2227                                                                         entry.fmt))
2228                                 {
2229                                     // We have an LLDB format, so clear the printf format
2230                                     clear_printf = true;
2231                                 }
2232                                 else if (entry.printf_format.size() == 1)
2233                                 {
2234                                     switch (entry.printf_format[0])
2235                                     {
2236                                         case '@':             // if this is an @ sign, print ObjC description
2237                                             entry.number = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
2238                                             clear_printf = true;
2239                                             break;
2240                                         case 'V': // if this is a V, print the value using the default format
2241                                             entry.number = ValueObject::eValueObjectRepresentationStyleValue;
2242                                             clear_printf = true;
2243                                             break;
2244                                         case 'L': // if this is an L, print the location of the value
2245                                             entry.number = ValueObject::eValueObjectRepresentationStyleLocation;
2246                                             clear_printf = true;
2247                                             break;
2248                                         case 'S': // if this is an S, print the summary after all
2249                                             entry.number = ValueObject::eValueObjectRepresentationStyleSummary;
2250                                             clear_printf = true;
2251                                             break;
2252                                         case '#': // if this is a '#', print the number of children
2253                                             entry.number = ValueObject::eValueObjectRepresentationStyleChildrenCount;
2254                                             clear_printf = true;
2255                                             break;
2256                                         case 'T': // if this is a 'T', print the type
2257                                             entry.number = ValueObject::eValueObjectRepresentationStyleType;
2258                                             clear_printf = true;
2259                                             break;
2260                                         case 'N': // if this is a 'N', print the name
2261                                             entry.number = ValueObject::eValueObjectRepresentationStyleName;
2262                                             clear_printf = true;
2263                                             break;
2264                                         case '>': // if this is a '>', print the expression path
2265                                             entry.number = ValueObject::eValueObjectRepresentationStyleExpressionPath;
2266                                             clear_printf = true;
2267                                             break;
2268                                         default:
2269                                             error.SetErrorStringWithFormat("invalid format: '%s'", entry.printf_format.c_str());
2270                                             return error;
2271                                     }
2272                                 }
2273                                 else if (FormatManager::GetFormatFromCString(entry.printf_format.c_str(),
2274                                                                              true,
2275                                                                              entry.fmt))
2276                                 {
2277                                     clear_printf = true;
2278                                 }
2279                                 else if (entry.printf_format == "tid")
2280                                 {
2281                                     verify_is_thread_id = true;
2282                                 }
2283                                 else
2284                                 {
2285                                     error.SetErrorStringWithFormat("invalid format: '%s'", entry.printf_format.c_str());
2286                                     return error;
2287                                 }
2288                                 
2289                                 // Our format string turned out to not be a printf style format
2290                                 // so lets clear the string
2291                                 if (clear_printf)
2292                                     entry.printf_format.clear();
2293                             }
2294                         }
2295
2296                         // Check for dereferences
2297                         if (variable[0] == '*')
2298                         {
2299                             entry.deref = true;
2300                             variable = variable.drop_front();
2301                         }
2302
2303                         error = ParseEntry (variable, &g_root, entry);
2304                         if (error.Fail())
2305                             return error;
2306
2307                         if (verify_is_thread_id)
2308                         {
2309                             if (entry.type != Entry::Type::ThreadID &&
2310                                 entry.type != Entry::Type::ThreadProtocolID)
2311                             {
2312                                 error.SetErrorString("the 'tid' format can only be used on ${thread.id} and ${thread.protocol_id}");
2313                             }
2314                         }
2315
2316                         switch (entry.type)
2317                         {
2318                             case Entry::Type::Variable:
2319                             case Entry::Type::VariableSynthetic:
2320                                 if (entry.number == 0)
2321                                 {
2322                                     if (entry.string.empty())
2323                                         entry.number = ValueObject::eValueObjectRepresentationStyleValue;
2324                                     else
2325                                         entry.number = ValueObject::eValueObjectRepresentationStyleSummary;
2326                                 }
2327                                 break;
2328                             default:
2329                                 // Make sure someone didn't try to dereference anything but ${var} or ${svar}
2330                                 if (entry.deref)
2331                                 {
2332                                     error.SetErrorStringWithFormat("${%s} can't be dereferenced, only ${var} and ${svar} can.", variable.str().c_str());
2333                                     return error;
2334                                 }
2335                         }
2336                         // Check if this entry just wants to insert a constant string
2337                         // value into the parent_entry, if so, insert the string with
2338                         // AppendText, else append the entry to the parent_entry.
2339                         if (entry.type == Entry::Type::InsertString)
2340                             parent_entry.AppendText(entry.string.c_str());
2341                         else
2342                             parent_entry.AppendEntry(std::move(entry));
2343                     }
2344                 }
2345                 break;
2346         }
2347     }
2348     return error;
2349 }
2350
2351
2352 Error
2353 FormatEntity::ExtractVariableInfo (llvm::StringRef &format_str, llvm::StringRef &variable_name, llvm::StringRef &variable_format)
2354 {
2355     Error error;
2356     variable_name = llvm::StringRef();
2357     variable_format = llvm::StringRef();
2358
2359     const size_t paren_pos = format_str.find_first_of('}');
2360     if (paren_pos != llvm::StringRef::npos)
2361     {
2362         const size_t percent_pos = format_str.find_first_of('%');
2363         if (percent_pos < paren_pos)
2364         {
2365             if (percent_pos > 0)
2366             {
2367                 if (percent_pos > 1)
2368                     variable_name = format_str.substr(0, percent_pos);
2369                 variable_format = format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
2370             }
2371         }
2372         else
2373         {
2374             variable_name = format_str.substr(0, paren_pos);
2375         }
2376         // Strip off elements and the formatting and the trailing '}'
2377         format_str = format_str.substr(paren_pos + 1);
2378     }
2379     else
2380     {
2381         error.SetErrorStringWithFormat("missing terminating '}' character for '${%s'", format_str.str().c_str());
2382     }
2383     return error;
2384 }
2385
2386 bool
2387 FormatEntity::FormatFileSpec (const FileSpec &file_spec, Stream &s, llvm::StringRef variable_name, llvm::StringRef variable_format)
2388 {
2389     if (variable_name.empty() || variable_name.equals(".fullpath"))
2390     {
2391         file_spec.Dump(&s);
2392         return true;
2393     }
2394     else if (variable_name.equals(".basename"))
2395     {
2396         s.PutCString(file_spec.GetFilename().AsCString(""));
2397         return true;
2398     }
2399     else if (variable_name.equals(".dirname"))
2400     {
2401         s.PutCString(file_spec.GetFilename().AsCString(""));
2402         return true;
2403     }
2404     return false;
2405 }
2406
2407 static std::string
2408 MakeMatch (const llvm::StringRef &prefix, const char *suffix)
2409 {
2410     std::string match(prefix.str());
2411     match.append(suffix);
2412     return std::move(match);
2413 }
2414
2415 static void
2416 AddMatches (const FormatEntity::Entry::Definition *def,
2417             const llvm::StringRef &prefix,
2418             const llvm::StringRef &match_prefix,
2419             StringList &matches)
2420 {
2421     const size_t n = def->num_children;
2422     if (n > 0)
2423     {
2424         for (size_t i=0; i<n; ++i)
2425         {
2426             std::string match = std::move(prefix.str());
2427             if (match_prefix.empty())
2428                 matches.AppendString(MakeMatch (prefix, def->children[i].name));
2429             else if (strncmp(def->children[i].name, match_prefix.data(), match_prefix.size()) == 0)
2430                 matches.AppendString(MakeMatch (prefix, def->children[i].name + match_prefix.size()));
2431         }
2432     }
2433 }
2434 size_t
2435 FormatEntity::AutoComplete (const char *s,
2436                             int match_start_point,
2437                             int max_return_elements,
2438                             bool &word_complete,
2439                             StringList &matches)
2440 {
2441     word_complete = false;
2442     llvm::StringRef str(s + match_start_point);
2443     matches.Clear();
2444     
2445     const size_t dollar_pos = str.rfind('$');
2446     if (dollar_pos != llvm::StringRef::npos)
2447     {
2448         // Hitting TAB after $ at the end of the string add a "{"
2449         if (dollar_pos == str.size() - 1)
2450         {
2451             std::string match = std::move(str.str());
2452             match.append("{");
2453             matches.AppendString(std::move(match));
2454         }
2455         else if (str[dollar_pos + 1] == '{')
2456         {
2457             const size_t close_pos = str.find('}', dollar_pos + 2);
2458             if (close_pos == llvm::StringRef::npos)
2459             {
2460                 const size_t format_pos = str.find('%', dollar_pos + 2);
2461                 if (format_pos == llvm::StringRef::npos)
2462                 {
2463                     llvm::StringRef partial_variable (str.substr(dollar_pos + 2));
2464                     if (partial_variable.empty())
2465                     {
2466                         // Suggest all top level entites as we are just past "${"
2467                         AddMatches(&g_root, str, llvm::StringRef(), matches);
2468                     }
2469                     else
2470                     {
2471                         // We have a partially specified variable, find it
2472                         llvm::StringRef remainder;
2473                         const FormatEntity::Entry::Definition* entry_def = FindEntry (partial_variable, &g_root, remainder);
2474                         if (entry_def)
2475                         {
2476                             const size_t n = entry_def->num_children;
2477
2478                             if (remainder.empty())
2479                             {
2480                                 // Exact match
2481                                 if (n > 0)
2482                                 {
2483                                     // "${thread.info" <TAB>
2484                                     matches.AppendString(std::move(MakeMatch (str, ".")));
2485                                 }
2486                                 else
2487                                 {
2488                                     // "${thread.id" <TAB>
2489                                     matches.AppendString(std::move(MakeMatch (str, "}")));
2490                                     word_complete = true;
2491                                 }
2492                             }
2493                             else if (remainder.equals("."))
2494                             {
2495                                 // "${thread." <TAB>
2496                                 AddMatches(entry_def, str, llvm::StringRef(), matches);
2497                             }
2498                             else
2499                             {
2500                                 // We have a partial match
2501                                 // "${thre" <TAB>
2502                                 AddMatches(entry_def, str, remainder, matches);
2503                             }
2504                         }
2505                     }
2506                 }
2507             }
2508         }
2509     }
2510     return matches.GetSize();
2511 }