Home | History | Annotate | Download | only in Target
      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 #include "lldb/lldb-python.h"
     11 
     12 #include "lldb/Target/StackFrame.h"
     13 
     14 // C Includes
     15 // C++ Includes
     16 // Other libraries and framework includes
     17 // Project includes
     18 #include "lldb/Core/Module.h"
     19 #include "lldb/Core/Debugger.h"
     20 #include "lldb/Core/Disassembler.h"
     21 #include "lldb/Core/Value.h"
     22 #include "lldb/Core/ValueObjectVariable.h"
     23 #include "lldb/Core/ValueObjectConstResult.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/VariableList.h"
     29 #include "lldb/Target/ExecutionContext.h"
     30 #include "lldb/Target/Process.h"
     31 #include "lldb/Target/RegisterContext.h"
     32 #include "lldb/Target/Target.h"
     33 #include "lldb/Target/Thread.h"
     34 
     35 using namespace lldb;
     36 using namespace lldb_private;
     37 
     38 // The first bits in the flags are reserved for the SymbolContext::Scope bits
     39 // so we know if we have tried to look up information in our internal symbol
     40 // context (m_sc) already.
     41 #define RESOLVED_FRAME_CODE_ADDR        (uint32_t(eSymbolContextEverything + 1))
     42 #define RESOLVED_FRAME_ID_SYMBOL_SCOPE  (RESOLVED_FRAME_CODE_ADDR << 1)
     43 #define GOT_FRAME_BASE                  (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
     44 #define RESOLVED_VARIABLES              (GOT_FRAME_BASE << 1)
     45 #define RESOLVED_GLOBAL_VARIABLES       (RESOLVED_VARIABLES << 1)
     46 
     47 StackFrame::StackFrame (const ThreadSP &thread_sp,
     48                         user_id_t frame_idx,
     49                         user_id_t unwind_frame_index,
     50                         addr_t cfa,
     51                         addr_t pc,
     52                         const SymbolContext *sc_ptr) :
     53     m_thread_wp (thread_sp),
     54     m_frame_index (frame_idx),
     55     m_concrete_frame_index (unwind_frame_index),
     56     m_reg_context_sp (),
     57     m_id (pc, cfa, NULL),
     58     m_frame_code_addr (pc),
     59     m_sc (),
     60     m_flags (),
     61     m_frame_base (),
     62     m_frame_base_error (),
     63     m_variable_list_sp (),
     64     m_variable_list_value_objects (),
     65     m_disassembly ()
     66 {
     67     if (sc_ptr != NULL)
     68     {
     69         m_sc = *sc_ptr;
     70         m_flags.Set(m_sc.GetResolvedMask ());
     71     }
     72 }
     73 
     74 StackFrame::StackFrame (const ThreadSP &thread_sp,
     75                         user_id_t frame_idx,
     76                         user_id_t unwind_frame_index,
     77                         const RegisterContextSP &reg_context_sp,
     78                         addr_t cfa,
     79                         addr_t pc,
     80                         const SymbolContext *sc_ptr) :
     81     m_thread_wp (thread_sp),
     82     m_frame_index (frame_idx),
     83     m_concrete_frame_index (unwind_frame_index),
     84     m_reg_context_sp (reg_context_sp),
     85     m_id (pc, cfa, NULL),
     86     m_frame_code_addr (pc),
     87     m_sc (),
     88     m_flags (),
     89     m_frame_base (),
     90     m_frame_base_error (),
     91     m_variable_list_sp (),
     92     m_variable_list_value_objects (),
     93     m_disassembly ()
     94 {
     95     if (sc_ptr != NULL)
     96     {
     97         m_sc = *sc_ptr;
     98         m_flags.Set(m_sc.GetResolvedMask ());
     99     }
    100 
    101     if (reg_context_sp && !m_sc.target_sp)
    102     {
    103         m_sc.target_sp = reg_context_sp->CalculateTarget();
    104         if (m_sc.target_sp)
    105             m_flags.Set (eSymbolContextTarget);
    106     }
    107 }
    108 
    109 StackFrame::StackFrame (const ThreadSP &thread_sp,
    110                         user_id_t frame_idx,
    111                         user_id_t unwind_frame_index,
    112                         const RegisterContextSP &reg_context_sp,
    113                         addr_t cfa,
    114                         const Address& pc_addr,
    115                         const SymbolContext *sc_ptr) :
    116     m_thread_wp (thread_sp),
    117     m_frame_index (frame_idx),
    118     m_concrete_frame_index (unwind_frame_index),
    119     m_reg_context_sp (reg_context_sp),
    120     m_id (pc_addr.GetLoadAddress (thread_sp->CalculateTarget().get()), cfa, NULL),
    121     m_frame_code_addr (pc_addr),
    122     m_sc (),
    123     m_flags (),
    124     m_frame_base (),
    125     m_frame_base_error (),
    126     m_variable_list_sp (),
    127     m_variable_list_value_objects (),
    128     m_disassembly ()
    129 {
    130     if (sc_ptr != NULL)
    131     {
    132         m_sc = *sc_ptr;
    133         m_flags.Set(m_sc.GetResolvedMask ());
    134     }
    135 
    136     if (m_sc.target_sp.get() == NULL && reg_context_sp)
    137     {
    138         m_sc.target_sp = reg_context_sp->CalculateTarget();
    139         if (m_sc.target_sp)
    140             m_flags.Set (eSymbolContextTarget);
    141     }
    142 
    143     ModuleSP pc_module_sp (pc_addr.GetModule());
    144     if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp)
    145     {
    146         if (pc_module_sp)
    147         {
    148             m_sc.module_sp = pc_module_sp;
    149             m_flags.Set (eSymbolContextModule);
    150         }
    151         else
    152         {
    153             m_sc.module_sp.reset();
    154         }
    155     }
    156 }
    157 
    158 
    159 //----------------------------------------------------------------------
    160 // Destructor
    161 //----------------------------------------------------------------------
    162 StackFrame::~StackFrame()
    163 {
    164 }
    165 
    166 StackID&
    167 StackFrame::GetStackID()
    168 {
    169     // Make sure we have resolved the StackID object's symbol context scope if
    170     // we already haven't looked it up.
    171 
    172     if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE))
    173     {
    174         if (m_id.GetSymbolContextScope ())
    175         {
    176             // We already have a symbol context scope, we just don't have our
    177             // flag bit set.
    178             m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
    179         }
    180         else
    181         {
    182             // Calculate the frame block and use this for the stack ID symbol
    183             // context scope if we have one.
    184             SymbolContextScope *scope = GetFrameBlock ();
    185             if (scope == NULL)
    186             {
    187                 // We don't have a block, so use the symbol
    188                 if (m_flags.IsClear (eSymbolContextSymbol))
    189                     GetSymbolContext (eSymbolContextSymbol);
    190 
    191                 // It is ok if m_sc.symbol is NULL here
    192                 scope = m_sc.symbol;
    193             }
    194             // Set the symbol context scope (the accessor will set the
    195             // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
    196             SetSymbolContextScope (scope);
    197         }
    198     }
    199     return m_id;
    200 }
    201 
    202 uint32_t
    203 StackFrame::GetFrameIndex () const
    204 {
    205     ThreadSP thread_sp = GetThread();
    206     if (thread_sp)
    207         return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(m_frame_index);
    208     else
    209         return m_frame_index;
    210 }
    211 
    212 void
    213 StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope)
    214 {
    215     m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE);
    216     m_id.SetSymbolContextScope (symbol_scope);
    217 }
    218 
    219 const Address&
    220 StackFrame::GetFrameCodeAddress()
    221 {
    222     if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset())
    223     {
    224         m_flags.Set (RESOLVED_FRAME_CODE_ADDR);
    225 
    226         // Resolve the PC into a temporary address because if ResolveLoadAddress
    227         // fails to resolve the address, it will clear the address object...
    228         ThreadSP thread_sp (GetThread());
    229         if (thread_sp)
    230         {
    231             TargetSP target_sp (thread_sp->CalculateTarget());
    232             if (target_sp)
    233             {
    234                 if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), target_sp.get()))
    235                 {
    236                     ModuleSP module_sp (m_frame_code_addr.GetModule());
    237                     if (module_sp)
    238                     {
    239                         m_sc.module_sp = module_sp;
    240                         m_flags.Set(eSymbolContextModule);
    241                     }
    242                 }
    243             }
    244         }
    245     }
    246     return m_frame_code_addr;
    247 }
    248 
    249 void
    250 StackFrame::ChangePC (addr_t pc)
    251 {
    252     m_frame_code_addr.SetRawAddress(pc);
    253     m_sc.Clear(false);
    254     m_flags.Reset(0);
    255     ThreadSP thread_sp (GetThread());
    256     if (thread_sp)
    257         thread_sp->ClearStackFrames ();
    258 }
    259 
    260 const char *
    261 StackFrame::Disassemble ()
    262 {
    263     if (m_disassembly.GetSize() == 0)
    264     {
    265         ExecutionContext exe_ctx (shared_from_this());
    266         Target *target = exe_ctx.GetTargetPtr();
    267         if (target)
    268         {
    269             const char *plugin_name = NULL;
    270             const char *flavor = NULL;
    271             Disassembler::Disassemble (target->GetDebugger(),
    272                                        target->GetArchitecture(),
    273                                        plugin_name,
    274                                        flavor,
    275                                        exe_ctx,
    276                                        0,
    277                                        0,
    278                                        0,
    279                                        m_disassembly);
    280         }
    281         if (m_disassembly.GetSize() == 0)
    282             return NULL;
    283     }
    284     return m_disassembly.GetData();
    285 }
    286 
    287 Block *
    288 StackFrame::GetFrameBlock ()
    289 {
    290     if (m_sc.block == NULL && m_flags.IsClear (eSymbolContextBlock))
    291         GetSymbolContext (eSymbolContextBlock);
    292 
    293     if (m_sc.block)
    294     {
    295         Block *inline_block = m_sc.block->GetContainingInlinedBlock();
    296         if (inline_block)
    297         {
    298             // Use the block with the inlined function info
    299             // as the frame block we want this frame to have only the variables
    300             // for the inlined function and its non-inlined block child blocks.
    301             return inline_block;
    302         }
    303         else
    304         {
    305             // This block is not contained withing any inlined function blocks
    306             // with so we want to use the top most function block.
    307             return &m_sc.function->GetBlock (false);
    308         }
    309     }
    310     return NULL;
    311 }
    312 
    313 //----------------------------------------------------------------------
    314 // Get the symbol context if we already haven't done so by resolving the
    315 // PC address as much as possible. This way when we pass around a
    316 // StackFrame object, everyone will have as much information as
    317 // possible and no one will ever have to look things up manually.
    318 //----------------------------------------------------------------------
    319 const SymbolContext&
    320 StackFrame::GetSymbolContext (uint32_t resolve_scope)
    321 {
    322     // Copy our internal symbol context into "sc".
    323     if ((m_flags.Get() & resolve_scope) != resolve_scope)
    324     {
    325         uint32_t resolved = 0;
    326 
    327         // If the target was requested add that:
    328         if (!m_sc.target_sp)
    329         {
    330             m_sc.target_sp = CalculateTarget();
    331             if (m_sc.target_sp)
    332                 resolved |= eSymbolContextTarget;
    333         }
    334 
    335 
    336         // Resolve our PC to section offset if we haven't alreday done so
    337         // and if we don't have a module. The resolved address section will
    338         // contain the module to which it belongs
    339         if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
    340             GetFrameCodeAddress();
    341 
    342         // If this is not frame zero, then we need to subtract 1 from the PC
    343         // value when doing address lookups since the PC will be on the
    344         // instruction following the function call instruction...
    345 
    346         Address lookup_addr(GetFrameCodeAddress());
    347         if (m_frame_index > 0 && lookup_addr.IsValid())
    348         {
    349             addr_t offset = lookup_addr.GetOffset();
    350             if (offset > 0)
    351                 lookup_addr.SetOffset(offset - 1);
    352         }
    353 
    354 
    355         if (m_sc.module_sp)
    356         {
    357             // We have something in our stack frame symbol context, lets check
    358             // if we haven't already tried to lookup one of those things. If we
    359             // haven't then we will do the query.
    360 
    361             uint32_t actual_resolve_scope = 0;
    362 
    363             if (resolve_scope & eSymbolContextCompUnit)
    364             {
    365                 if (m_flags.IsClear (eSymbolContextCompUnit))
    366                 {
    367                     if (m_sc.comp_unit)
    368                         resolved |= eSymbolContextCompUnit;
    369                     else
    370                         actual_resolve_scope |= eSymbolContextCompUnit;
    371                 }
    372             }
    373 
    374             if (resolve_scope & eSymbolContextFunction)
    375             {
    376                 if (m_flags.IsClear (eSymbolContextFunction))
    377                 {
    378                     if (m_sc.function)
    379                         resolved |= eSymbolContextFunction;
    380                     else
    381                         actual_resolve_scope |= eSymbolContextFunction;
    382                 }
    383             }
    384 
    385             if (resolve_scope & eSymbolContextBlock)
    386             {
    387                 if (m_flags.IsClear (eSymbolContextBlock))
    388                 {
    389                     if (m_sc.block)
    390                         resolved |= eSymbolContextBlock;
    391                     else
    392                         actual_resolve_scope |= eSymbolContextBlock;
    393                 }
    394             }
    395 
    396             if (resolve_scope & eSymbolContextSymbol)
    397             {
    398                 if (m_flags.IsClear (eSymbolContextSymbol))
    399                 {
    400                     if (m_sc.symbol)
    401                         resolved |= eSymbolContextSymbol;
    402                     else
    403                         actual_resolve_scope |= eSymbolContextSymbol;
    404                 }
    405             }
    406 
    407             if (resolve_scope & eSymbolContextLineEntry)
    408             {
    409                 if (m_flags.IsClear (eSymbolContextLineEntry))
    410                 {
    411                     if (m_sc.line_entry.IsValid())
    412                         resolved |= eSymbolContextLineEntry;
    413                     else
    414                         actual_resolve_scope |= eSymbolContextLineEntry;
    415                 }
    416             }
    417 
    418             if (actual_resolve_scope)
    419             {
    420                 // We might be resolving less information than what is already
    421                 // in our current symbol context so resolve into a temporary
    422                 // symbol context "sc" so we don't clear out data we have
    423                 // already found in "m_sc"
    424                 SymbolContext sc;
    425                 // Set flags that indicate what we have tried to resolve
    426                 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc);
    427                 // Only replace what we didn't already have as we may have
    428                 // information for an inlined function scope that won't match
    429                 // what a standard lookup by address would match
    430                 if ((resolved & eSymbolContextCompUnit)  && m_sc.comp_unit == NULL)
    431                     m_sc.comp_unit = sc.comp_unit;
    432                 if ((resolved & eSymbolContextFunction)  && m_sc.function == NULL)
    433                     m_sc.function = sc.function;
    434                 if ((resolved & eSymbolContextBlock)     && m_sc.block == NULL)
    435                     m_sc.block = sc.block;
    436                 if ((resolved & eSymbolContextSymbol)    && m_sc.symbol == NULL)
    437                     m_sc.symbol = sc.symbol;
    438                 if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
    439                 {
    440                     m_sc.line_entry = sc.line_entry;
    441                     if (m_sc.target_sp)
    442                     {
    443                         // Be sure to apply and file remappings to our file and line
    444                         // entries when handing out a line entry
    445                         FileSpec new_file_spec;
    446                         if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec))
    447                             m_sc.line_entry.file = new_file_spec;
    448                     }
    449                 }
    450             }
    451         }
    452         else
    453         {
    454             // If we don't have a module, then we can't have the compile unit,
    455             // function, block, line entry or symbol, so we can safely call
    456             // ResolveSymbolContextForAddress with our symbol context member m_sc.
    457             if (m_sc.target_sp)
    458             {
    459                 resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
    460             }
    461         }
    462 
    463         // Update our internal flags so we remember what we have tried to locate so
    464         // we don't have to keep trying when more calls to this function are made.
    465         // We might have dug up more information that was requested (for example
    466         // if we were asked to only get the block, we will have gotten the
    467         // compile unit, and function) so set any additional bits that we resolved
    468         m_flags.Set (resolve_scope | resolved);
    469     }
    470 
    471     // Return the symbol context with everything that was possible to resolve
    472     // resolved.
    473     return m_sc;
    474 }
    475 
    476 
    477 VariableList *
    478 StackFrame::GetVariableList (bool get_file_globals)
    479 {
    480     if (m_flags.IsClear(RESOLVED_VARIABLES))
    481     {
    482         m_flags.Set(RESOLVED_VARIABLES);
    483 
    484         Block *frame_block = GetFrameBlock();
    485 
    486         if (frame_block)
    487         {
    488             const bool get_child_variables = true;
    489             const bool can_create = true;
    490             const bool stop_if_child_block_is_inlined_function = true;
    491             m_variable_list_sp.reset(new VariableList());
    492             frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, m_variable_list_sp.get());
    493         }
    494     }
    495 
    496     if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) &&
    497         get_file_globals)
    498     {
    499         m_flags.Set(RESOLVED_GLOBAL_VARIABLES);
    500 
    501         if (m_flags.IsClear (eSymbolContextCompUnit))
    502             GetSymbolContext (eSymbolContextCompUnit);
    503 
    504         if (m_sc.comp_unit)
    505         {
    506             VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
    507             if (m_variable_list_sp)
    508                 m_variable_list_sp->AddVariables (global_variable_list_sp.get());
    509             else
    510                 m_variable_list_sp = global_variable_list_sp;
    511         }
    512     }
    513 
    514     return m_variable_list_sp.get();
    515 }
    516 
    517 VariableListSP
    518 StackFrame::GetInScopeVariableList (bool get_file_globals)
    519 {
    520     VariableListSP var_list_sp(new VariableList);
    521     GetSymbolContext (eSymbolContextCompUnit | eSymbolContextBlock);
    522 
    523     if (m_sc.block)
    524     {
    525         const bool can_create = true;
    526         const bool get_parent_variables = true;
    527         const bool stop_if_block_is_inlined_function = true;
    528         m_sc.block->AppendVariables (can_create,
    529                                      get_parent_variables,
    530                                      stop_if_block_is_inlined_function,
    531                                      var_list_sp.get());
    532     }
    533 
    534     if (m_sc.comp_unit)
    535     {
    536         VariableListSP global_variable_list_sp (m_sc.comp_unit->GetVariableList(true));
    537         if (global_variable_list_sp)
    538             var_list_sp->AddVariables (global_variable_list_sp.get());
    539     }
    540 
    541     return var_list_sp;
    542 }
    543 
    544 
    545 ValueObjectSP
    546 StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
    547                                                DynamicValueType use_dynamic,
    548                                                uint32_t options,
    549                                                VariableSP &var_sp,
    550                                                Error &error)
    551 {
    552 
    553     if (var_expr_cstr && var_expr_cstr[0])
    554     {
    555         const bool check_ptr_vs_member = (options & eExpressionPathOptionCheckPtrVsMember) != 0;
    556         const bool no_fragile_ivar = (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
    557         const bool no_synth_child = (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
    558         //const bool no_synth_array = (options & eExpressionPathOptionsNoSyntheticArrayRange) != 0;
    559         error.Clear();
    560         bool deref = false;
    561         bool address_of = false;
    562         ValueObjectSP valobj_sp;
    563         const bool get_file_globals = true;
    564         // When looking up a variable for an expression, we need only consider the
    565         // variables that are in scope.
    566         VariableListSP var_list_sp (GetInScopeVariableList (get_file_globals));
    567         VariableList *variable_list = var_list_sp.get();
    568 
    569         if (variable_list)
    570         {
    571             // If first character is a '*', then show pointer contents
    572             const char *var_expr = var_expr_cstr;
    573             if (var_expr[0] == '*')
    574             {
    575                 deref = true;
    576                 var_expr++; // Skip the '*'
    577             }
    578             else if (var_expr[0] == '&')
    579             {
    580                 address_of = true;
    581                 var_expr++; // Skip the '&'
    582             }
    583 
    584             std::string var_path (var_expr);
    585             size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}");
    586             StreamString var_expr_path_strm;
    587 
    588             ConstString name_const_string;
    589             if (separator_idx == std::string::npos)
    590                 name_const_string.SetCString (var_path.c_str());
    591             else
    592                 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
    593 
    594             var_sp = variable_list->FindVariable(name_const_string);
    595 
    596             bool synthetically_added_instance_object = false;
    597 
    598             if (var_sp)
    599             {
    600                 var_path.erase (0, name_const_string.GetLength ());
    601             }
    602             else if (options & eExpressionPathOptionsAllowDirectIVarAccess)
    603             {
    604                 // Check for direct ivars access which helps us with implicit
    605                 // access to ivars with the "this->" or "self->"
    606                 GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock);
    607                 lldb::LanguageType method_language = eLanguageTypeUnknown;
    608                 bool is_instance_method = false;
    609                 ConstString method_object_name;
    610                 if (m_sc.GetFunctionMethodInfo (method_language, is_instance_method, method_object_name))
    611                 {
    612                     if (is_instance_method && method_object_name)
    613                     {
    614                         var_sp = variable_list->FindVariable(method_object_name);
    615                         if (var_sp)
    616                         {
    617                             separator_idx = 0;
    618                             var_path.insert(0, "->");
    619                             synthetically_added_instance_object = true;
    620                         }
    621                     }
    622                 }
    623             }
    624 
    625             if (var_sp)
    626             {
    627                 valobj_sp = GetValueObjectForFrameVariable (var_sp, use_dynamic);
    628                 if (!valobj_sp)
    629                     return valobj_sp;
    630 
    631                 // We are dumping at least one child
    632                 while (separator_idx != std::string::npos)
    633                 {
    634                     // Calculate the next separator index ahead of time
    635                     ValueObjectSP child_valobj_sp;
    636                     const char separator_type = var_path[0];
    637                     switch (separator_type)
    638                     {
    639 
    640                     case '-':
    641                         if (var_path.size() >= 2 && var_path[1] != '>')
    642                             return ValueObjectSP();
    643 
    644                         if (no_fragile_ivar)
    645                         {
    646                             // Make sure we aren't trying to deref an objective
    647                             // C ivar if this is not allowed
    648                             const uint32_t pointer_type_flags = valobj_sp->GetClangType().GetTypeInfo (NULL);
    649                             if ((pointer_type_flags & ClangASTType::eTypeIsObjC) &&
    650                                 (pointer_type_flags & ClangASTType::eTypeIsPointer))
    651                             {
    652                                 // This was an objective C object pointer and
    653                                 // it was requested we skip any fragile ivars
    654                                 // so return nothing here
    655                                 return ValueObjectSP();
    656                             }
    657                         }
    658                         var_path.erase (0, 1); // Remove the '-'
    659                         // Fall through
    660                     case '.':
    661                         {
    662                             const bool expr_is_ptr = var_path[0] == '>';
    663 
    664                             var_path.erase (0, 1); // Remove the '.' or '>'
    665                             separator_idx = var_path.find_first_of(".-[");
    666                             ConstString child_name;
    667                             if (separator_idx == std::string::npos)
    668                                 child_name.SetCString (var_path.c_str());
    669                             else
    670                                 child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
    671 
    672                             if (check_ptr_vs_member)
    673                             {
    674                                 // We either have a pointer type and need to verify
    675                                 // valobj_sp is a pointer, or we have a member of a
    676                                 // class/union/struct being accessed with the . syntax
    677                                 // and need to verify we don't have a pointer.
    678                                 const bool actual_is_ptr = valobj_sp->IsPointerType ();
    679 
    680                                 if (actual_is_ptr != expr_is_ptr)
    681                                 {
    682                                     // Incorrect use of "." with a pointer, or "->" with
    683                                     // a class/union/struct instance or reference.
    684                                     valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    685                                     if (actual_is_ptr)
    686                                         error.SetErrorStringWithFormat ("\"%s\" is a pointer and . was used to attempt to access \"%s\". Did you mean \"%s->%s\"?",
    687                                                                         var_expr_path_strm.GetString().c_str(),
    688                                                                         child_name.GetCString(),
    689                                                                         var_expr_path_strm.GetString().c_str(),
    690                                                                         var_path.c_str());
    691                                     else
    692                                         error.SetErrorStringWithFormat ("\"%s\" is not a pointer and -> was used to attempt to access \"%s\". Did you mean \"%s.%s\"?",
    693                                                                         var_expr_path_strm.GetString().c_str(),
    694                                                                         child_name.GetCString(),
    695                                                                         var_expr_path_strm.GetString().c_str(),
    696                                                                         var_path.c_str());
    697                                     return ValueObjectSP();
    698                                 }
    699                             }
    700                             child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
    701                             if (!child_valobj_sp)
    702                             {
    703                                 if (no_synth_child == false)
    704                                 {
    705                                     child_valobj_sp = valobj_sp->GetSyntheticValue();
    706                                     if (child_valobj_sp)
    707                                         child_valobj_sp = child_valobj_sp->GetChildMemberWithName (child_name, true);
    708                                 }
    709 
    710                                 if (no_synth_child || !child_valobj_sp)
    711                                 {
    712                                     // No child member with name "child_name"
    713                                     if (synthetically_added_instance_object)
    714                                     {
    715                                         // We added a "this->" or "self->" to the beginning of the expression
    716                                         // and this is the first pointer ivar access, so just return the normal
    717                                         // error
    718                                         error.SetErrorStringWithFormat("no variable or instance variable named '%s' found in this frame",
    719                                                                        name_const_string.GetCString());
    720                                     }
    721                                     else
    722                                     {
    723                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    724                                         if (child_name)
    725                                         {
    726                                             error.SetErrorStringWithFormat ("\"%s\" is not a member of \"(%s) %s\"",
    727                                                                             child_name.GetCString(),
    728                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
    729                                                                             var_expr_path_strm.GetString().c_str());
    730                                         }
    731                                         else
    732                                         {
    733                                             error.SetErrorStringWithFormat ("incomplete expression path after \"%s\" in \"%s\"",
    734                                                                             var_expr_path_strm.GetString().c_str(),
    735                                                                             var_expr_cstr);
    736                                         }
    737                                     }
    738                                     return ValueObjectSP();
    739                                 }
    740                             }
    741                             synthetically_added_instance_object = false;
    742                             // Remove the child name from the path
    743                             var_path.erase(0, child_name.GetLength());
    744                             if (use_dynamic != eNoDynamicValues)
    745                             {
    746                                 ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
    747                                 if (dynamic_value_sp)
    748                                     child_valobj_sp = dynamic_value_sp;
    749                             }
    750                         }
    751                         break;
    752 
    753                     case '[':
    754                         // Array member access, or treating pointer as an array
    755                         if (var_path.size() > 2) // Need at least two brackets and a number
    756                         {
    757                             char *end = NULL;
    758                             long child_index = ::strtol (&var_path[1], &end, 0);
    759                             if (end && *end == ']'
    760                                 && *(end-1) != '[') // this code forces an error in the case of arr[]. as bitfield[] is not a good syntax we're good to go
    761                             {
    762                                 if (valobj_sp->GetClangType().IsPointerToScalarType() && deref)
    763                                 {
    764                                     // what we have is *ptr[low]. the most similar C++ syntax is to deref ptr
    765                                     // and extract bit low out of it. reading array item low
    766                                     // would be done by saying ptr[low], without a deref * sign
    767                                     Error error;
    768                                     ValueObjectSP temp(valobj_sp->Dereference(error));
    769                                     if (error.Fail())
    770                                     {
    771                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    772                                         error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
    773                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
    774                                                                         var_expr_path_strm.GetString().c_str());
    775                                         return ValueObjectSP();
    776                                     }
    777                                     valobj_sp = temp;
    778                                     deref = false;
    779                                 }
    780                                 else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref)
    781                                 {
    782                                     // what we have is *arr[low]. the most similar C++ syntax is to get arr[0]
    783                                     // (an operation that is equivalent to deref-ing arr)
    784                                     // and extract bit low out of it. reading array item low
    785                                     // would be done by saying arr[low], without a deref * sign
    786                                     Error error;
    787                                     ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
    788                                     if (error.Fail())
    789                                     {
    790                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    791                                         error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
    792                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
    793                                                                         var_expr_path_strm.GetString().c_str());
    794                                         return ValueObjectSP();
    795                                     }
    796                                     valobj_sp = temp;
    797                                     deref = false;
    798                                 }
    799 
    800                                 bool is_incomplete_array = false;
    801                                 if (valobj_sp->IsPointerType ())
    802                                 {
    803                                     bool is_objc_pointer = true;
    804 
    805                                     if (valobj_sp->GetClangType().GetMinimumLanguage() != eLanguageTypeObjC)
    806                                         is_objc_pointer = false;
    807                                     else if (!valobj_sp->GetClangType().IsPointerType())
    808                                         is_objc_pointer = false;
    809 
    810                                     if (no_synth_child && is_objc_pointer)
    811                                     {
    812                                         error.SetErrorStringWithFormat("\"(%s) %s\" is an Objective-C pointer, and cannot be subscripted",
    813                                                                        valobj_sp->GetTypeName().AsCString("<invalid type>"),
    814                                                                        var_expr_path_strm.GetString().c_str());
    815 
    816                                         return ValueObjectSP();
    817                                     }
    818                                     else if (is_objc_pointer)
    819                                     {
    820                                         // dereferencing ObjC variables is not valid.. so let's try and recur to synthetic children
    821                                         ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
    822                                         if (synthetic.get() == NULL /* no synthetic */
    823                                             || synthetic == valobj_sp) /* synthetic is the same as the original object */
    824                                         {
    825                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    826                                             error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
    827                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
    828                                                                             var_expr_path_strm.GetString().c_str());
    829                                         }
    830                                         else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
    831                                         {
    832                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    833                                             error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
    834                                                                             child_index,
    835                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
    836                                                                             var_expr_path_strm.GetString().c_str());
    837                                         }
    838                                         else
    839                                         {
    840                                             child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
    841                                             if (!child_valobj_sp)
    842                                             {
    843                                                 valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    844                                                 error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
    845                                                                                 child_index,
    846                                                                                 valobj_sp->GetTypeName().AsCString("<invalid type>"),
    847                                                                                 var_expr_path_strm.GetString().c_str());
    848                                             }
    849                                         }
    850                                     }
    851                                     else
    852                                     {
    853                                         child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
    854                                         if (!child_valobj_sp)
    855                                         {
    856                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    857                                             error.SetErrorStringWithFormat ("failed to use pointer as array for index %ld for \"(%s) %s\"",
    858                                                                             child_index,
    859                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
    860                                                                             var_expr_path_strm.GetString().c_str());
    861                                         }
    862                                     }
    863                                 }
    864                                 else if (valobj_sp->GetClangType().IsArrayType (NULL, NULL, &is_incomplete_array))
    865                                 {
    866                                     // Pass false to dynamic_value here so we can tell the difference between
    867                                     // no dynamic value and no member of this type...
    868                                     child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
    869                                     if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false))
    870                                         child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
    871 
    872                                     if (!child_valobj_sp)
    873                                     {
    874                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    875                                         error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
    876                                                                         child_index,
    877                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
    878                                                                         var_expr_path_strm.GetString().c_str());
    879                                     }
    880                                 }
    881                                 else if (valobj_sp->GetClangType().IsScalarType())
    882                                 {
    883                                     // this is a bitfield asking to display just one bit
    884                                     child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, child_index, true);
    885                                     if (!child_valobj_sp)
    886                                     {
    887                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    888                                         error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
    889                                                                         child_index, child_index,
    890                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
    891                                                                         var_expr_path_strm.GetString().c_str());
    892                                     }
    893                                 }
    894                                 else
    895                                 {
    896                                     ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
    897                                     if (no_synth_child /* synthetic is forbidden */ ||
    898                                         synthetic.get() == NULL /* no synthetic */
    899                                         || synthetic == valobj_sp) /* synthetic is the same as the original object */
    900                                     {
    901                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    902                                         error.SetErrorStringWithFormat ("\"(%s) %s\" is not an array type",
    903                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
    904                                                                         var_expr_path_strm.GetString().c_str());
    905                                     }
    906                                     else if (child_index >= synthetic->GetNumChildren() /* synthetic does not have that many values */)
    907                                     {
    908                                         valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    909                                         error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
    910                                                                         child_index,
    911                                                                         valobj_sp->GetTypeName().AsCString("<invalid type>"),
    912                                                                         var_expr_path_strm.GetString().c_str());
    913                                     }
    914                                     else
    915                                     {
    916                                         child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
    917                                         if (!child_valobj_sp)
    918                                         {
    919                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    920                                             error.SetErrorStringWithFormat ("array index %ld is not valid for \"(%s) %s\"",
    921                                                                             child_index,
    922                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
    923                                                                             var_expr_path_strm.GetString().c_str());
    924                                         }
    925                                     }
    926                                 }
    927 
    928                                 if (!child_valobj_sp)
    929                                 {
    930                                     // Invalid array index...
    931                                     return ValueObjectSP();
    932                                 }
    933 
    934                                 // Erase the array member specification '[%i]' where
    935                                 // %i is the array index
    936                                 var_path.erase(0, (end - var_path.c_str()) + 1);
    937                                 separator_idx = var_path.find_first_of(".-[");
    938                                 if (use_dynamic != eNoDynamicValues)
    939                                 {
    940                                     ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
    941                                     if (dynamic_value_sp)
    942                                         child_valobj_sp = dynamic_value_sp;
    943                                 }
    944                                 // Break out early from the switch since we were
    945                                 // able to find the child member
    946                                 break;
    947                             }
    948                             else if (end && *end == '-')
    949                             {
    950                                 // this is most probably a BitField, let's take a look
    951                                 char *real_end = NULL;
    952                                 long final_index = ::strtol (end+1, &real_end, 0);
    953                                 bool expand_bitfield = true;
    954                                 if (real_end && *real_end == ']')
    955                                 {
    956                                     // if the format given is [high-low], swap range
    957                                     if (child_index > final_index)
    958                                     {
    959                                         long temp = child_index;
    960                                         child_index = final_index;
    961                                         final_index = temp;
    962                                     }
    963 
    964                                     if (valobj_sp->GetClangType().IsPointerToScalarType() && deref)
    965                                     {
    966                                         // what we have is *ptr[low-high]. the most similar C++ syntax is to deref ptr
    967                                         // and extract bits low thru high out of it. reading array items low thru high
    968                                         // would be done by saying ptr[low-high], without a deref * sign
    969                                         Error error;
    970                                         ValueObjectSP temp(valobj_sp->Dereference(error));
    971                                         if (error.Fail())
    972                                         {
    973                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    974                                             error.SetErrorStringWithFormat ("could not dereference \"(%s) %s\"",
    975                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
    976                                                                             var_expr_path_strm.GetString().c_str());
    977                                             return ValueObjectSP();
    978                                         }
    979                                         valobj_sp = temp;
    980                                         deref = false;
    981                                     }
    982                                     else if (valobj_sp->GetClangType().IsArrayOfScalarType() && deref)
    983                                     {
    984                                         // what we have is *arr[low-high]. the most similar C++ syntax is to get arr[0]
    985                                         // (an operation that is equivalent to deref-ing arr)
    986                                         // and extract bits low thru high out of it. reading array items low thru high
    987                                         // would be done by saying arr[low-high], without a deref * sign
    988                                         Error error;
    989                                         ValueObjectSP temp(valobj_sp->GetChildAtIndex (0, true));
    990                                         if (error.Fail())
    991                                         {
    992                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
    993                                             error.SetErrorStringWithFormat ("could not get item 0 for \"(%s) %s\"",
    994                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
    995                                                                             var_expr_path_strm.GetString().c_str());
    996                                             return ValueObjectSP();
    997                                         }
    998                                         valobj_sp = temp;
    999                                         deref = false;
   1000                                     }
   1001                                     /*else if (valobj_sp->IsArrayType() || valobj_sp->IsPointerType())
   1002                                     {
   1003                                         child_valobj_sp = valobj_sp->GetSyntheticArrayRangeChild(child_index, final_index, true);
   1004                                         expand_bitfield = false;
   1005                                         if (!child_valobj_sp)
   1006                                         {
   1007                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
   1008                                             error.SetErrorStringWithFormat ("array range %i-%i is not valid for \"(%s) %s\"",
   1009                                                                             child_index, final_index,
   1010                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
   1011                                                                             var_expr_path_strm.GetString().c_str());
   1012                                         }
   1013                                     }*/
   1014 
   1015                                     if (expand_bitfield)
   1016                                     {
   1017                                         child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
   1018                                         if (!child_valobj_sp)
   1019                                         {
   1020                                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
   1021                                             error.SetErrorStringWithFormat ("bitfield range %ld-%ld is not valid for \"(%s) %s\"",
   1022                                                                             child_index, final_index,
   1023                                                                             valobj_sp->GetTypeName().AsCString("<invalid type>"),
   1024                                                                             var_expr_path_strm.GetString().c_str());
   1025                                         }
   1026                                     }
   1027                                 }
   1028 
   1029                                 if (!child_valobj_sp)
   1030                                 {
   1031                                     // Invalid bitfield range...
   1032                                     return ValueObjectSP();
   1033                                 }
   1034 
   1035                                 // Erase the bitfield member specification '[%i-%i]' where
   1036                                 // %i is the index
   1037                                 var_path.erase(0, (real_end - var_path.c_str()) + 1);
   1038                                 separator_idx = var_path.find_first_of(".-[");
   1039                                 if (use_dynamic != eNoDynamicValues)
   1040                                 {
   1041                                     ValueObjectSP dynamic_value_sp(child_valobj_sp->GetDynamicValue(use_dynamic));
   1042                                     if (dynamic_value_sp)
   1043                                         child_valobj_sp = dynamic_value_sp;
   1044                                 }
   1045                                 // Break out early from the switch since we were
   1046                                 // able to find the child member
   1047                                 break;
   1048 
   1049                             }
   1050                         }
   1051                         else
   1052                         {
   1053                             error.SetErrorStringWithFormat("invalid square bracket encountered after \"%s\" in \"%s\"",
   1054                                                            var_expr_path_strm.GetString().c_str(),
   1055                                                            var_path.c_str());
   1056                         }
   1057                         return ValueObjectSP();
   1058 
   1059                     default:
   1060                         // Failure...
   1061                         {
   1062                             valobj_sp->GetExpressionPath (var_expr_path_strm, false);
   1063                             error.SetErrorStringWithFormat ("unexpected char '%c' encountered after \"%s\" in \"%s\"",
   1064                                                             separator_type,
   1065                                                             var_expr_path_strm.GetString().c_str(),
   1066                                                             var_path.c_str());
   1067 
   1068                             return ValueObjectSP();
   1069                         }
   1070                     }
   1071 
   1072                     if (child_valobj_sp)
   1073                         valobj_sp = child_valobj_sp;
   1074 
   1075                     if (var_path.empty())
   1076                         break;
   1077 
   1078                 }
   1079                 if (valobj_sp)
   1080                 {
   1081                     if (deref)
   1082                     {
   1083                         ValueObjectSP deref_valobj_sp (valobj_sp->Dereference(error));
   1084                         valobj_sp = deref_valobj_sp;
   1085                     }
   1086                     else if (address_of)
   1087                     {
   1088                         ValueObjectSP address_of_valobj_sp (valobj_sp->AddressOf(error));
   1089                         valobj_sp = address_of_valobj_sp;
   1090                     }
   1091                 }
   1092                 return valobj_sp;
   1093             }
   1094             else
   1095             {
   1096                 error.SetErrorStringWithFormat("no variable named '%s' found in this frame",
   1097                                                name_const_string.GetCString());
   1098             }
   1099         }
   1100     }
   1101     else
   1102     {
   1103         error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
   1104     }
   1105     return ValueObjectSP();
   1106 }
   1107 
   1108 bool
   1109 StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
   1110 {
   1111     if (m_flags.IsClear(GOT_FRAME_BASE))
   1112     {
   1113         if (m_sc.function)
   1114         {
   1115             m_frame_base.Clear();
   1116             m_frame_base_error.Clear();
   1117 
   1118             m_flags.Set(GOT_FRAME_BASE);
   1119             ExecutionContext exe_ctx (shared_from_this());
   1120             Value expr_value;
   1121             addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
   1122             if (m_sc.function->GetFrameBaseExpression().IsLocationList())
   1123                 loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.GetTargetPtr());
   1124 
   1125             if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
   1126             {
   1127                 // We should really have an error if evaluate returns, but in case
   1128                 // we don't, lets set the error to something at least.
   1129                 if (m_frame_base_error.Success())
   1130                     m_frame_base_error.SetErrorString("Evaluation of the frame base expression failed.");
   1131             }
   1132             else
   1133             {
   1134                 m_frame_base = expr_value.ResolveValue(&exe_ctx);
   1135             }
   1136         }
   1137         else
   1138         {
   1139             m_frame_base_error.SetErrorString ("No function in symbol context.");
   1140         }
   1141     }
   1142 
   1143     if (m_frame_base_error.Success())
   1144         frame_base = m_frame_base;
   1145 
   1146     if (error_ptr)
   1147         *error_ptr = m_frame_base_error;
   1148     return m_frame_base_error.Success();
   1149 }
   1150 
   1151 RegisterContextSP
   1152 StackFrame::GetRegisterContext ()
   1153 {
   1154     if (!m_reg_context_sp)
   1155     {
   1156         ThreadSP thread_sp (GetThread());
   1157         if (thread_sp)
   1158             m_reg_context_sp = thread_sp->CreateRegisterContextForFrame (this);
   1159     }
   1160     return m_reg_context_sp;
   1161 }
   1162 
   1163 bool
   1164 StackFrame::HasDebugInformation ()
   1165 {
   1166     GetSymbolContext (eSymbolContextLineEntry);
   1167     return m_sc.line_entry.IsValid();
   1168 }
   1169 
   1170 
   1171 ValueObjectSP
   1172 StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
   1173 {
   1174     ValueObjectSP valobj_sp;
   1175     VariableList *var_list = GetVariableList (true);
   1176     if (var_list)
   1177     {
   1178         // Make sure the variable is a frame variable
   1179         const uint32_t var_idx = var_list->FindIndexForVariable (variable_sp.get());
   1180         const uint32_t num_variables = var_list->GetSize();
   1181         if (var_idx < num_variables)
   1182         {
   1183             valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex (var_idx);
   1184             if (valobj_sp.get() == NULL)
   1185             {
   1186                 if (m_variable_list_value_objects.GetSize() < num_variables)
   1187                     m_variable_list_value_objects.Resize(num_variables);
   1188                 valobj_sp = ValueObjectVariable::Create (this, variable_sp);
   1189                 m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
   1190             }
   1191         }
   1192     }
   1193     if (use_dynamic != eNoDynamicValues && valobj_sp)
   1194     {
   1195         ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue (use_dynamic);
   1196         if (dynamic_sp)
   1197             return dynamic_sp;
   1198     }
   1199     return valobj_sp;
   1200 }
   1201 
   1202 ValueObjectSP
   1203 StackFrame::TrackGlobalVariable (const VariableSP &variable_sp, DynamicValueType use_dynamic)
   1204 {
   1205     // Check to make sure we aren't already tracking this variable?
   1206     ValueObjectSP valobj_sp (GetValueObjectForFrameVariable (variable_sp, use_dynamic));
   1207     if (!valobj_sp)
   1208     {
   1209         // We aren't already tracking this global
   1210         VariableList *var_list = GetVariableList (true);
   1211         // If this frame has no variables, create a new list
   1212         if (var_list == NULL)
   1213             m_variable_list_sp.reset (new VariableList());
   1214 
   1215         // Add the global/static variable to this frame
   1216         m_variable_list_sp->AddVariable (variable_sp);
   1217 
   1218         // Now make a value object for it so we can track its changes
   1219         valobj_sp = GetValueObjectForFrameVariable (variable_sp, use_dynamic);
   1220     }
   1221     return valobj_sp;
   1222 }
   1223 
   1224 bool
   1225 StackFrame::IsInlined ()
   1226 {
   1227     if (m_sc.block == NULL)
   1228         GetSymbolContext (eSymbolContextBlock);
   1229     if (m_sc.block)
   1230         return m_sc.block->GetContainingInlinedBlock() != NULL;
   1231     return false;
   1232 }
   1233 
   1234 TargetSP
   1235 StackFrame::CalculateTarget ()
   1236 {
   1237     TargetSP target_sp;
   1238     ThreadSP thread_sp(GetThread());
   1239     if (thread_sp)
   1240     {
   1241         ProcessSP process_sp (thread_sp->CalculateProcess());
   1242         if (process_sp)
   1243             target_sp = process_sp->CalculateTarget();
   1244     }
   1245     return target_sp;
   1246 }
   1247 
   1248 ProcessSP
   1249 StackFrame::CalculateProcess ()
   1250 {
   1251     ProcessSP process_sp;
   1252     ThreadSP thread_sp(GetThread());
   1253     if (thread_sp)
   1254         process_sp = thread_sp->CalculateProcess();
   1255     return process_sp;
   1256 }
   1257 
   1258 ThreadSP
   1259 StackFrame::CalculateThread ()
   1260 {
   1261     return GetThread();
   1262 }
   1263 
   1264 StackFrameSP
   1265 StackFrame::CalculateStackFrame ()
   1266 {
   1267     return shared_from_this();
   1268 }
   1269 
   1270 
   1271 void
   1272 StackFrame::CalculateExecutionContext (ExecutionContext &exe_ctx)
   1273 {
   1274     exe_ctx.SetContext (shared_from_this());
   1275 }
   1276 
   1277 void
   1278 StackFrame::DumpUsingSettingsFormat (Stream *strm)
   1279 {
   1280     if (strm == NULL)
   1281         return;
   1282 
   1283     GetSymbolContext(eSymbolContextEverything);
   1284     ExecutionContext exe_ctx (shared_from_this());
   1285     StreamString s;
   1286     const char *frame_format = NULL;
   1287     Target *target = exe_ctx.GetTargetPtr();
   1288     if (target)
   1289         frame_format = target->GetDebugger().GetFrameFormat();
   1290     if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s))
   1291     {
   1292         strm->Write(s.GetData(), s.GetSize());
   1293     }
   1294     else
   1295     {
   1296         Dump (strm, true, false);
   1297         strm->EOL();
   1298     }
   1299 }
   1300 
   1301 void
   1302 StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
   1303 {
   1304     if (strm == NULL)
   1305         return;
   1306 
   1307     if (show_frame_index)
   1308         strm->Printf("frame #%u: ", m_frame_index);
   1309     ExecutionContext exe_ctx (shared_from_this());
   1310     Target *target = exe_ctx.GetTargetPtr();
   1311     strm->Printf("0x%0*" PRIx64 " ",
   1312                  target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16,
   1313                  GetFrameCodeAddress().GetLoadAddress(target));
   1314     GetSymbolContext(eSymbolContextEverything);
   1315     const bool show_module = true;
   1316     const bool show_inline = true;
   1317     m_sc.DumpStopContext (strm,
   1318                           exe_ctx.GetBestExecutionContextScope(),
   1319                           GetFrameCodeAddress(),
   1320                           show_fullpaths,
   1321                           show_module,
   1322                           show_inline);
   1323 }
   1324 
   1325 void
   1326 StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame)
   1327 {
   1328     assert (GetStackID() == prev_frame.GetStackID());    // TODO: remove this after some testing
   1329     m_variable_list_sp = prev_frame.m_variable_list_sp;
   1330     m_variable_list_value_objects.Swap (prev_frame.m_variable_list_value_objects);
   1331     if (!m_disassembly.GetString().empty())
   1332         m_disassembly.GetString().swap (m_disassembly.GetString());
   1333 }
   1334 
   1335 
   1336 void
   1337 StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame)
   1338 {
   1339     assert (GetStackID() == curr_frame.GetStackID());        // TODO: remove this after some testing
   1340     m_id.SetPC (curr_frame.m_id.GetPC());       // Update the Stack ID PC value
   1341     assert (GetThread() == curr_frame.GetThread());
   1342     m_frame_index = curr_frame.m_frame_index;
   1343     m_concrete_frame_index = curr_frame.m_concrete_frame_index;
   1344     m_reg_context_sp = curr_frame.m_reg_context_sp;
   1345     m_frame_code_addr = curr_frame.m_frame_code_addr;
   1346     assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
   1347     assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
   1348     assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit);
   1349     assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function);
   1350     m_sc = curr_frame.m_sc;
   1351     m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
   1352     m_flags.Set (m_sc.GetResolvedMask());
   1353     m_frame_base.Clear();
   1354     m_frame_base_error.Clear();
   1355 }
   1356 
   1357 
   1358 bool
   1359 StackFrame::HasCachedData () const
   1360 {
   1361     if (m_variable_list_sp.get())
   1362         return true;
   1363     if (m_variable_list_value_objects.GetSize() > 0)
   1364         return true;
   1365     if (!m_disassembly.GetString().empty())
   1366         return true;
   1367     return false;
   1368 }
   1369 
   1370 bool
   1371 StackFrame::GetStatus (Stream& strm,
   1372                        bool show_frame_info,
   1373                        bool show_source)
   1374 {
   1375 
   1376     if (show_frame_info)
   1377     {
   1378         strm.Indent();
   1379         DumpUsingSettingsFormat (&strm);
   1380     }
   1381 
   1382     if (show_source)
   1383     {
   1384         ExecutionContext exe_ctx (shared_from_this());
   1385         bool have_source = false;
   1386         Debugger::StopDisassemblyType disasm_display = Debugger::eStopDisassemblyTypeNever;
   1387         Target *target = exe_ctx.GetTargetPtr();
   1388         if (target)
   1389         {
   1390             Debugger &debugger = target->GetDebugger();
   1391             const uint32_t source_lines_before = debugger.GetStopSourceLineCount(true);
   1392             const uint32_t source_lines_after = debugger.GetStopSourceLineCount(false);
   1393             disasm_display = debugger.GetStopDisassemblyDisplay ();
   1394 
   1395             if (source_lines_before > 0 || source_lines_after > 0)
   1396             {
   1397                 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
   1398 
   1399                 if (m_sc.comp_unit && m_sc.line_entry.IsValid())
   1400                 {
   1401                     have_source = true;
   1402                     target->GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
   1403                                                                                       m_sc.line_entry.line,
   1404                                                                                       source_lines_before,
   1405                                                                                       source_lines_after,
   1406                                                                                       "->",
   1407                                                                                       &strm);
   1408                 }
   1409             }
   1410             switch (disasm_display)
   1411             {
   1412             case Debugger::eStopDisassemblyTypeNever:
   1413                 break;
   1414 
   1415             case Debugger::eStopDisassemblyTypeNoSource:
   1416                 if (have_source)
   1417                     break;
   1418                 // Fall through to next case
   1419             case Debugger::eStopDisassemblyTypeAlways:
   1420                 if (target)
   1421                 {
   1422                     const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
   1423                     if (disasm_lines > 0)
   1424                     {
   1425                         const ArchSpec &target_arch = target->GetArchitecture();
   1426                         AddressRange pc_range;
   1427                         pc_range.GetBaseAddress() = GetFrameCodeAddress();
   1428                         pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
   1429                         const char *plugin_name = NULL;
   1430                         const char *flavor = NULL;
   1431                         Disassembler::Disassemble (target->GetDebugger(),
   1432                                                    target_arch,
   1433                                                    plugin_name,
   1434                                                    flavor,
   1435                                                    exe_ctx,
   1436                                                    pc_range,
   1437                                                    disasm_lines,
   1438                                                    0,
   1439                                                    Disassembler::eOptionMarkPCAddress,
   1440                                                    strm);
   1441                     }
   1442                 }
   1443                 break;
   1444             }
   1445         }
   1446     }
   1447     return true;
   1448 }
   1449 
   1450