1 //===-- StackFrame.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 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Target/StackFrame.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/Disassembler.h"
17 #include "lldb/Core/FormatEntity.h"
18 #include "lldb/Core/Mangled.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/Value.h"
21 #include "lldb/Core/ValueObjectConstResult.h"
22 #include "lldb/Core/ValueObjectMemory.h"
23 #include "lldb/Core/ValueObjectVariable.h"
24 #include "lldb/Symbol/CompileUnit.h"
25 #include "lldb/Symbol/Function.h"
26 #include "lldb/Symbol/Symbol.h"
27 #include "lldb/Symbol/SymbolContextScope.h"
28 #include "lldb/Symbol/Type.h"
29 #include "lldb/Symbol/VariableList.h"
30 #include "lldb/Target/ABI.h"
31 #include "lldb/Target/ExecutionContext.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/RegisterContext.h"
34 #include "lldb/Target/Target.h"
35 #include "lldb/Target/Thread.h"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 
40 // The first bits in the flags are reserved for the SymbolContext::Scope bits
41 // so we know if we have tried to look up information in our internal symbol
42 // context (m_sc) already.
43 #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1))
44 #define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
45 #define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
46 #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
47 #define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
48 
49 StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
50                        user_id_t unwind_frame_index, addr_t cfa,
51                        bool cfa_is_valid, addr_t pc, uint32_t stop_id,
52                        bool stop_id_is_valid, bool is_history_frame,
53                        const SymbolContext *sc_ptr)
54     : m_thread_wp(thread_sp), m_frame_index(frame_idx),
55       m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(),
56       m_id(pc, cfa, nullptr), m_frame_code_addr(pc), m_sc(), m_flags(),
57       m_frame_base(), m_frame_base_error(), m_cfa_is_valid(cfa_is_valid),
58       m_stop_id(stop_id), m_stop_id_is_valid(stop_id_is_valid),
59       m_is_history_frame(is_history_frame), m_variable_list_sp(),
60       m_variable_list_value_objects(), m_disassembly(), m_mutex() {
61   // If we don't have a CFA value, use the frame index for our StackID so that
62   // recursive
63   // functions properly aren't confused with one another on a history stack.
64   if (m_is_history_frame && !m_cfa_is_valid) {
65     m_id.SetCFA(m_frame_index);
66   }
67 
68   if (sc_ptr != nullptr) {
69     m_sc = *sc_ptr;
70     m_flags.Set(m_sc.GetResolvedMask());
71   }
72 }
73 
74 StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
75                        user_id_t unwind_frame_index,
76                        const RegisterContextSP &reg_context_sp, addr_t cfa,
77                        addr_t pc, const SymbolContext *sc_ptr)
78     : m_thread_wp(thread_sp), m_frame_index(frame_idx),
79       m_concrete_frame_index(unwind_frame_index),
80       m_reg_context_sp(reg_context_sp), m_id(pc, cfa, nullptr),
81       m_frame_code_addr(pc), m_sc(), m_flags(), m_frame_base(),
82       m_frame_base_error(), m_cfa_is_valid(true), m_stop_id(0),
83       m_stop_id_is_valid(false), m_is_history_frame(false),
84       m_variable_list_sp(), m_variable_list_value_objects(), m_disassembly(),
85       m_mutex() {
86   if (sc_ptr != nullptr) {
87     m_sc = *sc_ptr;
88     m_flags.Set(m_sc.GetResolvedMask());
89   }
90 
91   if (reg_context_sp && !m_sc.target_sp) {
92     m_sc.target_sp = reg_context_sp->CalculateTarget();
93     if (m_sc.target_sp)
94       m_flags.Set(eSymbolContextTarget);
95   }
96 }
97 
98 StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
99                        user_id_t unwind_frame_index,
100                        const RegisterContextSP &reg_context_sp, addr_t cfa,
101                        const Address &pc_addr, const SymbolContext *sc_ptr)
102     : m_thread_wp(thread_sp), m_frame_index(frame_idx),
103       m_concrete_frame_index(unwind_frame_index),
104       m_reg_context_sp(reg_context_sp),
105       m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa,
106            nullptr),
107       m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(),
108       m_frame_base_error(), m_cfa_is_valid(true), m_stop_id(0),
109       m_stop_id_is_valid(false), m_is_history_frame(false),
110       m_variable_list_sp(), m_variable_list_value_objects(), m_disassembly(),
111       m_mutex() {
112   if (sc_ptr != nullptr) {
113     m_sc = *sc_ptr;
114     m_flags.Set(m_sc.GetResolvedMask());
115   }
116 
117   if (!m_sc.target_sp && reg_context_sp) {
118     m_sc.target_sp = reg_context_sp->CalculateTarget();
119     if (m_sc.target_sp)
120       m_flags.Set(eSymbolContextTarget);
121   }
122 
123   ModuleSP pc_module_sp(pc_addr.GetModule());
124   if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) {
125     if (pc_module_sp) {
126       m_sc.module_sp = pc_module_sp;
127       m_flags.Set(eSymbolContextModule);
128     } else {
129       m_sc.module_sp.reset();
130     }
131   }
132 }
133 
134 StackFrame::~StackFrame() = default;
135 
136 StackID &StackFrame::GetStackID() {
137   std::lock_guard<std::recursive_mutex> guard(m_mutex);
138   // Make sure we have resolved the StackID object's symbol context scope if
139   // we already haven't looked it up.
140 
141   if (m_flags.IsClear(RESOLVED_FRAME_ID_SYMBOL_SCOPE)) {
142     if (m_id.GetSymbolContextScope()) {
143       // We already have a symbol context scope, we just don't have our
144       // flag bit set.
145       m_flags.Set(RESOLVED_FRAME_ID_SYMBOL_SCOPE);
146     } else {
147       // Calculate the frame block and use this for the stack ID symbol
148       // context scope if we have one.
149       SymbolContextScope *scope = GetFrameBlock();
150       if (scope == nullptr) {
151         // We don't have a block, so use the symbol
152         if (m_flags.IsClear(eSymbolContextSymbol))
153           GetSymbolContext(eSymbolContextSymbol);
154 
155         // It is ok if m_sc.symbol is nullptr here
156         scope = m_sc.symbol;
157       }
158       // Set the symbol context scope (the accessor will set the
159       // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
160       SetSymbolContextScope(scope);
161     }
162   }
163   return m_id;
164 }
165 
166 uint32_t StackFrame::GetFrameIndex() const {
167   ThreadSP thread_sp = GetThread();
168   if (thread_sp)
169     return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(
170         m_frame_index);
171   else
172     return m_frame_index;
173 }
174 
175 void StackFrame::SetSymbolContextScope(SymbolContextScope *symbol_scope) {
176   std::lock_guard<std::recursive_mutex> guard(m_mutex);
177   m_flags.Set(RESOLVED_FRAME_ID_SYMBOL_SCOPE);
178   m_id.SetSymbolContextScope(symbol_scope);
179 }
180 
181 const Address &StackFrame::GetFrameCodeAddress() {
182   std::lock_guard<std::recursive_mutex> guard(m_mutex);
183   if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) &&
184       !m_frame_code_addr.IsSectionOffset()) {
185     m_flags.Set(RESOLVED_FRAME_CODE_ADDR);
186 
187     // Resolve the PC into a temporary address because if ResolveLoadAddress
188     // fails to resolve the address, it will clear the address object...
189     ThreadSP thread_sp(GetThread());
190     if (thread_sp) {
191       TargetSP target_sp(thread_sp->CalculateTarget());
192       if (target_sp) {
193         if (m_frame_code_addr.SetOpcodeLoadAddress(
194                 m_frame_code_addr.GetOffset(), target_sp.get(),
195                 eAddressClassCode)) {
196           ModuleSP module_sp(m_frame_code_addr.GetModule());
197           if (module_sp) {
198             m_sc.module_sp = module_sp;
199             m_flags.Set(eSymbolContextModule);
200           }
201         }
202       }
203     }
204   }
205   return m_frame_code_addr;
206 }
207 
208 bool StackFrame::ChangePC(addr_t pc) {
209   std::lock_guard<std::recursive_mutex> guard(m_mutex);
210   // We can't change the pc value of a history stack frame - it is immutable.
211   if (m_is_history_frame)
212     return false;
213   m_frame_code_addr.SetRawAddress(pc);
214   m_sc.Clear(false);
215   m_flags.Reset(0);
216   ThreadSP thread_sp(GetThread());
217   if (thread_sp)
218     thread_sp->ClearStackFrames();
219   return true;
220 }
221 
222 const char *StackFrame::Disassemble() {
223   std::lock_guard<std::recursive_mutex> guard(m_mutex);
224   if (m_disassembly.Empty()) {
225     ExecutionContext exe_ctx(shared_from_this());
226     Target *target = exe_ctx.GetTargetPtr();
227     if (target) {
228       const char *plugin_name = nullptr;
229       const char *flavor = nullptr;
230       Disassembler::Disassemble(target->GetDebugger(),
231                                 target->GetArchitecture(), plugin_name, flavor,
232                                 exe_ctx, 0, false, 0, 0, m_disassembly);
233     }
234     if (m_disassembly.Empty())
235       return nullptr;
236   }
237 
238   return m_disassembly.GetData();
239 }
240 
241 Block *StackFrame::GetFrameBlock() {
242   if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock))
243     GetSymbolContext(eSymbolContextBlock);
244 
245   if (m_sc.block) {
246     Block *inline_block = m_sc.block->GetContainingInlinedBlock();
247     if (inline_block) {
248       // Use the block with the inlined function info
249       // as the frame block we want this frame to have only the variables
250       // for the inlined function and its non-inlined block child blocks.
251       return inline_block;
252     } else {
253       // This block is not contained within any inlined function blocks
254       // with so we want to use the top most function block.
255       return &m_sc.function->GetBlock(false);
256     }
257   }
258   return nullptr;
259 }
260 
261 //----------------------------------------------------------------------
262 // Get the symbol context if we already haven't done so by resolving the
263 // PC address as much as possible. This way when we pass around a
264 // StackFrame object, everyone will have as much information as
265 // possible and no one will ever have to look things up manually.
266 //----------------------------------------------------------------------
267 const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) {
268   std::lock_guard<std::recursive_mutex> guard(m_mutex);
269   // Copy our internal symbol context into "sc".
270   if ((m_flags.Get() & resolve_scope) != resolve_scope) {
271     uint32_t resolved = 0;
272 
273     // If the target was requested add that:
274     if (!m_sc.target_sp) {
275       m_sc.target_sp = CalculateTarget();
276       if (m_sc.target_sp)
277         resolved |= eSymbolContextTarget;
278     }
279 
280     // Resolve our PC to section offset if we haven't already done so
281     // and if we don't have a module. The resolved address section will
282     // contain the module to which it belongs
283     if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
284       GetFrameCodeAddress();
285 
286     // If this is not frame zero, then we need to subtract 1 from the PC
287     // value when doing address lookups since the PC will be on the
288     // instruction following the function call instruction...
289 
290     Address lookup_addr(GetFrameCodeAddress());
291     if (m_frame_index > 0 && lookup_addr.IsValid()) {
292       addr_t offset = lookup_addr.GetOffset();
293       if (offset > 0) {
294         lookup_addr.SetOffset(offset - 1);
295 
296       } else {
297         // lookup_addr is the start of a section.  We need
298         // do the math on the actual load address and re-compute
299         // the section.  We're working with a 'noreturn' function
300         // at the end of a section.
301         ThreadSP thread_sp(GetThread());
302         if (thread_sp) {
303           TargetSP target_sp(thread_sp->CalculateTarget());
304           if (target_sp) {
305             addr_t addr_minus_one =
306                 lookup_addr.GetLoadAddress(target_sp.get()) - 1;
307             lookup_addr.SetLoadAddress(addr_minus_one, target_sp.get());
308           } else {
309             lookup_addr.SetOffset(offset - 1);
310           }
311         }
312       }
313     }
314 
315     if (m_sc.module_sp) {
316       // We have something in our stack frame symbol context, lets check
317       // if we haven't already tried to lookup one of those things. If we
318       // haven't then we will do the query.
319 
320       uint32_t actual_resolve_scope = 0;
321 
322       if (resolve_scope & eSymbolContextCompUnit) {
323         if (m_flags.IsClear(eSymbolContextCompUnit)) {
324           if (m_sc.comp_unit)
325             resolved |= eSymbolContextCompUnit;
326           else
327             actual_resolve_scope |= eSymbolContextCompUnit;
328         }
329       }
330 
331       if (resolve_scope & eSymbolContextFunction) {
332         if (m_flags.IsClear(eSymbolContextFunction)) {
333           if (m_sc.function)
334             resolved |= eSymbolContextFunction;
335           else
336             actual_resolve_scope |= eSymbolContextFunction;
337         }
338       }
339 
340       if (resolve_scope & eSymbolContextBlock) {
341         if (m_flags.IsClear(eSymbolContextBlock)) {
342           if (m_sc.block)
343             resolved |= eSymbolContextBlock;
344           else
345             actual_resolve_scope |= eSymbolContextBlock;
346         }
347       }
348 
349       if (resolve_scope & eSymbolContextSymbol) {
350         if (m_flags.IsClear(eSymbolContextSymbol)) {
351           if (m_sc.symbol)
352             resolved |= eSymbolContextSymbol;
353           else
354             actual_resolve_scope |= eSymbolContextSymbol;
355         }
356       }
357 
358       if (resolve_scope & eSymbolContextLineEntry) {
359         if (m_flags.IsClear(eSymbolContextLineEntry)) {
360           if (m_sc.line_entry.IsValid())
361             resolved |= eSymbolContextLineEntry;
362           else
363             actual_resolve_scope |= eSymbolContextLineEntry;
364         }
365       }
366 
367       if (actual_resolve_scope) {
368         // We might be resolving less information than what is already
369         // in our current symbol context so resolve into a temporary
370         // symbol context "sc" so we don't clear out data we have
371         // already found in "m_sc"
372         SymbolContext sc;
373         // Set flags that indicate what we have tried to resolve
374         resolved |= m_sc.module_sp->ResolveSymbolContextForAddress(
375             lookup_addr, actual_resolve_scope, sc);
376         // Only replace what we didn't already have as we may have
377         // information for an inlined function scope that won't match
378         // what a standard lookup by address would match
379         if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr)
380           m_sc.comp_unit = sc.comp_unit;
381         if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr)
382           m_sc.function = sc.function;
383         if ((resolved & eSymbolContextBlock) && m_sc.block == nullptr)
384           m_sc.block = sc.block;
385         if ((resolved & eSymbolContextSymbol) && m_sc.symbol == nullptr)
386           m_sc.symbol = sc.symbol;
387         if ((resolved & eSymbolContextLineEntry) &&
388             !m_sc.line_entry.IsValid()) {
389           m_sc.line_entry = sc.line_entry;
390           m_sc.line_entry.ApplyFileMappings(m_sc.target_sp);
391         }
392       }
393     } else {
394       // If we don't have a module, then we can't have the compile unit,
395       // function, block, line entry or symbol, so we can safely call
396       // ResolveSymbolContextForAddress with our symbol context member m_sc.
397       if (m_sc.target_sp) {
398         resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress(
399             lookup_addr, resolve_scope, m_sc);
400       }
401     }
402 
403     // Update our internal flags so we remember what we have tried to locate so
404     // we don't have to keep trying when more calls to this function are made.
405     // We might have dug up more information that was requested (for example
406     // if we were asked to only get the block, we will have gotten the
407     // compile unit, and function) so set any additional bits that we resolved
408     m_flags.Set(resolve_scope | resolved);
409   }
410 
411   // Return the symbol context with everything that was possible to resolve
412   // resolved.
413   return m_sc;
414 }
415 
416 VariableList *StackFrame::GetVariableList(bool get_file_globals) {
417   std::lock_guard<std::recursive_mutex> guard(m_mutex);
418   if (m_flags.IsClear(RESOLVED_VARIABLES)) {
419     m_flags.Set(RESOLVED_VARIABLES);
420 
421     Block *frame_block = GetFrameBlock();
422 
423     if (frame_block) {
424       const bool get_child_variables = true;
425       const bool can_create = true;
426       const bool stop_if_child_block_is_inlined_function = true;
427       m_variable_list_sp.reset(new VariableList());
428       frame_block->AppendBlockVariables(can_create, get_child_variables,
429                                         stop_if_child_block_is_inlined_function,
430                                         [](Variable *v) { return true; },
431                                         m_variable_list_sp.get());
432     }
433   }
434 
435   if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && get_file_globals) {
436     m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
437 
438     if (m_flags.IsClear(eSymbolContextCompUnit))
439       GetSymbolContext(eSymbolContextCompUnit);
440 
441     if (m_sc.comp_unit) {
442       VariableListSP global_variable_list_sp(
443           m_sc.comp_unit->GetVariableList(true));
444       if (m_variable_list_sp)
445         m_variable_list_sp->AddVariables(global_variable_list_sp.get());
446       else
447         m_variable_list_sp = global_variable_list_sp;
448     }
449   }
450 
451   return m_variable_list_sp.get();
452 }
453 
454 VariableListSP
455 StackFrame::GetInScopeVariableList(bool get_file_globals,
456                                    bool must_have_valid_location) {
457   std::lock_guard<std::recursive_mutex> guard(m_mutex);
458   // We can't fetch variable information for a history stack frame.
459   if (m_is_history_frame)
460     return VariableListSP();
461 
462   VariableListSP var_list_sp(new VariableList);
463   GetSymbolContext(eSymbolContextCompUnit | eSymbolContextBlock);
464 
465   if (m_sc.block) {
466     const bool can_create = true;
467     const bool get_parent_variables = true;
468     const bool stop_if_block_is_inlined_function = true;
469     m_sc.block->AppendVariables(
470         can_create, get_parent_variables, stop_if_block_is_inlined_function,
471         [this, must_have_valid_location](Variable *v) {
472           return v->IsInScope(this) && (!must_have_valid_location ||
473                                         v->LocationIsValidForFrame(this));
474         },
475         var_list_sp.get());
476   }
477 
478   if (m_sc.comp_unit && get_file_globals) {
479     VariableListSP global_variable_list_sp(
480         m_sc.comp_unit->GetVariableList(true));
481     if (global_variable_list_sp)
482       var_list_sp->AddVariables(global_variable_list_sp.get());
483   }
484 
485   return var_list_sp;
486 }
487 
488 ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
489     llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
490     VariableSP &var_sp, Error &error) {
491   llvm::StringRef original_var_expr = var_expr;
492   // We can't fetch variable information for a history stack frame.
493   if (m_is_history_frame)
494     return ValueObjectSP();
495 
496   if (var_expr.empty()) {
497     error.SetErrorStringWithFormat("invalid variable path '%s'",
498                                    var_expr.str().c_str());
499     return ValueObjectSP();
500   }
501 
502   const bool check_ptr_vs_member =
503       (options & eExpressionPathOptionCheckPtrVsMember) != 0;
504   const bool no_fragile_ivar =
505       (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
506   const bool no_synth_child =
507       (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
508   // const bool no_synth_array = (options &
509   // eExpressionPathOptionsNoSyntheticArrayRange) != 0;
510   error.Clear();
511   bool deref = false;
512   bool address_of = false;
513   ValueObjectSP valobj_sp;
514   const bool get_file_globals = true;
515   // When looking up a variable for an expression, we need only consider the
516   // variables that are in scope.
517   VariableListSP var_list_sp(GetInScopeVariableList(get_file_globals));
518   VariableList *variable_list = var_list_sp.get();
519 
520   if (!variable_list)
521     return ValueObjectSP();
522 
523   // If first character is a '*', then show pointer contents
524   std::string var_expr_storage;
525   if (var_expr[0] == '*') {
526     deref = true;
527     var_expr = var_expr.drop_front(); // Skip the '*'
528   } else if (var_expr[0] == '&') {
529     address_of = true;
530     var_expr = var_expr.drop_front(); // Skip the '&'
531   }
532 
533   size_t separator_idx = var_expr.find_first_of(".-[=+~|&^%#@!/?,<>{}");
534   StreamString var_expr_path_strm;
535 
536   ConstString name_const_string(var_expr.substr(0, separator_idx));
537 
538   var_sp = variable_list->FindVariable(name_const_string, false);
539 
540   bool synthetically_added_instance_object = false;
541 
542   if (var_sp) {
543     var_expr = var_expr.drop_front(name_const_string.GetLength());
544   }
545 
546   if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) {
547     // Check for direct ivars access which helps us with implicit
548     // access to ivars with the "this->" or "self->"
549     GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock);
550     lldb::LanguageType method_language = eLanguageTypeUnknown;
551     bool is_instance_method = false;
552     ConstString method_object_name;
553     if (m_sc.GetFunctionMethodInfo(method_language, is_instance_method,
554                                    method_object_name)) {
555       if (is_instance_method && method_object_name) {
556         var_sp = variable_list->FindVariable(method_object_name);
557         if (var_sp) {
558           separator_idx = 0;
559           var_expr_storage = "->";
560           var_expr_storage += var_expr;
561           var_expr = var_expr_storage;
562           synthetically_added_instance_object = true;
563         }
564       }
565     }
566   }
567 
568   if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) {
569     // Check if any anonymous unions are there which contain a variable with
570     // the name we need
571     for (size_t i = 0; i < variable_list->GetSize(); i++) {
572       VariableSP variable_sp = variable_list->GetVariableAtIndex(i);
573       if (!variable_sp)
574         continue;
575       if (!variable_sp->GetName().IsEmpty())
576         continue;
577 
578       Type *var_type = variable_sp->GetType();
579       if (!var_type)
580         continue;
581 
582       if (!var_type->GetForwardCompilerType().IsAnonymousType())
583         continue;
584       valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic);
585       if (!valobj_sp)
586         return valobj_sp;
587       valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string, true);
588       if (valobj_sp)
589         break;
590     }
591   }
592 
593   if (var_sp && !valobj_sp) {
594     valobj_sp = GetValueObjectForFrameVariable(var_sp, use_dynamic);
595     if (!valobj_sp)
596       return valobj_sp;
597   }
598   if (!valobj_sp) {
599     error.SetErrorStringWithFormat("no variable named '%s' found in this frame",
600                                    name_const_string.GetCString());
601     return ValueObjectSP();
602   }
603 
604   // We are dumping at least one child
605   while (separator_idx != std::string::npos) {
606     // Calculate the next separator index ahead of time
607     ValueObjectSP child_valobj_sp;
608     const char separator_type = var_expr[0];
609     bool expr_is_ptr = false;
610     switch (separator_type) {
611     case '-':
612       expr_is_ptr = true;
613       if (var_expr.size() >= 2 && var_expr[1] != '>')
614         return ValueObjectSP();
615 
616       if (no_fragile_ivar) {
617         // Make sure we aren't trying to deref an objective
618         // C ivar if this is not allowed
619         const uint32_t pointer_type_flags =
620             valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
621         if ((pointer_type_flags & eTypeIsObjC) &&
622             (pointer_type_flags & eTypeIsPointer)) {
623           // This was an objective C object pointer and
624           // it was requested we skip any fragile ivars
625           // so return nothing here
626           return ValueObjectSP();
627         }
628       }
629 
630       // If we have a non pointer type with a sythetic value then lets check if
631       // we have an sythetic dereference specified.
632       if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
633         Error deref_error;
634         if (valobj_sp->GetCompilerType().IsReferenceType()) {
635           valobj_sp = valobj_sp->GetSyntheticValue()->Dereference(deref_error);
636           if (error.Fail()) {
637             error.SetErrorStringWithFormatv(
638                 "Failed to dereference reference type: %s", deref_error);
639             return ValueObjectSP();
640           }
641         }
642 
643         valobj_sp = valobj_sp->Dereference(deref_error);
644         if (error.Fail()) {
645           error.SetErrorStringWithFormatv(
646               "Failed to dereference sythetic value: %s", deref_error);
647           return ValueObjectSP();
648         }
649         expr_is_ptr = false;
650       }
651 
652       var_expr = var_expr.drop_front(); // Remove the '-'
653       LLVM_FALLTHROUGH;
654     case '.': {
655       var_expr = var_expr.drop_front(); // Remove the '.' or '>'
656       separator_idx = var_expr.find_first_of(".-[");
657       ConstString child_name(var_expr.substr(0, var_expr.find_first_of(".-[")));
658 
659       if (check_ptr_vs_member) {
660         // We either have a pointer type and need to verify
661         // valobj_sp is a pointer, or we have a member of a
662         // class/union/struct being accessed with the . syntax
663         // and need to verify we don't have a pointer.
664         const bool actual_is_ptr = valobj_sp->IsPointerType();
665 
666         if (actual_is_ptr != expr_is_ptr) {
667           // Incorrect use of "." with a pointer, or "->" with
668           // a class/union/struct instance or reference.
669           valobj_sp->GetExpressionPath(var_expr_path_strm, false);
670           if (actual_is_ptr)
671             error.SetErrorStringWithFormat(
672                 "\"%s\" is a pointer and . was used to attempt to access "
673                 "\"%s\". Did you mean \"%s->%s\"?",
674                 var_expr_path_strm.GetData(), child_name.GetCString(),
675                 var_expr_path_strm.GetData(), var_expr.str().c_str());
676           else
677             error.SetErrorStringWithFormat(
678                 "\"%s\" is not a pointer and -> was used to attempt to "
679                 "access \"%s\". Did you mean \"%s.%s\"?",
680                 var_expr_path_strm.GetData(), child_name.GetCString(),
681                 var_expr_path_strm.GetData(), var_expr.str().c_str());
682           return ValueObjectSP();
683         }
684       }
685       child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name, true);
686       if (!child_valobj_sp) {
687         if (!no_synth_child) {
688           child_valobj_sp = valobj_sp->GetSyntheticValue();
689           if (child_valobj_sp)
690             child_valobj_sp =
691                 child_valobj_sp->GetChildMemberWithName(child_name, true);
692         }
693 
694         if (no_synth_child || !child_valobj_sp) {
695           // No child member with name "child_name"
696           if (synthetically_added_instance_object) {
697             // We added a "this->" or "self->" to the beginning of the
698             // expression
699             // and this is the first pointer ivar access, so just return
700             // the normal
701             // error
702             error.SetErrorStringWithFormat(
703                 "no variable or instance variable named '%s' found in "
704                 "this frame",
705                 name_const_string.GetCString());
706           } else {
707             valobj_sp->GetExpressionPath(var_expr_path_strm, false);
708             if (child_name) {
709               error.SetErrorStringWithFormat(
710                   "\"%s\" is not a member of \"(%s) %s\"",
711                   child_name.GetCString(),
712                   valobj_sp->GetTypeName().AsCString("<invalid type>"),
713                   var_expr_path_strm.GetData());
714             } else {
715               error.SetErrorStringWithFormat(
716                   "incomplete expression path after \"%s\" in \"%s\"",
717                   var_expr_path_strm.GetData(),
718                   original_var_expr.str().c_str());
719             }
720           }
721           return ValueObjectSP();
722         }
723       }
724       synthetically_added_instance_object = false;
725       // Remove the child name from the path
726       var_expr = var_expr.drop_front(child_name.GetLength());
727       if (use_dynamic != eNoDynamicValues) {
728         ValueObjectSP dynamic_value_sp(
729             child_valobj_sp->GetDynamicValue(use_dynamic));
730         if (dynamic_value_sp)
731           child_valobj_sp = dynamic_value_sp;
732       }
733     } break;
734 
735     case '[': {
736       // Array member access, or treating pointer as an array
737       // Need at least two brackets and a number
738       if (var_expr.size() <= 2) {
739         error.SetErrorStringWithFormat(
740             "invalid square bracket encountered after \"%s\" in \"%s\"",
741             var_expr_path_strm.GetData(), var_expr.str().c_str());
742         return ValueObjectSP();
743       }
744 
745       // Drop the open brace.
746       var_expr = var_expr.drop_front();
747       long child_index = 0;
748 
749       // If there's no closing brace, this is an invalid expression.
750       size_t end_pos = var_expr.find_first_of(']');
751       if (end_pos == llvm::StringRef::npos) {
752         error.SetErrorStringWithFormat(
753             "missing closing square bracket in expression \"%s\"",
754             var_expr_path_strm.GetData());
755         return ValueObjectSP();
756       }
757       llvm::StringRef index_expr = var_expr.take_front(end_pos);
758       llvm::StringRef original_index_expr = index_expr;
759       // Drop all of "[index_expr]"
760       var_expr = var_expr.drop_front(end_pos + 1);
761 
762       if (index_expr.consumeInteger(0, child_index)) {
763         // If there was no integer anywhere in the index expression, this is
764         // erroneous expression.
765         error.SetErrorStringWithFormat("invalid index expression \"%s\"",
766                                        index_expr.str().c_str());
767         return ValueObjectSP();
768       }
769 
770       if (index_expr.empty()) {
771         // The entire index expression was a single integer.
772 
773         if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
774           // what we have is *ptr[low]. the most similar C++ syntax is to deref
775           // ptr and extract bit low out of it. reading array item low would be
776           // done by saying ptr[low], without a deref * sign
777           Error error;
778           ValueObjectSP temp(valobj_sp->Dereference(error));
779           if (error.Fail()) {
780             valobj_sp->GetExpressionPath(var_expr_path_strm, false);
781             error.SetErrorStringWithFormat(
782                 "could not dereference \"(%s) %s\"",
783                 valobj_sp->GetTypeName().AsCString("<invalid type>"),
784                 var_expr_path_strm.GetData());
785             return ValueObjectSP();
786           }
787           valobj_sp = temp;
788           deref = false;
789         } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
790                    deref) {
791           // what we have is *arr[low]. the most similar C++ syntax is
792           // to get arr[0]
793           // (an operation that is equivalent to deref-ing arr)
794           // and extract bit low out of it. reading array item low
795           // would be done by saying arr[low], without a deref * sign
796           Error error;
797           ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
798           if (error.Fail()) {
799             valobj_sp->GetExpressionPath(var_expr_path_strm, false);
800             error.SetErrorStringWithFormat(
801                 "could not get item 0 for \"(%s) %s\"",
802                 valobj_sp->GetTypeName().AsCString("<invalid type>"),
803                 var_expr_path_strm.GetData());
804             return ValueObjectSP();
805           }
806           valobj_sp = temp;
807           deref = false;
808         }
809 
810         bool is_incomplete_array = false;
811         if (valobj_sp->IsPointerType()) {
812           bool is_objc_pointer = true;
813 
814           if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
815               eLanguageTypeObjC)
816             is_objc_pointer = false;
817           else if (!valobj_sp->GetCompilerType().IsPointerType())
818             is_objc_pointer = false;
819 
820           if (no_synth_child && is_objc_pointer) {
821             error.SetErrorStringWithFormat(
822                 "\"(%s) %s\" is an Objective-C pointer, and cannot be "
823                 "subscripted",
824                 valobj_sp->GetTypeName().AsCString("<invalid type>"),
825                 var_expr_path_strm.GetData());
826 
827             return ValueObjectSP();
828           } else if (is_objc_pointer) {
829             // dereferencing ObjC variables is not valid.. so let's try
830             // and recur to synthetic children
831             ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
832             if (!synthetic                 /* no synthetic */
833                 || synthetic == valobj_sp) /* synthetic is the same as
834                                               the original object */
835             {
836               valobj_sp->GetExpressionPath(var_expr_path_strm, false);
837               error.SetErrorStringWithFormat(
838                   "\"(%s) %s\" is not an array type",
839                   valobj_sp->GetTypeName().AsCString("<invalid type>"),
840                   var_expr_path_strm.GetData());
841             } else if (
842                 static_cast<uint32_t>(child_index) >=
843                 synthetic
844                     ->GetNumChildren() /* synthetic does not have that many values */) {
845               valobj_sp->GetExpressionPath(var_expr_path_strm, false);
846               error.SetErrorStringWithFormat(
847                   "array index %ld is not valid for \"(%s) %s\"", child_index,
848                   valobj_sp->GetTypeName().AsCString("<invalid type>"),
849                   var_expr_path_strm.GetData());
850             } else {
851               child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
852               if (!child_valobj_sp) {
853                 valobj_sp->GetExpressionPath(var_expr_path_strm, false);
854                 error.SetErrorStringWithFormat(
855                     "array index %ld is not valid for \"(%s) %s\"", child_index,
856                     valobj_sp->GetTypeName().AsCString("<invalid type>"),
857                     var_expr_path_strm.GetData());
858               }
859             }
860           } else {
861             child_valobj_sp =
862                 valobj_sp->GetSyntheticArrayMember(child_index, true);
863             if (!child_valobj_sp) {
864               valobj_sp->GetExpressionPath(var_expr_path_strm, false);
865               error.SetErrorStringWithFormat(
866                   "failed to use pointer as array for index %ld for "
867                   "\"(%s) %s\"",
868                   child_index,
869                   valobj_sp->GetTypeName().AsCString("<invalid type>"),
870                   var_expr_path_strm.GetData());
871             }
872           }
873         } else if (valobj_sp->GetCompilerType().IsArrayType(
874                        nullptr, nullptr, &is_incomplete_array)) {
875           // Pass false to dynamic_value here so we can tell the
876           // difference between
877           // no dynamic value and no member of this type...
878           child_valobj_sp = valobj_sp->GetChildAtIndex(child_index, true);
879           if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
880             child_valobj_sp =
881                 valobj_sp->GetSyntheticArrayMember(child_index, true);
882 
883           if (!child_valobj_sp) {
884             valobj_sp->GetExpressionPath(var_expr_path_strm, false);
885             error.SetErrorStringWithFormat(
886                 "array index %ld is not valid for \"(%s) %s\"", child_index,
887                 valobj_sp->GetTypeName().AsCString("<invalid type>"),
888                 var_expr_path_strm.GetData());
889           }
890         } else if (valobj_sp->GetCompilerType().IsScalarType()) {
891           // this is a bitfield asking to display just one bit
892           child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
893               child_index, child_index, true);
894           if (!child_valobj_sp) {
895             valobj_sp->GetExpressionPath(var_expr_path_strm, false);
896             error.SetErrorStringWithFormat(
897                 "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
898                 child_index, child_index,
899                 valobj_sp->GetTypeName().AsCString("<invalid type>"),
900                 var_expr_path_strm.GetData());
901           }
902         } else {
903           ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
904           if (no_synth_child /* synthetic is forbidden */ ||
905               !synthetic                 /* no synthetic */
906               || synthetic == valobj_sp) /* synthetic is the same as the
907                                             original object */
908           {
909             valobj_sp->GetExpressionPath(var_expr_path_strm, false);
910             error.SetErrorStringWithFormat(
911                 "\"(%s) %s\" is not an array type",
912                 valobj_sp->GetTypeName().AsCString("<invalid type>"),
913                 var_expr_path_strm.GetData());
914           } else if (
915               static_cast<uint32_t>(child_index) >=
916               synthetic
917                   ->GetNumChildren() /* synthetic does not have that many values */) {
918             valobj_sp->GetExpressionPath(var_expr_path_strm, false);
919             error.SetErrorStringWithFormat(
920                 "array index %ld is not valid for \"(%s) %s\"", child_index,
921                 valobj_sp->GetTypeName().AsCString("<invalid type>"),
922                 var_expr_path_strm.GetData());
923           } else {
924             child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
925             if (!child_valobj_sp) {
926               valobj_sp->GetExpressionPath(var_expr_path_strm, false);
927               error.SetErrorStringWithFormat(
928                   "array index %ld is not valid for \"(%s) %s\"", child_index,
929                   valobj_sp->GetTypeName().AsCString("<invalid type>"),
930                   var_expr_path_strm.GetData());
931             }
932           }
933         }
934 
935         if (!child_valobj_sp) {
936           // Invalid array index...
937           return ValueObjectSP();
938         }
939 
940         separator_idx = var_expr.find_first_of(".-[");
941         if (use_dynamic != eNoDynamicValues) {
942           ValueObjectSP dynamic_value_sp(
943               child_valobj_sp->GetDynamicValue(use_dynamic));
944           if (dynamic_value_sp)
945             child_valobj_sp = dynamic_value_sp;
946         }
947         // Break out early from the switch since we were able to find the child
948         // member
949         break;
950       }
951 
952       // this is most probably a BitField, let's take a look
953       if (index_expr.front() != '-') {
954         error.SetErrorStringWithFormat("invalid range expression \"'%s'\"",
955                                        original_index_expr.str().c_str());
956         return ValueObjectSP();
957       }
958 
959       index_expr = index_expr.drop_front();
960       long final_index = 0;
961       if (index_expr.getAsInteger(0, final_index)) {
962         error.SetErrorStringWithFormat("invalid range expression \"'%s'\"",
963                                        original_index_expr.str().c_str());
964         return ValueObjectSP();
965       }
966 
967       // if the format given is [high-low], swap range
968       if (child_index > final_index) {
969         long temp = child_index;
970         child_index = final_index;
971         final_index = temp;
972       }
973 
974       if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
975         // what we have is *ptr[low-high]. the most similar C++ syntax is to
976         // deref ptr and extract bits low thru high out of it. reading array
977         // items low thru high would be done by saying ptr[low-high], without
978         // a deref * sign
979         Error error;
980         ValueObjectSP temp(valobj_sp->Dereference(error));
981         if (error.Fail()) {
982           valobj_sp->GetExpressionPath(var_expr_path_strm, false);
983           error.SetErrorStringWithFormat(
984               "could not dereference \"(%s) %s\"",
985               valobj_sp->GetTypeName().AsCString("<invalid type>"),
986               var_expr_path_strm.GetData());
987           return ValueObjectSP();
988         }
989         valobj_sp = temp;
990         deref = false;
991       } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
992         // what we have is *arr[low-high]. the most similar C++ syntax is to get
993         // arr[0] (an operation that is equivalent to deref-ing arr) and extract
994         // bits low thru high out of it. reading array items low thru high would
995         // be done by saying arr[low-high], without a deref * sign
996         Error error;
997         ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
998         if (error.Fail()) {
999           valobj_sp->GetExpressionPath(var_expr_path_strm, false);
1000           error.SetErrorStringWithFormat(
1001               "could not get item 0 for \"(%s) %s\"",
1002               valobj_sp->GetTypeName().AsCString("<invalid type>"),
1003               var_expr_path_strm.GetData());
1004           return ValueObjectSP();
1005         }
1006         valobj_sp = temp;
1007         deref = false;
1008       }
1009 
1010       child_valobj_sp =
1011           valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
1012       if (!child_valobj_sp) {
1013         valobj_sp->GetExpressionPath(var_expr_path_strm, false);
1014         error.SetErrorStringWithFormat(
1015             "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
1016             final_index, valobj_sp->GetTypeName().AsCString("<invalid type>"),
1017             var_expr_path_strm.GetData());
1018       }
1019 
1020       if (!child_valobj_sp) {
1021         // Invalid bitfield range...
1022         return ValueObjectSP();
1023       }
1024 
1025       separator_idx = var_expr.find_first_of(".-[");
1026       if (use_dynamic != eNoDynamicValues) {
1027         ValueObjectSP dynamic_value_sp(
1028             child_valobj_sp->GetDynamicValue(use_dynamic));
1029         if (dynamic_value_sp)
1030           child_valobj_sp = dynamic_value_sp;
1031       }
1032       // Break out early from the switch since we were able to find the child
1033       // member
1034       break;
1035     }
1036     default:
1037       // Failure...
1038       {
1039         valobj_sp->GetExpressionPath(var_expr_path_strm, false);
1040         error.SetErrorStringWithFormat(
1041             "unexpected char '%c' encountered after \"%s\" in \"%s\"",
1042             separator_type, var_expr_path_strm.GetData(),
1043             var_expr.str().c_str());
1044 
1045         return ValueObjectSP();
1046       }
1047     }
1048 
1049     if (child_valobj_sp)
1050       valobj_sp = child_valobj_sp;
1051 
1052     if (var_expr.empty())
1053       break;
1054   }
1055   if (valobj_sp) {
1056     if (deref) {
1057       ValueObjectSP deref_valobj_sp(valobj_sp->Dereference(error));
1058       valobj_sp = deref_valobj_sp;
1059     } else if (address_of) {
1060       ValueObjectSP address_of_valobj_sp(valobj_sp->AddressOf(error));
1061       valobj_sp = address_of_valobj_sp;
1062     }
1063   }
1064   return valobj_sp;
1065 }
1066 
1067 bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Error *error_ptr) {
1068   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1069   if (!m_cfa_is_valid) {
1070     m_frame_base_error.SetErrorString(
1071         "No frame base available for this historical stack frame.");
1072     return false;
1073   }
1074 
1075   if (m_flags.IsClear(GOT_FRAME_BASE)) {
1076     if (m_sc.function) {
1077       m_frame_base.Clear();
1078       m_frame_base_error.Clear();
1079 
1080       m_flags.Set(GOT_FRAME_BASE);
1081       ExecutionContext exe_ctx(shared_from_this());
1082       Value expr_value;
1083       addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
1084       if (m_sc.function->GetFrameBaseExpression().IsLocationList())
1085         loclist_base_addr =
1086             m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
1087                 exe_ctx.GetTargetPtr());
1088 
1089       if (m_sc.function->GetFrameBaseExpression().Evaluate(
1090               &exe_ctx, nullptr, nullptr, nullptr, loclist_base_addr, nullptr,
1091               nullptr, expr_value, &m_frame_base_error) == false) {
1092         // We should really have an error if evaluate returns, but in case
1093         // we don't, lets set the error to something at least.
1094         if (m_frame_base_error.Success())
1095           m_frame_base_error.SetErrorString(
1096               "Evaluation of the frame base expression failed.");
1097       } else {
1098         m_frame_base = expr_value.ResolveValue(&exe_ctx);
1099       }
1100     } else {
1101       m_frame_base_error.SetErrorString("No function in symbol context.");
1102     }
1103   }
1104 
1105   if (m_frame_base_error.Success())
1106     frame_base = m_frame_base;
1107 
1108   if (error_ptr)
1109     *error_ptr = m_frame_base_error;
1110   return m_frame_base_error.Success();
1111 }
1112 
1113 DWARFExpression *StackFrame::GetFrameBaseExpression(Error *error_ptr) {
1114   if (!m_sc.function) {
1115     if (error_ptr) {
1116       error_ptr->SetErrorString("No function in symbol context.");
1117     }
1118     return nullptr;
1119   }
1120 
1121   return &m_sc.function->GetFrameBaseExpression();
1122 }
1123 
1124 RegisterContextSP StackFrame::GetRegisterContext() {
1125   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1126   if (!m_reg_context_sp) {
1127     ThreadSP thread_sp(GetThread());
1128     if (thread_sp)
1129       m_reg_context_sp = thread_sp->CreateRegisterContextForFrame(this);
1130   }
1131   return m_reg_context_sp;
1132 }
1133 
1134 bool StackFrame::HasDebugInformation() {
1135   GetSymbolContext(eSymbolContextLineEntry);
1136   return m_sc.line_entry.IsValid();
1137 }
1138 
1139 ValueObjectSP
1140 StackFrame::GetValueObjectForFrameVariable(const VariableSP &variable_sp,
1141                                            DynamicValueType use_dynamic) {
1142   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1143   ValueObjectSP valobj_sp;
1144   if (m_is_history_frame) {
1145     return valobj_sp;
1146   }
1147   VariableList *var_list = GetVariableList(true);
1148   if (var_list) {
1149     // Make sure the variable is a frame variable
1150     const uint32_t var_idx = var_list->FindIndexForVariable(variable_sp.get());
1151     const uint32_t num_variables = var_list->GetSize();
1152     if (var_idx < num_variables) {
1153       valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex(var_idx);
1154       if (!valobj_sp) {
1155         if (m_variable_list_value_objects.GetSize() < num_variables)
1156           m_variable_list_value_objects.Resize(num_variables);
1157         valobj_sp = ValueObjectVariable::Create(this, variable_sp);
1158         m_variable_list_value_objects.SetValueObjectAtIndex(var_idx, valobj_sp);
1159       }
1160     }
1161   }
1162   if (use_dynamic != eNoDynamicValues && valobj_sp) {
1163     ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
1164     if (dynamic_sp)
1165       return dynamic_sp;
1166   }
1167   return valobj_sp;
1168 }
1169 
1170 ValueObjectSP StackFrame::TrackGlobalVariable(const VariableSP &variable_sp,
1171                                               DynamicValueType use_dynamic) {
1172   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1173   if (m_is_history_frame)
1174     return ValueObjectSP();
1175 
1176   // Check to make sure we aren't already tracking this variable?
1177   ValueObjectSP valobj_sp(
1178       GetValueObjectForFrameVariable(variable_sp, use_dynamic));
1179   if (!valobj_sp) {
1180     // We aren't already tracking this global
1181     VariableList *var_list = GetVariableList(true);
1182     // If this frame has no variables, create a new list
1183     if (var_list == nullptr)
1184       m_variable_list_sp.reset(new VariableList());
1185 
1186     // Add the global/static variable to this frame
1187     m_variable_list_sp->AddVariable(variable_sp);
1188 
1189     // Now make a value object for it so we can track its changes
1190     valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic);
1191   }
1192   return valobj_sp;
1193 }
1194 
1195 bool StackFrame::IsInlined() {
1196   if (m_sc.block == nullptr)
1197     GetSymbolContext(eSymbolContextBlock);
1198   if (m_sc.block)
1199     return m_sc.block->GetContainingInlinedBlock() != nullptr;
1200   return false;
1201 }
1202 
1203 lldb::LanguageType StackFrame::GetLanguage() {
1204   CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
1205   if (cu)
1206     return cu->GetLanguage();
1207   return lldb::eLanguageTypeUnknown;
1208 }
1209 
1210 lldb::LanguageType StackFrame::GuessLanguage() {
1211   LanguageType lang_type = GetLanguage();
1212 
1213   if (lang_type == eLanguageTypeUnknown) {
1214     Function *f = GetSymbolContext(eSymbolContextFunction).function;
1215     if (f) {
1216       lang_type = f->GetMangled().GuessLanguage();
1217     }
1218   }
1219 
1220   return lang_type;
1221 }
1222 
1223 namespace {
1224 std::pair<const Instruction::Operand *, int64_t>
1225 GetBaseExplainingValue(const Instruction::Operand &operand,
1226                        RegisterContext &register_context, lldb::addr_t value) {
1227   switch (operand.m_type) {
1228   case Instruction::Operand::Type::Dereference:
1229   case Instruction::Operand::Type::Immediate:
1230   case Instruction::Operand::Type::Invalid:
1231   case Instruction::Operand::Type::Product:
1232     // These are not currently interesting
1233     return std::make_pair(nullptr, 0);
1234   case Instruction::Operand::Type::Sum: {
1235     const Instruction::Operand *immediate_child = nullptr;
1236     const Instruction::Operand *variable_child = nullptr;
1237     if (operand.m_children[0].m_type == Instruction::Operand::Type::Immediate) {
1238       immediate_child = &operand.m_children[0];
1239       variable_child = &operand.m_children[1];
1240     } else if (operand.m_children[1].m_type ==
1241                Instruction::Operand::Type::Immediate) {
1242       immediate_child = &operand.m_children[1];
1243       variable_child = &operand.m_children[0];
1244     }
1245     if (!immediate_child) {
1246       return std::make_pair(nullptr, 0);
1247     }
1248     lldb::addr_t adjusted_value = value;
1249     if (immediate_child->m_negative) {
1250       adjusted_value += immediate_child->m_immediate;
1251     } else {
1252       adjusted_value -= immediate_child->m_immediate;
1253     }
1254     std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1255         GetBaseExplainingValue(*variable_child, register_context,
1256                                adjusted_value);
1257     if (!base_and_offset.first) {
1258       return std::make_pair(nullptr, 0);
1259     }
1260     if (immediate_child->m_negative) {
1261       base_and_offset.second -= immediate_child->m_immediate;
1262     } else {
1263       base_and_offset.second += immediate_child->m_immediate;
1264     }
1265     return base_and_offset;
1266   }
1267   case Instruction::Operand::Type::Register: {
1268     const RegisterInfo *info =
1269         register_context.GetRegisterInfoByName(operand.m_register.AsCString());
1270     if (!info) {
1271       return std::make_pair(nullptr, 0);
1272     }
1273     RegisterValue reg_value;
1274     if (!register_context.ReadRegister(info, reg_value)) {
1275       return std::make_pair(nullptr, 0);
1276     }
1277     if (reg_value.GetAsUInt64() == value) {
1278       return std::make_pair(&operand, 0);
1279     } else {
1280       return std::make_pair(nullptr, 0);
1281     }
1282   }
1283   }
1284   return std::make_pair(nullptr, 0);
1285 }
1286 
1287 std::pair<const Instruction::Operand *, int64_t>
1288 GetBaseExplainingDereference(const Instruction::Operand &operand,
1289                              RegisterContext &register_context,
1290                              lldb::addr_t addr) {
1291   if (operand.m_type == Instruction::Operand::Type::Dereference) {
1292     return GetBaseExplainingValue(operand.m_children[0], register_context,
1293                                   addr);
1294   }
1295   return std::make_pair(nullptr, 0);
1296 }
1297 }
1298 
1299 lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) {
1300   TargetSP target_sp = CalculateTarget();
1301 
1302   const ArchSpec &target_arch = target_sp->GetArchitecture();
1303 
1304   AddressRange pc_range;
1305   pc_range.GetBaseAddress() = GetFrameCodeAddress();
1306   pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize());
1307 
1308   ExecutionContext exe_ctx(shared_from_this());
1309 
1310   const char *plugin_name = nullptr;
1311   const char *flavor = nullptr;
1312   const bool prefer_file_cache = false;
1313 
1314   DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
1315       target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache);
1316 
1317   if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1318     return ValueObjectSP();
1319   }
1320 
1321   InstructionSP instruction_sp =
1322       disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1323 
1324   llvm::SmallVector<Instruction::Operand, 3> operands;
1325 
1326   if (!instruction_sp->ParseOperands(operands)) {
1327     return ValueObjectSP();
1328   }
1329 
1330   RegisterContextSP register_context_sp = GetRegisterContext();
1331 
1332   if (!register_context_sp) {
1333     return ValueObjectSP();
1334   }
1335 
1336   for (const Instruction::Operand &operand : operands) {
1337     std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1338         GetBaseExplainingDereference(operand, *register_context_sp, addr);
1339 
1340     if (!base_and_offset.first) {
1341       continue;
1342     }
1343 
1344     switch (base_and_offset.first->m_type) {
1345     case Instruction::Operand::Type::Immediate: {
1346       lldb_private::Address addr;
1347       if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
1348                                             base_and_offset.second,
1349                                         addr)) {
1350         TypeSystem *c_type_system =
1351             target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
1352         if (!c_type_system) {
1353           return ValueObjectSP();
1354         } else {
1355           CompilerType void_ptr_type =
1356               c_type_system
1357                   ->GetBasicTypeFromAST(lldb::BasicType::eBasicTypeChar)
1358                   .GetPointerType();
1359           return ValueObjectMemory::Create(this, "", addr, void_ptr_type);
1360         }
1361       } else {
1362         return ValueObjectSP();
1363       }
1364       break;
1365     }
1366     case Instruction::Operand::Type::Register: {
1367       return GuessValueForRegisterAndOffset(base_and_offset.first->m_register,
1368                                             base_and_offset.second);
1369     }
1370     default:
1371       return ValueObjectSP();
1372     }
1373   }
1374 
1375   return ValueObjectSP();
1376 }
1377 
1378 namespace {
1379 ValueObjectSP GetValueForOffset(StackFrame &frame, ValueObjectSP &parent,
1380                                 int64_t offset) {
1381   if (offset < 0 || uint64_t(offset) >= parent->GetByteSize()) {
1382     return ValueObjectSP();
1383   }
1384 
1385   if (parent->IsPointerOrReferenceType()) {
1386     return parent;
1387   }
1388 
1389   for (int ci = 0, ce = parent->GetNumChildren(); ci != ce; ++ci) {
1390     const bool can_create = true;
1391     ValueObjectSP child_sp = parent->GetChildAtIndex(ci, can_create);
1392 
1393     if (!child_sp) {
1394       return ValueObjectSP();
1395     }
1396 
1397     int64_t child_offset = child_sp->GetByteOffset();
1398     int64_t child_size = child_sp->GetByteSize();
1399 
1400     if (offset >= child_offset && offset < (child_offset + child_size)) {
1401       return GetValueForOffset(frame, child_sp, offset - child_offset);
1402     }
1403   }
1404 
1405   if (offset == 0) {
1406     return parent;
1407   } else {
1408     return ValueObjectSP();
1409   }
1410 }
1411 
1412 ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
1413                                              ValueObjectSP &base,
1414                                              int64_t offset) {
1415   // base is a pointer to something
1416   // offset is the thing to add to the pointer
1417   // We return the most sensible ValueObject for the result of *(base+offset)
1418 
1419   if (!base->IsPointerOrReferenceType()) {
1420     return ValueObjectSP();
1421   }
1422 
1423   Error error;
1424   ValueObjectSP pointee = base->Dereference(error);
1425 
1426   if (!pointee) {
1427     return ValueObjectSP();
1428   }
1429 
1430   if (offset >= 0 && uint64_t(offset) >= pointee->GetByteSize()) {
1431     int64_t index = offset / pointee->GetByteSize();
1432     offset = offset % pointee->GetByteSize();
1433     const bool can_create = true;
1434     pointee = base->GetSyntheticArrayMember(index, can_create);
1435   }
1436 
1437   if (!pointee || error.Fail()) {
1438     return ValueObjectSP();
1439   }
1440 
1441   return GetValueForOffset(frame, pointee, offset);
1442 }
1443 
1444 //------------------------------------------------------------------
1445 /// Attempt to reconstruct the ValueObject for the address contained in a
1446 /// given register plus an offset.
1447 ///
1448 /// @params [in] frame
1449 ///   The current stack frame.
1450 ///
1451 /// @params [in] reg
1452 ///   The register.
1453 ///
1454 /// @params [in] offset
1455 ///   The offset from the register.
1456 ///
1457 /// @param [in] disassembler
1458 ///   A disassembler containing instructions valid up to the current PC.
1459 ///
1460 /// @param [in] variables
1461 ///   The variable list from the current frame,
1462 ///
1463 /// @param [in] pc
1464 ///   The program counter for the instruction considered the 'user'.
1465 ///
1466 /// @return
1467 ///   A string describing the base for the ExpressionPath.  This could be a
1468 ///     variable, a register value, an argument, or a function return value.
1469 ///   The ValueObject if found.  If valid, it has a valid ExpressionPath.
1470 //------------------------------------------------------------------
1471 lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
1472                                    int64_t offset, Disassembler &disassembler,
1473                                    VariableList &variables, const Address &pc) {
1474   // Example of operation for Intel:
1475   //
1476   // +14: movq   -0x8(%rbp), %rdi
1477   // +18: movq   0x8(%rdi), %rdi
1478   // +22: addl   0x4(%rdi), %eax
1479   //
1480   // f, a pointer to a struct, is known to be at -0x8(%rbp).
1481   //
1482   // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at +18
1483   // that assigns to rdi, and calls itself recursively for that dereference
1484   //   DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at
1485   //   +14 that assigns to rdi, and calls itself recursively for that
1486   //   derefernece
1487   //     DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the
1488   //     variable list.
1489   //     Returns a ValueObject for f.  (That's what was stored at rbp-8 at +14)
1490   //   Returns a ValueObject for *(f+8) or f->b (That's what was stored at rdi+8
1491   //   at +18)
1492   // Returns a ValueObject for *(f->b+4) or f->b->a (That's what was stored at
1493   // rdi+4 at +22)
1494 
1495   // First, check the variable list to see if anything is at the specified
1496   // location.
1497 
1498   using namespace OperandMatchers;
1499 
1500   const RegisterInfo *reg_info =
1501       frame.GetRegisterContext()->GetRegisterInfoByName(reg.AsCString());
1502   if (!reg_info) {
1503     return ValueObjectSP();
1504   }
1505 
1506   Instruction::Operand op =
1507       offset ? Instruction::Operand::BuildDereference(
1508                    Instruction::Operand::BuildSum(
1509                        Instruction::Operand::BuildRegister(reg),
1510                        Instruction::Operand::BuildImmediate(offset)))
1511              : Instruction::Operand::BuildDereference(
1512                    Instruction::Operand::BuildRegister(reg));
1513 
1514   for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi) {
1515     VariableSP var_sp = variables.GetVariableAtIndex(vi);
1516     if (var_sp->LocationExpression().MatchesOperand(frame, op)) {
1517       return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
1518     }
1519   }
1520 
1521   const uint32_t current_inst =
1522       disassembler.GetInstructionList().GetIndexOfInstructionAtAddress(pc);
1523   if (current_inst == UINT32_MAX) {
1524     return ValueObjectSP();
1525   }
1526 
1527   for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
1528     // This is not an exact algorithm, and it sacrifices accuracy for
1529     // generality.  Recognizing "mov" and "ld" instructions –– and which are
1530     // their source and destination operands -- is something the disassembler
1531     // should do for us.
1532     InstructionSP instruction_sp =
1533         disassembler.GetInstructionList().GetInstructionAtIndex(ii);
1534 
1535     if (instruction_sp->IsCall()) {
1536       ABISP abi_sp = frame.CalculateProcess()->GetABI();
1537       if (!abi_sp) {
1538         continue;
1539       }
1540 
1541       const char *return_register_name;
1542       if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1543         continue;
1544       }
1545 
1546       const RegisterInfo *return_register_info =
1547           frame.GetRegisterContext()->GetRegisterInfoByName(
1548               return_register_name);
1549       if (!return_register_info) {
1550         continue;
1551       }
1552 
1553       int64_t offset = 0;
1554 
1555       if (!MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference),
1556                         MatchRegOp(*return_register_info))(op) &&
1557           !MatchUnaryOp(
1558               MatchOpType(Instruction::Operand::Type::Dereference),
1559               MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),
1560                             MatchRegOp(*return_register_info),
1561                             FetchImmOp(offset)))(op)) {
1562         continue;
1563       }
1564 
1565       llvm::SmallVector<Instruction::Operand, 1> operands;
1566       if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1567         continue;
1568       }
1569 
1570       switch (operands[0].m_type) {
1571       default:
1572         break;
1573       case Instruction::Operand::Type::Immediate: {
1574         SymbolContext sc;
1575         Address load_address;
1576         if (!frame.CalculateTarget()->ResolveLoadAddress(
1577                 operands[0].m_immediate, load_address)) {
1578           break;
1579         }
1580         frame.CalculateTarget()->GetImages().ResolveSymbolContextForAddress(
1581             load_address, eSymbolContextFunction, sc);
1582         if (!sc.function) {
1583           break;
1584         }
1585         CompilerType function_type = sc.function->GetCompilerType();
1586         if (!function_type.IsFunctionType()) {
1587           break;
1588         }
1589         CompilerType return_type = function_type.GetFunctionReturnType();
1590         RegisterValue return_value;
1591         if (!frame.GetRegisterContext()->ReadRegister(return_register_info,
1592                                                       return_value)) {
1593           break;
1594         }
1595         std::string name_str(
1596             sc.function->GetName().AsCString("<unknown function>"));
1597         name_str.append("()");
1598         Address return_value_address(return_value.GetAsUInt64());
1599         ValueObjectSP return_value_sp = ValueObjectMemory::Create(
1600             &frame, name_str, return_value_address, return_type);
1601         return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1602       }
1603       }
1604 
1605       continue;
1606     }
1607 
1608     llvm::SmallVector<Instruction::Operand, 2> operands;
1609     if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1610       continue;
1611     }
1612 
1613     Instruction::Operand *origin_operand = nullptr;
1614     auto clobbered_reg_matcher = [reg_info](const Instruction::Operand &op) {
1615       return MatchRegOp(*reg_info)(op) && op.m_clobbered;
1616     };
1617 
1618     if (clobbered_reg_matcher(operands[0])) {
1619       origin_operand = &operands[1];
1620     }
1621     else if (clobbered_reg_matcher(operands[1])) {
1622       origin_operand = &operands[0];
1623     }
1624     else {
1625       continue;
1626     }
1627 
1628     // We have an origin operand.  Can we track its value down?
1629     ValueObjectSP source_path;
1630     ConstString origin_register;
1631     int64_t origin_offset = 0;
1632 
1633     if (FetchRegOp(origin_register)(*origin_operand)) {
1634       source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1635                                    variables, instruction_sp->GetAddress());
1636     } else if (MatchUnaryOp(
1637                    MatchOpType(Instruction::Operand::Type::Dereference),
1638                    FetchRegOp(origin_register))(*origin_operand) ||
1639                MatchUnaryOp(
1640                    MatchOpType(Instruction::Operand::Type::Dereference),
1641                    MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),
1642                                  FetchRegOp(origin_register),
1643                                  FetchImmOp(origin_offset)))(*origin_operand)) {
1644       source_path =
1645           DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
1646                          variables, instruction_sp->GetAddress());
1647       if (!source_path) {
1648         continue;
1649       }
1650       source_path =
1651           GetValueForDereferincingOffset(frame, source_path, offset);
1652     }
1653 
1654     if (source_path) {
1655       return source_path;
1656     }
1657   }
1658 
1659   return ValueObjectSP();
1660 }
1661 }
1662 
1663 lldb::ValueObjectSP StackFrame::GuessValueForRegisterAndOffset(ConstString reg,
1664                                                                int64_t offset) {
1665   TargetSP target_sp = CalculateTarget();
1666 
1667   const ArchSpec &target_arch = target_sp->GetArchitecture();
1668 
1669   Block *frame_block = GetFrameBlock();
1670 
1671   if (!frame_block) {
1672     return ValueObjectSP();
1673   }
1674 
1675   Function *function = frame_block->CalculateSymbolContextFunction();
1676   if (!function) {
1677     return ValueObjectSP();
1678   }
1679 
1680   AddressRange pc_range = function->GetAddressRange();
1681 
1682   if (GetFrameCodeAddress().GetFileAddress() <
1683           pc_range.GetBaseAddress().GetFileAddress() ||
1684       GetFrameCodeAddress().GetFileAddress() -
1685               pc_range.GetBaseAddress().GetFileAddress() >=
1686           pc_range.GetByteSize()) {
1687     return ValueObjectSP();
1688   }
1689 
1690   ExecutionContext exe_ctx(shared_from_this());
1691 
1692   const char *plugin_name = nullptr;
1693   const char *flavor = nullptr;
1694   const bool prefer_file_cache = false;
1695   DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
1696       target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache);
1697 
1698   if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1699     return ValueObjectSP();
1700   }
1701 
1702   const bool get_file_globals = false;
1703   VariableList *variables = GetVariableList(get_file_globals);
1704 
1705   if (!variables) {
1706     return ValueObjectSP();
1707   }
1708 
1709   return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables,
1710                         GetFrameCodeAddress());
1711 }
1712 
1713 TargetSP StackFrame::CalculateTarget() {
1714   TargetSP target_sp;
1715   ThreadSP thread_sp(GetThread());
1716   if (thread_sp) {
1717     ProcessSP process_sp(thread_sp->CalculateProcess());
1718     if (process_sp)
1719       target_sp = process_sp->CalculateTarget();
1720   }
1721   return target_sp;
1722 }
1723 
1724 ProcessSP StackFrame::CalculateProcess() {
1725   ProcessSP process_sp;
1726   ThreadSP thread_sp(GetThread());
1727   if (thread_sp)
1728     process_sp = thread_sp->CalculateProcess();
1729   return process_sp;
1730 }
1731 
1732 ThreadSP StackFrame::CalculateThread() { return GetThread(); }
1733 
1734 StackFrameSP StackFrame::CalculateStackFrame() { return shared_from_this(); }
1735 
1736 void StackFrame::CalculateExecutionContext(ExecutionContext &exe_ctx) {
1737   exe_ctx.SetContext(shared_from_this());
1738 }
1739 
1740 void StackFrame::DumpUsingSettingsFormat(Stream *strm,
1741                                          const char *frame_marker) {
1742   if (strm == nullptr)
1743     return;
1744 
1745   GetSymbolContext(eSymbolContextEverything);
1746   ExecutionContext exe_ctx(shared_from_this());
1747   StreamString s;
1748 
1749   if (frame_marker)
1750     s.PutCString(frame_marker);
1751 
1752   const FormatEntity::Entry *frame_format = nullptr;
1753   Target *target = exe_ctx.GetTargetPtr();
1754   if (target)
1755     frame_format = target->GetDebugger().GetFrameFormat();
1756   if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx,
1757                                            nullptr, nullptr, false, false)) {
1758     strm->PutCString(s.GetString());
1759   } else {
1760     Dump(strm, true, false);
1761     strm->EOL();
1762   }
1763 }
1764 
1765 void StackFrame::Dump(Stream *strm, bool show_frame_index,
1766                       bool show_fullpaths) {
1767   if (strm == nullptr)
1768     return;
1769 
1770   if (show_frame_index)
1771     strm->Printf("frame #%u: ", m_frame_index);
1772   ExecutionContext exe_ctx(shared_from_this());
1773   Target *target = exe_ctx.GetTargetPtr();
1774   strm->Printf("0x%0*" PRIx64 " ",
1775                target ? (target->GetArchitecture().GetAddressByteSize() * 2)
1776                       : 16,
1777                GetFrameCodeAddress().GetLoadAddress(target));
1778   GetSymbolContext(eSymbolContextEverything);
1779   const bool show_module = true;
1780   const bool show_inline = true;
1781   const bool show_function_arguments = true;
1782   const bool show_function_name = true;
1783   m_sc.DumpStopContext(strm, exe_ctx.GetBestExecutionContextScope(),
1784                        GetFrameCodeAddress(), show_fullpaths, show_module,
1785                        show_inline, show_function_arguments,
1786                        show_function_name);
1787 }
1788 
1789 void StackFrame::UpdateCurrentFrameFromPreviousFrame(StackFrame &prev_frame) {
1790   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1791   assert(GetStackID() ==
1792          prev_frame.GetStackID()); // TODO: remove this after some testing
1793   m_variable_list_sp = prev_frame.m_variable_list_sp;
1794   m_variable_list_value_objects.Swap(prev_frame.m_variable_list_value_objects);
1795   if (!m_disassembly.GetString().empty()) {
1796     m_disassembly.Clear();
1797     m_disassembly.PutCString(prev_frame.m_disassembly.GetString());
1798   }
1799 }
1800 
1801 void StackFrame::UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame) {
1802   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1803   assert(GetStackID() ==
1804          curr_frame.GetStackID());     // TODO: remove this after some testing
1805   m_id.SetPC(curr_frame.m_id.GetPC()); // Update the Stack ID PC value
1806   assert(GetThread() == curr_frame.GetThread());
1807   m_frame_index = curr_frame.m_frame_index;
1808   m_concrete_frame_index = curr_frame.m_concrete_frame_index;
1809   m_reg_context_sp = curr_frame.m_reg_context_sp;
1810   m_frame_code_addr = curr_frame.m_frame_code_addr;
1811   assert(!m_sc.target_sp || !curr_frame.m_sc.target_sp ||
1812          m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
1813   assert(!m_sc.module_sp || !curr_frame.m_sc.module_sp ||
1814          m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
1815   assert(m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr ||
1816          m_sc.comp_unit == curr_frame.m_sc.comp_unit);
1817   assert(m_sc.function == nullptr || curr_frame.m_sc.function == nullptr ||
1818          m_sc.function == curr_frame.m_sc.function);
1819   m_sc = curr_frame.m_sc;
1820   m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
1821   m_flags.Set(m_sc.GetResolvedMask());
1822   m_frame_base.Clear();
1823   m_frame_base_error.Clear();
1824 }
1825 
1826 bool StackFrame::HasCachedData() const {
1827   if (m_variable_list_sp)
1828     return true;
1829   if (m_variable_list_value_objects.GetSize() > 0)
1830     return true;
1831   if (!m_disassembly.GetString().empty())
1832     return true;
1833   return false;
1834 }
1835 
1836 bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
1837                            const char *frame_marker) {
1838 
1839   if (show_frame_info) {
1840     strm.Indent();
1841     DumpUsingSettingsFormat(&strm, frame_marker);
1842   }
1843 
1844   if (show_source) {
1845     ExecutionContext exe_ctx(shared_from_this());
1846     bool have_source = false, have_debuginfo = false;
1847     Debugger::StopDisassemblyType disasm_display =
1848         Debugger::eStopDisassemblyTypeNever;
1849     Target *target = exe_ctx.GetTargetPtr();
1850     if (target) {
1851       Debugger &debugger = target->GetDebugger();
1852       const uint32_t source_lines_before =
1853           debugger.GetStopSourceLineCount(true);
1854       const uint32_t source_lines_after =
1855           debugger.GetStopSourceLineCount(false);
1856       disasm_display = debugger.GetStopDisassemblyDisplay();
1857 
1858       GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
1859       if (m_sc.comp_unit && m_sc.line_entry.IsValid()) {
1860         have_debuginfo = true;
1861         if (source_lines_before > 0 || source_lines_after > 0) {
1862           size_t num_lines =
1863               target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
1864                   m_sc.line_entry.file, m_sc.line_entry.line,
1865                   m_sc.line_entry.column, source_lines_before,
1866                   source_lines_after, "->", &strm);
1867           if (num_lines != 0)
1868             have_source = true;
1869           // TODO: Give here a one time warning if source file is missing.
1870         }
1871       }
1872       switch (disasm_display) {
1873       case Debugger::eStopDisassemblyTypeNever:
1874         break;
1875 
1876       case Debugger::eStopDisassemblyTypeNoDebugInfo:
1877         if (have_debuginfo)
1878           break;
1879         LLVM_FALLTHROUGH;
1880 
1881       case Debugger::eStopDisassemblyTypeNoSource:
1882         if (have_source)
1883           break;
1884         LLVM_FALLTHROUGH;
1885 
1886       case Debugger::eStopDisassemblyTypeAlways:
1887         if (target) {
1888           const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
1889           if (disasm_lines > 0) {
1890             const ArchSpec &target_arch = target->GetArchitecture();
1891             AddressRange pc_range;
1892             pc_range.GetBaseAddress() = GetFrameCodeAddress();
1893             pc_range.SetByteSize(disasm_lines *
1894                                  target_arch.GetMaximumOpcodeByteSize());
1895             const char *plugin_name = nullptr;
1896             const char *flavor = nullptr;
1897             const bool mixed_source_and_assembly = false;
1898             Disassembler::Disassemble(
1899                 target->GetDebugger(), target_arch, plugin_name, flavor,
1900                 exe_ctx, pc_range, disasm_lines, mixed_source_and_assembly, 0,
1901                 Disassembler::eOptionMarkPCAddress, strm);
1902           }
1903         }
1904         break;
1905       }
1906     }
1907   }
1908   return true;
1909 }
1910