diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Symbol/Variable.cpp')
| -rw-r--r-- | contrib/llvm/tools/lldb/source/Symbol/Variable.cpp | 1529 | 
1 files changed, 661 insertions, 868 deletions
diff --git a/contrib/llvm/tools/lldb/source/Symbol/Variable.cpp b/contrib/llvm/tools/lldb/source/Symbol/Variable.cpp index dd27b1b5d802..e17685e83e2a 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/Variable.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/Variable.cpp @@ -10,14 +10,14 @@  #include "lldb/Symbol/Variable.h"  #include "lldb/Core/Module.h" -#include "lldb/Core/Stream.h"  #include "lldb/Core/RegularExpression.h" +#include "lldb/Core/Stream.h"  #include "lldb/Core/ValueObject.h"  #include "lldb/Core/ValueObjectVariable.h"  #include "lldb/Symbol/Block.h" +#include "lldb/Symbol/CompileUnit.h"  #include "lldb/Symbol/CompilerDecl.h"  #include "lldb/Symbol/CompilerDeclContext.h" -#include "lldb/Symbol/CompileUnit.h"  #include "lldb/Symbol/Function.h"  #include "lldb/Symbol/SymbolContext.h"  #include "lldb/Symbol/SymbolFile.h" @@ -28,8 +28,10 @@  #include "lldb/Target/Process.h"  #include "lldb/Target/RegisterContext.h"  #include "lldb/Target/StackFrame.h" -#include "lldb/Target/Thread.h"  #include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" + +#include "llvm/ADT/Twine.h"  using namespace lldb;  using namespace lldb_private; @@ -37,948 +39,739 @@ using namespace lldb_private;  //----------------------------------------------------------------------  // Variable constructor  //---------------------------------------------------------------------- -Variable::Variable (lldb::user_id_t uid, -                    const char *name, -                    const char *mangled,  // The mangled or fully qualified name of the variable. -                    const lldb::SymbolFileTypeSP &symfile_type_sp, -                    ValueType scope, -                    SymbolContextScope *context, -                    const RangeList& scope_range, -                    Declaration* decl_ptr, -                    const DWARFExpression& location, -                    bool external, -                    bool artificial, -                    bool static_member) : -    UserID(uid), -    m_name(name), -    m_mangled (ConstString(mangled)), -    m_symfile_type_sp(symfile_type_sp), -    m_scope(scope), -    m_owner_scope(context), -    m_scope_range(scope_range), -    m_declaration(decl_ptr), -    m_location(location), -    m_external(external), -    m_artificial(artificial), -    m_static_member(static_member) -{ -} +Variable::Variable( +    lldb::user_id_t uid, const char *name, +    const char *mangled, // The mangled or fully qualified name of the variable. +    const lldb::SymbolFileTypeSP &symfile_type_sp, ValueType scope, +    SymbolContextScope *context, const RangeList &scope_range, +    Declaration *decl_ptr, const DWARFExpression &location, bool external, +    bool artificial, bool static_member) +    : UserID(uid), m_name(name), m_mangled(ConstString(mangled)), +      m_symfile_type_sp(symfile_type_sp), m_scope(scope), +      m_owner_scope(context), m_scope_range(scope_range), +      m_declaration(decl_ptr), m_location(location), m_external(external), +      m_artificial(artificial), m_static_member(static_member) {}  //----------------------------------------------------------------------  // Destructor  //---------------------------------------------------------------------- -Variable::~Variable() -{ +Variable::~Variable() {} + +lldb::LanguageType Variable::GetLanguage() const { +  SymbolContext variable_sc; +  m_owner_scope->CalculateSymbolContext(&variable_sc); +  if (variable_sc.comp_unit) +    return variable_sc.comp_unit->GetLanguage(); +  return lldb::eLanguageTypeUnknown;  } -lldb::LanguageType -Variable::GetLanguage () const -{ -    SymbolContext variable_sc; -    m_owner_scope->CalculateSymbolContext(&variable_sc); -    if (variable_sc.comp_unit) -        return variable_sc.comp_unit->GetLanguage(); -    return lldb::eLanguageTypeUnknown; +ConstString Variable::GetName() const { +  ConstString name = m_mangled.GetName(GetLanguage()); +  if (name) +    return name; +  return m_name;  } +ConstString Variable::GetUnqualifiedName() const { return m_name; } +bool Variable::NameMatches(const ConstString &name) const { +  if (m_name == name) +    return true; +  SymbolContext variable_sc; +  m_owner_scope->CalculateSymbolContext(&variable_sc); -ConstString -Variable::GetName() const -{ -    ConstString name = m_mangled.GetName(GetLanguage()); -    if (name) -        return name; -    return m_name; +  LanguageType language = eLanguageTypeUnknown; +  if (variable_sc.comp_unit) +    language = variable_sc.comp_unit->GetLanguage(); +  return m_mangled.NameMatches(name, language);  } - -ConstString -Variable::GetUnqualifiedName() const -{ -    return m_name; +bool Variable::NameMatches(const RegularExpression ®ex) const { +  if (regex.Execute(m_name.AsCString())) +    return true; +  if (m_mangled) +    return m_mangled.NameMatches(regex, GetLanguage()); +  return false;  } - -bool -Variable::NameMatches (const ConstString &name) const -{ -    if (m_name == name) -        return true; -    SymbolContext variable_sc; -    m_owner_scope->CalculateSymbolContext(&variable_sc); - -    LanguageType language = eLanguageTypeUnknown; -    if (variable_sc.comp_unit) -        language = variable_sc.comp_unit->GetLanguage(); -    return m_mangled.NameMatches (name, language); -} -bool -Variable::NameMatches (const RegularExpression& regex) const -{ -    if (regex.Execute (m_name.AsCString())) -        return true; -    if (m_mangled) -        return m_mangled.NameMatches (regex, GetLanguage()); -    return false; +Type *Variable::GetType() { +  if (m_symfile_type_sp) +    return m_symfile_type_sp->GetType(); +  return nullptr;  } -Type * -Variable::GetType() -{ -    if (m_symfile_type_sp) -        return m_symfile_type_sp->GetType(); -    return nullptr; -} +void Variable::Dump(Stream *s, bool show_context) const { +  s->Printf("%p: ", static_cast<const void *>(this)); +  s->Indent(); +  *s << "Variable" << (const UserID &)*this; -void -Variable::Dump(Stream *s, bool show_context) const -{ -    s->Printf("%p: ", static_cast<const void*>(this)); -    s->Indent(); -    *s << "Variable" << (const UserID&)*this; - -    if (m_name) -        *s << ", name = \"" << m_name << "\""; - -    if (m_symfile_type_sp) -    { -        Type *type = m_symfile_type_sp->GetType(); -        if (type) -        { -            *s << ", type = {" << type->GetID() << "} " << (void*)type << " ("; -            type->DumpTypeName(s); -            s->PutChar(')'); -        } -    } +  if (m_name) +    *s << ", name = \"" << m_name << "\""; -    if (m_scope != eValueTypeInvalid) -    { -        s->PutCString(", scope = "); -        switch (m_scope) -        { -        case eValueTypeVariableGlobal:       s->PutCString(m_external ? "global" : "static"); break; -        case eValueTypeVariableArgument: -            s->PutCString("parameter"); -            break; -        case eValueTypeVariableLocal:        s->PutCString("local"); break; -        case eValueTypeVariableThreadLocal: -            s->PutCString("thread local"); -            break; -        default:            *s << "??? (" << m_scope << ')'; -        } +  if (m_symfile_type_sp) { +    Type *type = m_symfile_type_sp->GetType(); +    if (type) { +      *s << ", type = {" << type->GetID() << "} " << (void *)type << " ("; +      type->DumpTypeName(s); +      s->PutChar(')');      } +  } -    if (show_context && m_owner_scope != nullptr) -    { -        s->PutCString(", context = ( "); -        m_owner_scope->DumpSymbolContext(s); -        s->PutCString(" )"); +  if (m_scope != eValueTypeInvalid) { +    s->PutCString(", scope = "); +    switch (m_scope) { +    case eValueTypeVariableGlobal: +      s->PutCString(m_external ? "global" : "static"); +      break; +    case eValueTypeVariableArgument: +      s->PutCString("parameter"); +      break; +    case eValueTypeVariableLocal: +      s->PutCString("local"); +      break; +    case eValueTypeVariableThreadLocal: +      s->PutCString("thread local"); +      break; +    default: +      *s << "??? (" << m_scope << ')';      } - -    bool show_fullpaths = false; -    m_declaration.Dump(s, show_fullpaths); - -    if (m_location.IsValid()) -    { -        s->PutCString(", location = "); -        lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; -        if (m_location.IsLocationList()) -        { -            SymbolContext variable_sc; -            m_owner_scope->CalculateSymbolContext(&variable_sc); -            if (variable_sc.function) -                loclist_base_addr = variable_sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); -        } -        ABI *abi = nullptr; -        if (m_owner_scope) -        { -            ModuleSP module_sp (m_owner_scope->CalculateSymbolContextModule()); -            if (module_sp) -                abi = ABI::FindPlugin (module_sp->GetArchitecture()).get(); -        } -        m_location.GetDescription(s, lldb::eDescriptionLevelBrief, loclist_base_addr, abi); +  } + +  if (show_context && m_owner_scope != nullptr) { +    s->PutCString(", context = ( "); +    m_owner_scope->DumpSymbolContext(s); +    s->PutCString(" )"); +  } + +  bool show_fullpaths = false; +  m_declaration.Dump(s, show_fullpaths); + +  if (m_location.IsValid()) { +    s->PutCString(", location = "); +    lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS; +    if (m_location.IsLocationList()) { +      SymbolContext variable_sc; +      m_owner_scope->CalculateSymbolContext(&variable_sc); +      if (variable_sc.function) +        loclist_base_addr = variable_sc.function->GetAddressRange() +                                .GetBaseAddress() +                                .GetFileAddress(); +    } +    ABI *abi = nullptr; +    if (m_owner_scope) { +      ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule()); +      if (module_sp) +        abi = ABI::FindPlugin(module_sp->GetArchitecture()).get();      } +    m_location.GetDescription(s, lldb::eDescriptionLevelBrief, +                              loclist_base_addr, abi); +  } -    if (m_external) -        s->PutCString(", external"); +  if (m_external) +    s->PutCString(", external"); -    if (m_artificial) -        s->PutCString(", artificial"); +  if (m_artificial) +    s->PutCString(", artificial"); -    s->EOL(); +  s->EOL();  } -bool -Variable::DumpDeclaration (Stream *s, bool show_fullpaths, bool show_module) -{ -    bool dumped_declaration_info = false; -    if (m_owner_scope) -    { -        SymbolContext sc; -        m_owner_scope->CalculateSymbolContext(&sc); -        sc.block = nullptr; -        sc.line_entry.Clear(); -        bool show_inlined_frames = false; -        const bool show_function_arguments = true; -        const bool show_function_name = true; -     -        dumped_declaration_info = sc.DumpStopContext (s,  -                                                      nullptr, -                                                      Address(),  -                                                      show_fullpaths,  -                                                      show_module,  -                                                      show_inlined_frames, -                                                      show_function_arguments, -                                                      show_function_name); -         -        if (sc.function) -            s->PutChar(':'); -    } -    if (m_declaration.DumpStopContext (s, false)) -        dumped_declaration_info = true; -    return dumped_declaration_info; +bool Variable::DumpDeclaration(Stream *s, bool show_fullpaths, +                               bool show_module) { +  bool dumped_declaration_info = false; +  if (m_owner_scope) { +    SymbolContext sc; +    m_owner_scope->CalculateSymbolContext(&sc); +    sc.block = nullptr; +    sc.line_entry.Clear(); +    bool show_inlined_frames = false; +    const bool show_function_arguments = true; +    const bool show_function_name = true; + +    dumped_declaration_info = sc.DumpStopContext( +        s, nullptr, Address(), show_fullpaths, show_module, show_inlined_frames, +        show_function_arguments, show_function_name); + +    if (sc.function) +      s->PutChar(':'); +  } +  if (m_declaration.DumpStopContext(s, false)) +    dumped_declaration_info = true; +  return dumped_declaration_info;  } -size_t -Variable::MemorySize() const -{ -    return sizeof(Variable); +size_t Variable::MemorySize() const { return sizeof(Variable); } + +CompilerDeclContext Variable::GetDeclContext() { +  Type *type = GetType(); +  if (type) +    return type->GetSymbolFile()->GetDeclContextContainingUID(GetID()); +  return CompilerDeclContext();  } -CompilerDeclContext -Variable::GetDeclContext () -{ -    Type *type = GetType(); -    if (type) -        return type->GetSymbolFile()->GetDeclContextContainingUID(GetID()); -    return CompilerDeclContext(); +CompilerDecl Variable::GetDecl() { +  Type *type = GetType(); +  return type ? type->GetSymbolFile()->GetDeclForUID(GetID()) : CompilerDecl();  } -CompilerDecl -Variable::GetDecl () -{ -    Type *type = GetType(); -    return type ? type->GetSymbolFile()->GetDeclForUID(GetID()) : CompilerDecl(); +void Variable::CalculateSymbolContext(SymbolContext *sc) { +  if (m_owner_scope) { +    m_owner_scope->CalculateSymbolContext(sc); +    sc->variable = this; +  } else +    sc->Clear(false);  } -void -Variable::CalculateSymbolContext (SymbolContext *sc) -{ -    if (m_owner_scope) -    { -        m_owner_scope->CalculateSymbolContext(sc); -        sc->variable = this; +bool Variable::LocationIsValidForFrame(StackFrame *frame) { +  // Is the variable is described by a single location? +  if (!m_location.IsLocationList()) { +    // Yes it is, the location is valid. +    return true; +  } + +  if (frame) { +    Function *function = +        frame->GetSymbolContext(eSymbolContextFunction).function; +    if (function) { +      TargetSP target_sp(frame->CalculateTarget()); + +      addr_t loclist_base_load_addr = +          function->GetAddressRange().GetBaseAddress().GetLoadAddress( +              target_sp.get()); +      if (loclist_base_load_addr == LLDB_INVALID_ADDRESS) +        return false; +      // It is a location list. We just need to tell if the location +      // list contains the current address when converted to a load +      // address +      return m_location.LocationListContainsAddress( +          loclist_base_load_addr, +          frame->GetFrameCodeAddress().GetLoadAddress(target_sp.get()));      } -    else -        sc->Clear(false); +  } +  return false;  } -bool -Variable::LocationIsValidForFrame (StackFrame *frame) -{ -    // Is the variable is described by a single location? -    if (!m_location.IsLocationList()) -    { -        // Yes it is, the location is valid.  +bool Variable::LocationIsValidForAddress(const Address &address) { +  // Be sure to resolve the address to section offset prior to +  // calling this function. +  if (address.IsSectionOffset()) { +    SymbolContext sc; +    CalculateSymbolContext(&sc); +    if (sc.module_sp == address.GetModule()) { +      // Is the variable is described by a single location? +      if (!m_location.IsLocationList()) { +        // Yes it is, the location is valid.          return true; +      } + +      if (sc.function) { +        addr_t loclist_base_file_addr = +            sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); +        if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) +          return false; +        // It is a location list. We just need to tell if the location +        // list contains the current address when converted to a load +        // address +        return m_location.LocationListContainsAddress(loclist_base_file_addr, +                                                      address.GetFileAddress()); +      }      } +  } +  return false; +} -    if (frame) -    { -        Function *function = frame->GetSymbolContext(eSymbolContextFunction).function; -        if (function) -        { -            TargetSP target_sp (frame->CalculateTarget()); -             -            addr_t loclist_base_load_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress (target_sp.get()); -            if (loclist_base_load_addr == LLDB_INVALID_ADDRESS) -                return false; -            // It is a location list. We just need to tell if the location -            // list contains the current address when converted to a load -            // address -            return m_location.LocationListContainsAddress (loclist_base_load_addr,  -                                                           frame->GetFrameCodeAddress().GetLoadAddress (target_sp.get())); -        } +bool Variable::IsInScope(StackFrame *frame) { +  switch (m_scope) { +  case eValueTypeRegister: +  case eValueTypeRegisterSet: +    return frame != nullptr; + +  case eValueTypeConstResult: +  case eValueTypeVariableGlobal: +  case eValueTypeVariableStatic: +  case eValueTypeVariableThreadLocal: +    return true; + +  case eValueTypeVariableArgument: +  case eValueTypeVariableLocal: +    if (frame) { +      // We don't have a location list, we just need to see if the block +      // that this variable was defined in is currently +      Block *deepest_frame_block = +          frame->GetSymbolContext(eSymbolContextBlock).block; +      if (deepest_frame_block) { +        SymbolContext variable_sc; +        CalculateSymbolContext(&variable_sc); + +        // Check for static or global variable defined at the compile unit +        // level that wasn't defined in a block +        if (variable_sc.block == nullptr) +          return true; + +        // Check if the variable is valid in the current block +        if (variable_sc.block != deepest_frame_block && +            !variable_sc.block->Contains(deepest_frame_block)) +          return false; + +        // If no scope range is specified then it means that the scope is the +        // same as the +        // scope of the enclosing lexical block. +        if (m_scope_range.IsEmpty()) +          return true; + +        addr_t file_address = frame->GetFrameCodeAddress().GetFileAddress(); +        return m_scope_range.FindEntryThatContains(file_address) != nullptr; +      }      } -    return false; +    break; + +  default: +    break; +  } +  return false;  } -bool -Variable::LocationIsValidForAddress (const Address &address) -{ -    // Be sure to resolve the address to section offset prior to  -    // calling this function. -    if (address.IsSectionOffset()) -    { -        SymbolContext sc; -        CalculateSymbolContext(&sc); -        if (sc.module_sp == address.GetModule()) -        { -            // Is the variable is described by a single location? -            if (!m_location.IsLocationList()) -            { -                // Yes it is, the location is valid.  -                return true; -            } -             -            if (sc.function) -            { -                addr_t loclist_base_file_addr = sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); -                if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) -                    return false; -                // It is a location list. We just need to tell if the location -                // list contains the current address when converted to a load -                // address -                return m_location.LocationListContainsAddress (loclist_base_file_addr,  -                                                               address.GetFileAddress()); -            } +Error Variable::GetValuesForVariableExpressionPath( +    llvm::StringRef variable_expr_path, ExecutionContextScope *scope, +    GetVariableCallback callback, void *baton, VariableList &variable_list, +    ValueObjectList &valobj_list) { +  Error error; +  if (!callback || variable_expr_path.empty()) { +    error.SetErrorString("unknown error"); +    return error; +  } + +  switch (variable_expr_path.front()) { +  case '*': +    error = Variable::GetValuesForVariableExpressionPath( +        variable_expr_path.drop_front(), scope, callback, baton, variable_list, +        valobj_list); +    if (error.Fail()) { +      error.SetErrorString("unknown error"); +      return error; +    } +    for (uint32_t i = 0; i < valobj_list.GetSize();) { +      Error tmp_error; +      ValueObjectSP valobj_sp( +          valobj_list.GetValueObjectAtIndex(i)->Dereference(tmp_error)); +      if (tmp_error.Fail()) { +        variable_list.RemoveVariableAtIndex(i); +        valobj_list.RemoveValueObjectAtIndex(i); +      } else { +        valobj_list.SetValueObjectAtIndex(i, valobj_sp); +        ++i; +      } +    } +    return error; +  case '&': { +    error = Variable::GetValuesForVariableExpressionPath( +        variable_expr_path.drop_front(), scope, callback, baton, variable_list, +        valobj_list); +    if (error.Success()) { +      for (uint32_t i = 0; i < valobj_list.GetSize();) { +        Error tmp_error; +        ValueObjectSP valobj_sp( +            valobj_list.GetValueObjectAtIndex(i)->AddressOf(tmp_error)); +        if (tmp_error.Fail()) { +          variable_list.RemoveVariableAtIndex(i); +          valobj_list.RemoveValueObjectAtIndex(i); +        } else { +          valobj_list.SetValueObjectAtIndex(i, valobj_sp); +          ++i;          } +      } +    } else { +      error.SetErrorString("unknown error");      } -    return false; -} - -bool -Variable::IsInScope (StackFrame *frame) -{ -    switch (m_scope) -    { -    case eValueTypeRegister: -    case eValueTypeRegisterSet: -        return frame != nullptr; - -    case eValueTypeConstResult: -    case eValueTypeVariableGlobal: -    case eValueTypeVariableStatic: -    case eValueTypeVariableThreadLocal: -        return true; - -    case eValueTypeVariableArgument: -    case eValueTypeVariableLocal: -        if (frame) -        { -            // We don't have a location list, we just need to see if the block -            // that this variable was defined in is currently -            Block *deepest_frame_block = frame->GetSymbolContext(eSymbolContextBlock).block; -            if (deepest_frame_block) -            { -                SymbolContext variable_sc; -                CalculateSymbolContext (&variable_sc); - -                // Check for static or global variable defined at the compile unit  -                // level that wasn't defined in a block -                if (variable_sc.block == nullptr) -                    return true; - -                // Check if the variable is valid in the current block -                if (variable_sc.block != deepest_frame_block && -                    !variable_sc.block->Contains(deepest_frame_block)) -                    return false; - -                // If no scope range is specified then it means that the scope is the same as the -                // scope of the enclosing lexical block. -                if (m_scope_range.IsEmpty()) -                    return true; - -                addr_t file_address = frame->GetFrameCodeAddress().GetFileAddress(); -                return m_scope_range.FindEntryThatContains(file_address) != nullptr; -            } +    return error; +  } break; + +  default: { +    static RegularExpression g_regex( +        llvm::StringRef("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)")); +    RegularExpression::Match regex_match(1); +    std::string variable_name; +    variable_list.Clear(); +    if (!g_regex.Execute(variable_expr_path, ®ex_match)) { +      error.SetErrorStringWithFormat( +          "unable to extract a variable name from '%s'", +          variable_expr_path.str().c_str()); +      return error; +    } +    if (!regex_match.GetMatchAtIndex(variable_expr_path, 1, variable_name)) { +      error.SetErrorStringWithFormat( +          "unable to extract a variable name from '%s'", +          variable_expr_path.str().c_str()); +      return error; +    } +    if (!callback(baton, variable_name.c_str(), variable_list)) { +      error.SetErrorString("unknown error"); +      return error; +    } +    uint32_t i = 0; +    while (i < variable_list.GetSize()) { +      VariableSP var_sp(variable_list.GetVariableAtIndex(i)); +      ValueObjectSP valobj_sp; +      if (!var_sp) { +        variable_list.RemoveVariableAtIndex(i); +        continue; +      } +      ValueObjectSP variable_valobj_sp( +          ValueObjectVariable::Create(scope, var_sp)); +      if (!variable_valobj_sp) { +        variable_list.RemoveVariableAtIndex(i); +        continue; +      } + +      llvm::StringRef variable_sub_expr_path = +          variable_expr_path.drop_front(variable_name.size()); +      if (!variable_sub_expr_path.empty()) { +        ValueObject::ExpressionPathScanEndReason reason_to_stop; +        ValueObject::ExpressionPathEndResultType final_value_type; +        ValueObject::GetValueForExpressionPathOptions options; +        ValueObject::ExpressionPathAftermath final_task_on_target; + +        valobj_sp = variable_valobj_sp->GetValueForExpressionPath( +            variable_sub_expr_path, &reason_to_stop, &final_value_type, options, +            &final_task_on_target); +        if (!valobj_sp) { +          error.SetErrorStringWithFormat( +              "invalid expression path '%s' for variable '%s'", +              variable_sub_expr_path.str().c_str(), +              var_sp->GetName().GetCString()); +          variable_list.RemoveVariableAtIndex(i); +          continue;          } -        break; +      } else { +        // Just the name of a variable with no extras +        valobj_sp = variable_valobj_sp; +      } -    default: -        break; +      valobj_list.Append(valobj_sp); +      ++i;      } -    return false; -} -Error -Variable::GetValuesForVariableExpressionPath (const char *variable_expr_path, -                                              ExecutionContextScope *scope, -                                              GetVariableCallback callback, -                                              void *baton, -                                              VariableList &variable_list, -                                              ValueObjectList &valobj_list) -{ -    Error error; -    if (variable_expr_path && callback) -    { -        switch (variable_expr_path[0]) -        { -        case '*': -            { -                error = Variable::GetValuesForVariableExpressionPath (variable_expr_path + 1, -                                                                      scope, -                                                                      callback, -                                                                      baton, -                                                                      variable_list, -                                                                      valobj_list); -                if (error.Success()) -                { -                    for (uint32_t i=0; i<valobj_list.GetSize(); ) -                    { -                        Error tmp_error; -                        ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(i)->Dereference(tmp_error)); -                        if (tmp_error.Fail()) -                        { -                            variable_list.RemoveVariableAtIndex (i); -                            valobj_list.RemoveValueObjectAtIndex (i); -                        } -                        else -                        { -                            valobj_list.SetValueObjectAtIndex (i, valobj_sp); -                            ++i; -                        } -                    } -                } -                else -                { -                    error.SetErrorString ("unknown error"); -                } -                return error; -            } -            break; -         -        case '&': -            { -                error = Variable::GetValuesForVariableExpressionPath (variable_expr_path + 1, -                                                                      scope, -                                                                      callback, -                                                                      baton, -                                                                      variable_list, -                                                                      valobj_list); -                if (error.Success()) -                { -                    for (uint32_t i=0; i<valobj_list.GetSize(); ) -                    { -                        Error tmp_error; -                        ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(i)->AddressOf(tmp_error)); -                        if (tmp_error.Fail()) -                        { -                            variable_list.RemoveVariableAtIndex (i); -                            valobj_list.RemoveValueObjectAtIndex (i); -                        } -                        else -                        { -                            valobj_list.SetValueObjectAtIndex (i, valobj_sp); -                            ++i; -                        } -                    } -                } -                else -                { -                    error.SetErrorString ("unknown error"); -                } -                return error; -            } -            break; -             -        default: -            { -                static RegularExpression g_regex ("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)"); -                RegularExpression::Match regex_match(1); -                if (g_regex.Execute(variable_expr_path, ®ex_match)) -                { -                    std::string variable_name; -                    if (regex_match.GetMatchAtIndex(variable_expr_path, 1, variable_name)) -                    { -                        variable_list.Clear(); -                        if (callback (baton, variable_name.c_str(), variable_list)) -                        { -                            uint32_t i=0; -                            while (i < variable_list.GetSize()) -                            { -                                VariableSP var_sp (variable_list.GetVariableAtIndex (i)); -                                ValueObjectSP valobj_sp; -                                if (var_sp) -                                { -                                    ValueObjectSP variable_valobj_sp(ValueObjectVariable::Create (scope, var_sp)); -                                    if (variable_valobj_sp) -                                    { -                                        const char *variable_sub_expr_path = variable_expr_path + variable_name.size(); -                                        if (*variable_sub_expr_path) -                                        { -                                            const char* first_unparsed = nullptr; -                                            ValueObject::ExpressionPathScanEndReason reason_to_stop; -                                            ValueObject::ExpressionPathEndResultType final_value_type; -                                            ValueObject::GetValueForExpressionPathOptions options; -                                            ValueObject::ExpressionPathAftermath final_task_on_target; - -                                            valobj_sp = variable_valobj_sp->GetValueForExpressionPath (variable_sub_expr_path, -                                                                                                       &first_unparsed, -                                                                                                       &reason_to_stop, -                                                                                                       &final_value_type, -                                                                                                       options, -                                                                                                       &final_task_on_target); -                                            if (!valobj_sp) -                                            { -                                                error.SetErrorStringWithFormat ("invalid expression path '%s' for variable '%s'", -                                                                                variable_sub_expr_path, -                                                                                var_sp->GetName().GetCString()); -                                            } -                                        } -                                        else -                                        { -                                            // Just the name of a variable with no extras -                                            valobj_sp = variable_valobj_sp; -                                        } -                                    } -                                } - -                                if (!var_sp || !valobj_sp) -                                { -                                    variable_list.RemoveVariableAtIndex (i); -                                } -                                else -                                { -                                    valobj_list.Append(valobj_sp); -                                    ++i; -                                } -                            } -                             -                            if (variable_list.GetSize() > 0) -                            { -                                error.Clear(); -                                return error; -                            } -                        } -                    } -                } -                error.SetErrorStringWithFormat ("unable to extract a variable name from '%s'", variable_expr_path); -            } -            break; -        } +    if (variable_list.GetSize() > 0) { +      error.Clear(); +      return error;      } -    error.SetErrorString ("unknown error"); -    return error; +  } break; +  } +  error.SetErrorString("unknown error"); +  return error;  } -bool -Variable::DumpLocationForAddress (Stream *s, const Address &address) -{ -    // Be sure to resolve the address to section offset prior to  -    // calling this function. -    if (address.IsSectionOffset()) -    { -        SymbolContext sc; -        CalculateSymbolContext(&sc); -        if (sc.module_sp == address.GetModule()) -        { -            ABI *abi = nullptr; -            if (m_owner_scope) -            { -                ModuleSP module_sp (m_owner_scope->CalculateSymbolContextModule()); -                if (module_sp) -                    abi = ABI::FindPlugin (module_sp->GetArchitecture()).get(); -            } - -            const addr_t file_addr = address.GetFileAddress(); -            if (sc.function) -            { -                if (sc.function->GetAddressRange().ContainsFileAddress(address)) -                { -                    addr_t loclist_base_file_addr = sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); -                    if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) -                        return false; -                    return m_location.DumpLocationForAddress (s,  -                                                              eDescriptionLevelBrief,  -                                                              loclist_base_file_addr,  -                                                              file_addr, -                                                              abi); -                } -            } -            return m_location.DumpLocationForAddress (s,  -                                                      eDescriptionLevelBrief,  -                                                      LLDB_INVALID_ADDRESS,  -                                                      file_addr, -                                                      abi); +bool Variable::DumpLocationForAddress(Stream *s, const Address &address) { +  // Be sure to resolve the address to section offset prior to +  // calling this function. +  if (address.IsSectionOffset()) { +    SymbolContext sc; +    CalculateSymbolContext(&sc); +    if (sc.module_sp == address.GetModule()) { +      ABI *abi = nullptr; +      if (m_owner_scope) { +        ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule()); +        if (module_sp) +          abi = ABI::FindPlugin(module_sp->GetArchitecture()).get(); +      } + +      const addr_t file_addr = address.GetFileAddress(); +      if (sc.function) { +        if (sc.function->GetAddressRange().ContainsFileAddress(address)) { +          addr_t loclist_base_file_addr = +              sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); +          if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) +            return false; +          return m_location.DumpLocationForAddress(s, eDescriptionLevelBrief, +                                                   loclist_base_file_addr, +                                                   file_addr, abi);          } +      } +      return m_location.DumpLocationForAddress( +          s, eDescriptionLevelBrief, LLDB_INVALID_ADDRESS, file_addr, abi);      } -    return false; +  } +  return false;  } - -static void -PrivateAutoComplete (StackFrame *frame, -                     const std::string &partial_path, -                     const std::string &prefix_path, // Anything that has been resolved already will be in here -                     const CompilerType& compiler_type, -                     StringList &matches, -                     bool &word_complete); - -static void -PrivateAutoCompleteMembers (StackFrame *frame, -                            const std::string &partial_member_name, -                            const std::string &partial_path, -                            const std::string &prefix_path, // Anything that has been resolved already will be in here -                            const CompilerType& compiler_type, -                            StringList &matches, -                            bool &word_complete); - -static void -PrivateAutoCompleteMembers (StackFrame *frame, -                            const std::string &partial_member_name, -                            const std::string &partial_path, -                            const std::string &prefix_path, // Anything that has been resolved already will be in here -                            const CompilerType& compiler_type, -                            StringList &matches, -                            bool &word_complete) -{ - -    // We are in a type parsing child members -    const uint32_t num_bases = compiler_type.GetNumDirectBaseClasses(); -     -    if (num_bases > 0) -    { -        for (uint32_t i = 0; i < num_bases; ++i) -        { -            CompilerType base_class_type = compiler_type.GetDirectBaseClassAtIndex(i, nullptr); -             -            PrivateAutoCompleteMembers (frame, -                                        partial_member_name, -                                        partial_path, -                                        prefix_path, -                                        base_class_type.GetCanonicalType(), -                                        matches, -                                        word_complete); -        } +static void PrivateAutoComplete( +    StackFrame *frame, llvm::StringRef partial_path, +    const llvm::Twine +        &prefix_path, // Anything that has been resolved already will be in here +    const CompilerType &compiler_type, +    StringList &matches, bool &word_complete); + +static void PrivateAutoCompleteMembers( +    StackFrame *frame, const std::string &partial_member_name, +    llvm::StringRef partial_path, +    const llvm::Twine +        &prefix_path, // Anything that has been resolved already will be in here +    const CompilerType &compiler_type, +    StringList &matches, bool &word_complete); + +static void PrivateAutoCompleteMembers( +    StackFrame *frame, const std::string &partial_member_name, +    llvm::StringRef partial_path, +    const llvm::Twine +        &prefix_path, // Anything that has been resolved already will be in here +    const CompilerType &compiler_type, +    StringList &matches, bool &word_complete) { + +  // We are in a type parsing child members +  const uint32_t num_bases = compiler_type.GetNumDirectBaseClasses(); + +  if (num_bases > 0) { +    for (uint32_t i = 0; i < num_bases; ++i) { +      CompilerType base_class_type = +          compiler_type.GetDirectBaseClassAtIndex(i, nullptr); + +      PrivateAutoCompleteMembers( +          frame, partial_member_name, partial_path, prefix_path, +          base_class_type.GetCanonicalType(), matches, word_complete);      } +  } -    const uint32_t num_vbases = compiler_type.GetNumVirtualBaseClasses(); -     -    if (num_vbases > 0) -    { -        for (uint32_t i = 0; i < num_vbases; ++i) -        { -            CompilerType vbase_class_type = compiler_type.GetVirtualBaseClassAtIndex(i,nullptr); -             -            PrivateAutoCompleteMembers (frame, -                                        partial_member_name, -                                        partial_path, -                                        prefix_path, -                                        vbase_class_type.GetCanonicalType(), -                                        matches, -                                        word_complete); -        } -    } +  const uint32_t num_vbases = compiler_type.GetNumVirtualBaseClasses(); -    // We are in a type parsing child members -    const uint32_t num_fields = compiler_type.GetNumFields(); -     -    if (num_fields > 0) -    { -        for (uint32_t i = 0; i < num_fields; ++i) -        { -            std::string member_name; -             -            CompilerType member_compiler_type = compiler_type.GetFieldAtIndex (i, member_name, nullptr, nullptr, nullptr); -             -            if (partial_member_name.empty() || -                member_name.find(partial_member_name) == 0) -            { -                if (member_name == partial_member_name) -                { -                    PrivateAutoComplete (frame, -                                         partial_path, -                                         prefix_path + member_name, // Anything that has been resolved already will be in here -                                         member_compiler_type.GetCanonicalType(), -                                         matches, -                                         word_complete); -                } -                else -                { -                    matches.AppendString (prefix_path + member_name); -                } -            } +  if (num_vbases > 0) { +    for (uint32_t i = 0; i < num_vbases; ++i) { +      CompilerType vbase_class_type = +          compiler_type.GetVirtualBaseClassAtIndex(i, nullptr); + +      PrivateAutoCompleteMembers( +          frame, partial_member_name, partial_path, prefix_path, +          vbase_class_type.GetCanonicalType(), matches, word_complete); +    } +  } + +  // We are in a type parsing child members +  const uint32_t num_fields = compiler_type.GetNumFields(); + +  if (num_fields > 0) { +    for (uint32_t i = 0; i < num_fields; ++i) { +      std::string member_name; + +      CompilerType member_compiler_type = compiler_type.GetFieldAtIndex( +          i, member_name, nullptr, nullptr, nullptr); + +      if (partial_member_name.empty() || +          member_name.find(partial_member_name) == 0) { +        if (member_name == partial_member_name) { +          PrivateAutoComplete( +              frame, partial_path, +              prefix_path + member_name, // Anything that has been resolved +                                         // already will be in here +              member_compiler_type.GetCanonicalType(), matches, word_complete); +        } else { +          matches.AppendString((prefix_path + member_name).str());          } +      }      } +  }  } -static void -PrivateAutoComplete (StackFrame *frame, -                     const std::string &partial_path, -                     const std::string &prefix_path, // Anything that has been resolved already will be in here -                     const CompilerType& compiler_type, -                     StringList &matches, -                     bool &word_complete) -{ -//    printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path = '%s'\n", prefix_path.c_str(), partial_path.c_str()); -    std::string remaining_partial_path; - -    const lldb::TypeClass type_class = compiler_type.GetTypeClass(); -    if (partial_path.empty()) -    { -        if (compiler_type.IsValid()) -        { -            switch (type_class) -            { -                default: -                case eTypeClassArray: -                case eTypeClassBlockPointer: -                case eTypeClassBuiltin: -                case eTypeClassComplexFloat: -                case eTypeClassComplexInteger: -                case eTypeClassEnumeration: -                case eTypeClassFunction: -                case eTypeClassMemberPointer: -                case eTypeClassReference: -                case eTypeClassTypedef: -                case eTypeClassVector: -                    { -                        matches.AppendString (prefix_path); -                        word_complete = matches.GetSize() == 1; -                    } -                    break; -                     -                case eTypeClassClass: -                case eTypeClassStruct: -                case eTypeClassUnion: -                    if (prefix_path.back() != '.') -                        matches.AppendString (prefix_path + '.'); -                    break; - -                case eTypeClassObjCObject: -                case eTypeClassObjCInterface: -                    break; -                case eTypeClassObjCObjectPointer: -                case eTypeClassPointer: -                    { -                        bool omit_empty_base_classes = true; -                        if (compiler_type.GetNumChildren (omit_empty_base_classes) > 0) -                            matches.AppendString (prefix_path + "->"); -                        else -                        { -                            matches.AppendString (prefix_path); -                            word_complete = true; -                        } -                    } -                    break; -            } +static void PrivateAutoComplete( +    StackFrame *frame, llvm::StringRef partial_path, +    const llvm::Twine +        &prefix_path, // Anything that has been resolved already will be in here +    const CompilerType &compiler_type, +    StringList &matches, bool &word_complete) { +  //    printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path = +  //    '%s'\n", prefix_path.c_str(), partial_path.c_str()); +  std::string remaining_partial_path; + +  const lldb::TypeClass type_class = compiler_type.GetTypeClass(); +  if (partial_path.empty()) { +    if (compiler_type.IsValid()) { +      switch (type_class) { +      default: +      case eTypeClassArray: +      case eTypeClassBlockPointer: +      case eTypeClassBuiltin: +      case eTypeClassComplexFloat: +      case eTypeClassComplexInteger: +      case eTypeClassEnumeration: +      case eTypeClassFunction: +      case eTypeClassMemberPointer: +      case eTypeClassReference: +      case eTypeClassTypedef: +      case eTypeClassVector: { +        matches.AppendString(prefix_path.str()); +        word_complete = matches.GetSize() == 1; +      } break; + +      case eTypeClassClass: +      case eTypeClassStruct: +      case eTypeClassUnion: +        if (prefix_path.str().back() != '.') +          matches.AppendString((prefix_path + ".").str()); +        break; + +      case eTypeClassObjCObject: +      case eTypeClassObjCInterface: +        break; +      case eTypeClassObjCObjectPointer: +      case eTypeClassPointer: { +        bool omit_empty_base_classes = true; +        if (compiler_type.GetNumChildren(omit_empty_base_classes) > 0) +          matches.AppendString((prefix_path + "->").str()); +        else { +          matches.AppendString(prefix_path.str()); +          word_complete = true;          } -        else -        { -            if (frame) -            { -                const bool get_file_globals = true; -                 -                VariableList *variable_list = frame->GetVariableList(get_file_globals); -                 -                if (variable_list) -                { -                    const size_t num_variables = variable_list->GetSize(); -                    for (size_t i=0; i<num_variables; ++i) -                    { -                        Variable *variable = variable_list->GetVariableAtIndex(i).get(); -                        matches.AppendString (variable->GetName().AsCString()); -                    } -                } -            } +      } break; +      } +    } else { +      if (frame) { +        const bool get_file_globals = true; + +        VariableList *variable_list = frame->GetVariableList(get_file_globals); + +        if (variable_list) { +          const size_t num_variables = variable_list->GetSize(); +          for (size_t i = 0; i < num_variables; ++i) { +            Variable *variable = variable_list->GetVariableAtIndex(i).get(); +            matches.AppendString(variable->GetName().AsCString()); +          }          } +      }      } -    else -    { -        const char ch = partial_path[0]; -        switch (ch) -        { -        case '*': -            if (prefix_path.empty()) -            { -                PrivateAutoComplete (frame, -                                     partial_path.substr(1), -                                     std::string("*"), -                                     compiler_type, -                                     matches, -                                     word_complete); -            } -            break; +  } else { +    const char ch = partial_path[0]; +    switch (ch) { +    case '*': +      if (prefix_path.str().empty()) { +        PrivateAutoComplete(frame, partial_path.substr(1), "*", compiler_type, +                            matches, word_complete); +      } +      break; + +    case '&': +      if (prefix_path.isTriviallyEmpty()) { +        PrivateAutoComplete(frame, partial_path.substr(1), std::string("&"), +                            compiler_type, matches, word_complete); +      } +      break; + +    case '-': +      if (partial_path[1] == '>' && !prefix_path.str().empty()) { +        switch (type_class) { +        case lldb::eTypeClassPointer: { +          CompilerType pointee_type(compiler_type.GetPointeeType()); +          if (partial_path[2]) { +            // If there is more after the "->", then search deeper +            PrivateAutoComplete( +                frame, partial_path.substr(2), prefix_path + "->", +                pointee_type.GetCanonicalType(), matches, word_complete); +          } else { +            // Nothing after the "->", so list all members +            PrivateAutoCompleteMembers( +                frame, std::string(), std::string(), prefix_path + "->", +                pointee_type.GetCanonicalType(), matches, word_complete); +          } +        } break; +        default: +          break; +        } +      } +      break; + +    case '.': +      if (compiler_type.IsValid()) { +        switch (type_class) { +        case lldb::eTypeClassUnion: +        case lldb::eTypeClassStruct: +        case lldb::eTypeClassClass: +          if (partial_path[1]) { +            // If there is more after the ".", then search deeper +            PrivateAutoComplete(frame, partial_path.substr(1), +                                prefix_path + ".", compiler_type, matches, +                                word_complete); + +          } else { +            // Nothing after the ".", so list all members +            PrivateAutoCompleteMembers(frame, std::string(), partial_path, +                                       prefix_path + ".", compiler_type, +                                       matches, word_complete); +          } +          break; +        default: +          break; +        } +      } +      break; +    default: +      if (isalpha(ch) || ch == '_' || ch == '$') { +        const size_t partial_path_len = partial_path.size(); +        size_t pos = 1; +        while (pos < partial_path_len) { +          const char curr_ch = partial_path[pos]; +          if (isalnum(curr_ch) || curr_ch == '_' || curr_ch == '$') { +            ++pos; +            continue; +          } +          break; +        } -        case '&': -            if (prefix_path.empty()) -            { -                PrivateAutoComplete (frame, -                                     partial_path.substr(1), -                                     std::string("&"), -                                     compiler_type, -                                     matches, +        std::string token(partial_path, 0, pos); +        remaining_partial_path = partial_path.substr(pos); + +        if (compiler_type.IsValid()) { +          PrivateAutoCompleteMembers(frame, token, remaining_partial_path, +                                     prefix_path, compiler_type, matches,                                       word_complete); -            } -            break; +        } else if (frame) { +          // We haven't found our variable yet +          const bool get_file_globals = true; -        case '-': -            if (partial_path[1] == '>' && !prefix_path.empty()) -            { -                switch (type_class) -                { -                    case lldb::eTypeClassPointer: -                        { -                            CompilerType pointee_type(compiler_type.GetPointeeType()); -                            if (partial_path[2]) -                            { -                                // If there is more after the "->", then search deeper -                                PrivateAutoComplete (frame, -                                                     partial_path.substr(2), -                                                     prefix_path + "->", -                                                     pointee_type.GetCanonicalType(), -                                                     matches, -                                                     word_complete); -                            } -                            else -                            { -                                // Nothing after the "->", so list all members -                                PrivateAutoCompleteMembers (frame, -                                                            std::string(), -                                                            std::string(), -                                                            prefix_path + "->", -                                                            pointee_type.GetCanonicalType(), -                                                            matches, -                                                            word_complete);                             -                            } -                        } -                        break; -                    default: -                        break; -                } -            } -            break; -             -        case '.': -            if (compiler_type.IsValid()) -            { -                switch (type_class) -                { -                    case lldb::eTypeClassUnion: -                    case lldb::eTypeClassStruct: -                    case lldb::eTypeClassClass: -                        if (partial_path[1]) -                        { -                            // If there is more after the ".", then search deeper -                            PrivateAutoComplete (frame, -                                                 partial_path.substr(1), -                                                 prefix_path + ".", -                                                 compiler_type, -                                                 matches, -                                                 word_complete); -                             -                        } -                        else -                        { -                            // Nothing after the ".", so list all members -                            PrivateAutoCompleteMembers (frame, -                                                        std::string(), -                                                        partial_path, -                                                        prefix_path + ".", -                                                        compiler_type, -                                                        matches, -                                                        word_complete); -                        } -                        break; -                    default: -                        break; -                } -            } +          VariableList *variable_list = +              frame->GetVariableList(get_file_globals); + +          if (!variable_list)              break; -        default: -            if (isalpha(ch) || ch == '_' || ch == '$') -            { -                const size_t partial_path_len = partial_path.size(); -                size_t pos = 1; -                while (pos < partial_path_len) -                { -                    const char curr_ch = partial_path[pos]; -                    if (isalnum(curr_ch) || curr_ch == '_'  || curr_ch == '$') -                    { -                        ++pos; -                        continue; -                    } -                    break; -                } -                std::string token(partial_path, 0, pos); -                remaining_partial_path = partial_path.substr(pos); -                 -                if (compiler_type.IsValid()) -                { -                    PrivateAutoCompleteMembers (frame, -                                                token, -                                                remaining_partial_path, -                                                prefix_path, -                                                compiler_type, -                                                matches, -                                                word_complete); -                } -                else if (frame) -                { -                    // We haven't found our variable yet -                    const bool get_file_globals = true; -                     -                    VariableList *variable_list = frame->GetVariableList(get_file_globals); -                     -                    if (!variable_list) -                        break; -                     -                    const size_t num_variables = variable_list->GetSize(); -                    for (size_t i=0; i<num_variables; ++i) -                    { -                        Variable *variable = variable_list->GetVariableAtIndex(i).get(); -                         -                        if (!variable) -                            continue; -                         -                        const char *variable_name = variable->GetName().AsCString(); -                        if (strstr(variable_name, token.c_str()) == variable_name) -                        { -                            if (strcmp (variable_name, token.c_str()) == 0) -                            { -                                Type *variable_type = variable->GetType(); -                                if (variable_type) -                                { -                                    CompilerType variable_compiler_type (variable_type->GetForwardCompilerType ()); -                                    PrivateAutoComplete (frame, -                                                         remaining_partial_path, -                                                         prefix_path + token, // Anything that has been resolved already will be in here -                                                         variable_compiler_type.GetCanonicalType(), -                                                         matches, -                                                         word_complete); -                                } -                                else -                                { -                                    matches.AppendString (prefix_path + variable_name); -                                } -                            } -                            else if (remaining_partial_path.empty()) -                            { -                                matches.AppendString (prefix_path + variable_name); -                            } -                        } -                    } +          const size_t num_variables = variable_list->GetSize(); +          for (size_t i = 0; i < num_variables; ++i) { +            Variable *variable = variable_list->GetVariableAtIndex(i).get(); + +            if (!variable) +              continue; + +            const char *variable_name = variable->GetName().AsCString(); +            if (strstr(variable_name, token.c_str()) == variable_name) { +              if (strcmp(variable_name, token.c_str()) == 0) { +                Type *variable_type = variable->GetType(); +                if (variable_type) { +                  CompilerType variable_compiler_type( +                      variable_type->GetForwardCompilerType()); +                  PrivateAutoComplete( +                      frame, remaining_partial_path, +                      prefix_path + token, // Anything that has been resolved +                                           // already will be in here +                      variable_compiler_type.GetCanonicalType(), matches, +                      word_complete); +                } else { +                  matches.AppendString((prefix_path + variable_name).str());                  } +              } else if (remaining_partial_path.empty()) { +                matches.AppendString((prefix_path + variable_name).str()); +              }              } -            break; +          }          } +      } +      break;      } +  }  } +size_t Variable::AutoComplete(const ExecutionContext &exe_ctx, +                              llvm::StringRef partial_path, StringList &matches, +                              bool &word_complete) { +  word_complete = false; +  CompilerType compiler_type; +  PrivateAutoComplete(exe_ctx.GetFramePtr(), partial_path, "", compiler_type, +                      matches, word_complete); -size_t -Variable::AutoComplete (const ExecutionContext &exe_ctx, -                        const char *partial_path_cstr, -                        StringList &matches, -                        bool &word_complete) -{ -    word_complete = false; -    std::string partial_path; -    std::string prefix_path; -    CompilerType compiler_type; -    if (partial_path_cstr && partial_path_cstr[0]) -        partial_path = partial_path_cstr; - -    PrivateAutoComplete (exe_ctx.GetFramePtr(), -                         partial_path, -                         prefix_path, -                         compiler_type, -                         matches, -                         word_complete); - -    return matches.GetSize(); +  return matches.GetSize();  } -  | 
