diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:26:05 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:26:05 +0000 | 
| commit | 14f1b3e8826ce43b978db93a62d1166055db5394 (patch) | |
| tree | 0a00ad8d3498783fe0193f3b656bca17c4c8697d /source/Plugins/Language/CPlusPlus | |
| parent | 4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/Language/CPlusPlus')
20 files changed, 3940 insertions, 3404 deletions
| diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp index 92e30d54f6e1..db7c24675825 100644 --- a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp +++ b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp @@ -27,199 +27,185 @@ using namespace lldb;  using namespace lldb_private;  using namespace lldb_private::formatters; -namespace lldb_private -{ -namespace formatters -{ +namespace lldb_private { +namespace formatters { -class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd -{ +class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd {  public: -    BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) -        : SyntheticChildrenFrontEnd(*valobj_sp), -          m_block_struct_type() -    { -        CompilerType block_pointer_type(m_backend.GetCompilerType()); -        CompilerType function_pointer_type; -        block_pointer_type.IsBlockPointerType(&function_pointer_type); -         -        TargetSP target_sp(m_backend.GetTargetSP()); -         -        if (!target_sp) -        { -            return; -        } -         -        Error err; -        TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(&err, lldb::eLanguageTypeC_plus_plus); -         -        if (!err.Success() || !type_system) -        { -            return; -        } -         -        ClangASTContext *clang_ast_context = llvm::dyn_cast<ClangASTContext>(type_system); -         -        if (!clang_ast_context) -        { -            return; -        } -         -        ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter(); -         -        if (!clang_ast_importer) -        { -            return; -        } -         -        const char *const   isa_name("__isa"); -        const CompilerType  isa_type = clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass); -        const char *const   flags_name("__flags"); -        const CompilerType  flags_type = clang_ast_context->GetBasicType(lldb::eBasicTypeInt); -        const char *const   reserved_name("__reserved"); -        const CompilerType  reserved_type = clang_ast_context->GetBasicType(lldb::eBasicTypeInt); -        const char *const   FuncPtr_name("__FuncPtr"); -        const CompilerType  FuncPtr_type = clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type); -         -        m_block_struct_type = clang_ast_context->CreateStructForIdentifier(ConstString(), -                                                                           { -                                                                               {isa_name, isa_type}, -                                                                               {flags_name, flags_type}, -                                                                               {reserved_name, reserved_type}, -                                                                               {FuncPtr_name, FuncPtr_type} -                                                                           }); +  BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +      : SyntheticChildrenFrontEnd(*valobj_sp), m_block_struct_type() { +    CompilerType block_pointer_type(m_backend.GetCompilerType()); +    CompilerType function_pointer_type; +    block_pointer_type.IsBlockPointerType(&function_pointer_type); +    TargetSP target_sp(m_backend.GetTargetSP()); + +    if (!target_sp) { +      return; +    } + +    Error err; +    TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage( +        &err, lldb::eLanguageTypeC_plus_plus); + +    if (!err.Success() || !type_system) { +      return; +    } + +    ClangASTContext *clang_ast_context = +        llvm::dyn_cast<ClangASTContext>(type_system); + +    if (!clang_ast_context) { +      return;      } -    ~BlockPointerSyntheticFrontEnd() override = default; +    ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter(); -    size_t -    CalculateNumChildren() override -    { -        const bool omit_empty_base_classes = false; -        return m_block_struct_type.GetNumChildren(omit_empty_base_classes); +    if (!clang_ast_importer) { +      return;      } -    lldb::ValueObjectSP -    GetChildAtIndex(size_t idx) override -    { -        if (!m_block_struct_type.IsValid()) -        { -            return lldb::ValueObjectSP(); -        } -         -        if (idx >= CalculateNumChildren()) -        { -            return lldb::ValueObjectSP(); -        } -         -        const bool thread_and_frame_only_if_stopped = true; -        ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped); -        const bool transparent_pointers = false; -        const bool omit_empty_base_classes = false; -        const bool ignore_array_bounds = false; -        ValueObject *value_object = nullptr; -     -        std::string child_name; -        uint32_t child_byte_size = 0; -        int32_t child_byte_offset = 0; -        uint32_t child_bitfield_bit_size = 0; -        uint32_t child_bitfield_bit_offset = 0; -        bool child_is_base_class = false; -        bool child_is_deref_of_parent = false; -        uint64_t language_flags = 0; -         -        const CompilerType child_type = m_block_struct_type.GetChildCompilerTypeAtIndex(&exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent, value_object, language_flags); -         -        ValueObjectSP struct_pointer_sp = m_backend.Cast(m_block_struct_type.GetPointerType()); -         -        if (!struct_pointer_sp) -        { -            return lldb::ValueObjectSP(); -        } -         -        Error err; -        ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err); -         -        if (!struct_sp || !err.Success()) -        { -            return lldb::ValueObjectSP(); -        } -         -        ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset(child_byte_offset, -                                                                    child_type, -                                                                    true, -                                                                    ConstString(child_name.c_str(), child_name.size()))); - -        return child_sp; +    const char *const isa_name("__isa"); +    const CompilerType isa_type = +        clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass); +    const char *const flags_name("__flags"); +    const CompilerType flags_type = +        clang_ast_context->GetBasicType(lldb::eBasicTypeInt); +    const char *const reserved_name("__reserved"); +    const CompilerType reserved_type = +        clang_ast_context->GetBasicType(lldb::eBasicTypeInt); +    const char *const FuncPtr_name("__FuncPtr"); +    const CompilerType FuncPtr_type = +        clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type); + +    m_block_struct_type = clang_ast_context->CreateStructForIdentifier( +        ConstString(), {{isa_name, isa_type}, +                        {flags_name, flags_type}, +                        {reserved_name, reserved_type}, +                        {FuncPtr_name, FuncPtr_type}}); +  } + +  ~BlockPointerSyntheticFrontEnd() override = default; + +  size_t CalculateNumChildren() override { +    const bool omit_empty_base_classes = false; +    return m_block_struct_type.GetNumChildren(omit_empty_base_classes); +  } + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { +    if (!m_block_struct_type.IsValid()) { +      return lldb::ValueObjectSP();      } -    // return true if this object is now safe to use forever without -    // ever updating again; the typical (and tested) answer here is -    // 'false' -    bool -    Update() override -    { -        return false; +    if (idx >= CalculateNumChildren()) { +      return lldb::ValueObjectSP();      } -    // maybe return false if the block pointer is, say, null -    bool -    MightHaveChildren() override -    { -        return true; +    const bool thread_and_frame_only_if_stopped = true; +    ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock( +        thread_and_frame_only_if_stopped); +    const bool transparent_pointers = false; +    const bool omit_empty_base_classes = false; +    const bool ignore_array_bounds = false; +    ValueObject *value_object = nullptr; + +    std::string child_name; +    uint32_t child_byte_size = 0; +    int32_t child_byte_offset = 0; +    uint32_t child_bitfield_bit_size = 0; +    uint32_t child_bitfield_bit_offset = 0; +    bool child_is_base_class = false; +    bool child_is_deref_of_parent = false; +    uint64_t language_flags = 0; + +    const CompilerType child_type = +        m_block_struct_type.GetChildCompilerTypeAtIndex( +            &exe_ctx, idx, transparent_pointers, omit_empty_base_classes, +            ignore_array_bounds, child_name, child_byte_size, child_byte_offset, +            child_bitfield_bit_size, child_bitfield_bit_offset, +            child_is_base_class, child_is_deref_of_parent, value_object, +            language_flags); + +    ValueObjectSP struct_pointer_sp = +        m_backend.Cast(m_block_struct_type.GetPointerType()); + +    if (!struct_pointer_sp) { +      return lldb::ValueObjectSP();      } -    size_t -    GetIndexOfChildWithName(const ConstString &name) override -    { -        if (!m_block_struct_type.IsValid()) -            return UINT32_MAX; -         -        const bool omit_empty_base_classes = false; -        return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(), omit_empty_base_classes); +    Error err; +    ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err); + +    if (!struct_sp || !err.Success()) { +      return lldb::ValueObjectSP();      } +    ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset( +        child_byte_offset, child_type, true, +        ConstString(child_name.c_str(), child_name.size()))); + +    return child_sp; +  } + +  // return true if this object is now safe to use forever without +  // ever updating again; the typical (and tested) answer here is +  // 'false' +  bool Update() override { return false; } + +  // maybe return false if the block pointer is, say, null +  bool MightHaveChildren() override { return true; } + +  size_t GetIndexOfChildWithName(const ConstString &name) override { +    if (!m_block_struct_type.IsValid()) +      return UINT32_MAX; + +    const bool omit_empty_base_classes = false; +    return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(), +                                                       omit_empty_base_classes); +  } +  private: -    CompilerType m_block_struct_type; +  CompilerType m_block_struct_type;  };  } // namespace formatters  } // namespace lldb_private -bool -lldb_private::formatters::BlockPointerSummaryProvider(ValueObject &valobj, Stream &s, const TypeSummaryOptions &) -{ -    lldb_private::SyntheticChildrenFrontEnd *synthetic_children = BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP()); -    if (!synthetic_children) -    { -        return false; -    } +bool lldb_private::formatters::BlockPointerSummaryProvider( +    ValueObject &valobj, Stream &s, const TypeSummaryOptions &) { +  lldb_private::SyntheticChildrenFrontEnd *synthetic_children = +      BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP()); +  if (!synthetic_children) { +    return false; +  } -    synthetic_children->Update(); +  synthetic_children->Update(); -    static const ConstString s_FuncPtr_name("__FuncPtr"); -     -    lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex(synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name)); -     -    if (!child_sp) -    { -        return false; -    } -     -    lldb::ValueObjectSP qualified_child_representation_sp = child_sp->GetQualifiedRepresentationIfAvailable(lldb::eDynamicDontRunTarget, true); +  static const ConstString s_FuncPtr_name("__FuncPtr"); + +  lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex( +      synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name)); + +  if (!child_sp) { +    return false; +  } + +  lldb::ValueObjectSP qualified_child_representation_sp = +      child_sp->GetQualifiedRepresentationIfAvailable( +          lldb::eDynamicDontRunTarget, true); -    const char *child_value = qualified_child_representation_sp->GetValueAsCString(); +  const char *child_value = +      qualified_child_representation_sp->GetValueAsCString(); -    s.Printf("%s", child_value); +  s.Printf("%s", child_value); -    return true; +  return true;  }  lldb_private::SyntheticChildrenFrontEnd * -lldb_private::formatters::BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) -{ -    if (!valobj_sp) -        return nullptr; -    return new BlockPointerSyntheticFrontEnd(valobj_sp); +lldb_private::formatters::BlockPointerSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  if (!valobj_sp) +    return nullptr; +  return new BlockPointerSyntheticFrontEnd(valobj_sp);  } diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.h b/source/Plugins/Language/CPlusPlus/BlockPointer.h index 5e6c748b5dbb..e5008a8f3676 100644 --- a/source/Plugins/Language/CPlusPlus/BlockPointer.h +++ b/source/Plugins/Language/CPlusPlus/BlockPointer.h @@ -12,15 +12,14 @@  #include "lldb/lldb-forward.h" -namespace lldb_private -{ -namespace formatters -{ -bool -BlockPointerSummaryProvider(ValueObject &, Stream &, const TypeSummaryOptions &); +namespace lldb_private { +namespace formatters { +bool BlockPointerSummaryProvider(ValueObject &, Stream &, +                                 const TypeSummaryOptions &);  SyntheticChildrenFrontEnd * -BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); +BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                     lldb::ValueObjectSP);  } // namespace formatters  } // namespace lldb_private diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt index de0dc99d85dd..5e105aa19b6b 100644 --- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt +++ b/source/Plugins/Language/CPlusPlus/CMakeLists.txt @@ -10,4 +10,6 @@ add_lldb_library(lldbPluginCPlusPlusLanguage    LibCxxUnorderedMap.cpp    LibCxxVector.cpp    LibStdcpp.cpp +  LibStdcppTuple.cpp +  LibStdcppUniquePointer.cpp  ) diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 33d22bf2e583..b5527edacd13 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -10,17 +10,22 @@  #include "CPlusPlusLanguage.h"  // C Includes -// C++ Includes -#include <cstring>  #include <cctype> +#include <cstring> + +// C++ Includes  #include <functional> +#include <memory>  #include <mutex> +#include <set>  // Other libraries and framework includes  #include "llvm/ADT/StringRef.h"  // Project includes  #include "lldb/Core/ConstString.h" +#include "lldb/Core/FastDemangle.h" +#include "lldb/Core/Log.h"  #include "lldb/Core/PluginManager.h"  #include "lldb/Core/RegularExpression.h"  #include "lldb/Core/UniqueCStringMap.h" @@ -39,818 +44,1122 @@ using namespace lldb;  using namespace lldb_private;  using namespace lldb_private::formatters; -void -CPlusPlusLanguage::Initialize() -{ -    PluginManager::RegisterPlugin (GetPluginNameStatic(), -                                   "C++ Language", -                                   CreateInstance); +void CPlusPlusLanguage::Initialize() { +  PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language", +                                CreateInstance);  } -void -CPlusPlusLanguage::Terminate() -{ -    PluginManager::UnregisterPlugin (CreateInstance); +void CPlusPlusLanguage::Terminate() { +  PluginManager::UnregisterPlugin(CreateInstance);  } -lldb_private::ConstString -CPlusPlusLanguage::GetPluginNameStatic() -{ -    static ConstString g_name("cplusplus"); -    return g_name; +lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() { +  static ConstString g_name("cplusplus"); +  return g_name;  }  //------------------------------------------------------------------  // PluginInterface protocol  //------------------------------------------------------------------ -lldb_private::ConstString -CPlusPlusLanguage::GetPluginName() -{ -    return GetPluginNameStatic(); +lldb_private::ConstString CPlusPlusLanguage::GetPluginName() { +  return GetPluginNameStatic();  } -uint32_t -CPlusPlusLanguage::GetPluginVersion() -{ -    return 1; -} +uint32_t CPlusPlusLanguage::GetPluginVersion() { return 1; }  //------------------------------------------------------------------  // Static Functions  //------------------------------------------------------------------ -Language * -CPlusPlusLanguage::CreateInstance (lldb::LanguageType language) -{ -    if (Language::LanguageIsCPlusPlus(language)) -        return new CPlusPlusLanguage(); -    return nullptr; +Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) { +  if (Language::LanguageIsCPlusPlus(language)) +    return new CPlusPlusLanguage(); +  return nullptr;  } -void -CPlusPlusLanguage::MethodName::Clear() -{ -    m_full.Clear(); -    m_basename = llvm::StringRef(); -    m_context = llvm::StringRef(); -    m_arguments = llvm::StringRef(); -    m_qualifiers = llvm::StringRef(); -    m_type = eTypeInvalid; -    m_parsed = false; -    m_parse_error = false; +void CPlusPlusLanguage::MethodName::Clear() { +  m_full.Clear(); +  m_basename = llvm::StringRef(); +  m_context = llvm::StringRef(); +  m_arguments = llvm::StringRef(); +  m_qualifiers = llvm::StringRef(); +  m_type = eTypeInvalid; +  m_parsed = false; +  m_parse_error = false;  } -bool -ReverseFindMatchingChars (const llvm::StringRef &s, -                          const llvm::StringRef &left_right_chars, -                          size_t &left_pos, -                          size_t &right_pos, -                          size_t pos = llvm::StringRef::npos) -{ -    assert (left_right_chars.size() == 2); -    left_pos = llvm::StringRef::npos; -    const char left_char = left_right_chars[0]; -    const char right_char = left_right_chars[1]; +bool ReverseFindMatchingChars(const llvm::StringRef &s, +                              const llvm::StringRef &left_right_chars, +                              size_t &left_pos, size_t &right_pos, +                              size_t pos = llvm::StringRef::npos) { +  assert(left_right_chars.size() == 2); +  left_pos = llvm::StringRef::npos; +  const char left_char = left_right_chars[0]; +  const char right_char = left_right_chars[1]; +  pos = s.find_last_of(left_right_chars, pos); +  if (pos == llvm::StringRef::npos || s[pos] == left_char) +    return false; +  right_pos = pos; +  uint32_t depth = 1; +  while (pos > 0 && depth > 0) {      pos = s.find_last_of(left_right_chars, pos); -    if (pos == llvm::StringRef::npos || s[pos] == left_char) -        return false; -    right_pos = pos; -    uint32_t depth = 1; -    while (pos > 0 && depth > 0) -    { -        pos = s.find_last_of(left_right_chars, pos); -        if (pos == llvm::StringRef::npos) -            return false; -        if (s[pos] == left_char) -        { -            if (--depth == 0) -            { -                left_pos = pos; -                return left_pos < right_pos; -            }             -        } -        else if (s[pos] == right_char) -        { -            ++depth; -        } +    if (pos == llvm::StringRef::npos) +      return false; +    if (s[pos] == left_char) { +      if (--depth == 0) { +        left_pos = pos; +        return left_pos < right_pos; +      } +    } else if (s[pos] == right_char) { +      ++depth;      } -    return false; +  } +  return false;  } -static bool -IsValidBasename(const llvm::StringRef& basename) -{ -    // Check that the basename matches with the following regular expression or is an operator name: -    // "^~?([A-Za-z_][A-Za-z_0-9]*)(<.*>)?$" -    // We are using a hand written implementation because it is significantly more efficient then -    // using the general purpose regular expression library. -    size_t idx = 0; -    if (basename.size() > 0 && basename[0] == '~') -        idx = 1; +static bool IsValidBasename(const llvm::StringRef &basename) { +  // Check that the basename matches with the following regular expression or is +  // an operator name: +  // "^~?([A-Za-z_][A-Za-z_0-9]*)(<.*>)?$" +  // We are using a hand written implementation because it is significantly more +  // efficient then +  // using the general purpose regular expression library. +  size_t idx = 0; +  if (basename.size() > 0 && basename[0] == '~') +    idx = 1; -    if (basename.size() <= idx) -        return false; // Empty string or "~" +  if (basename.size() <= idx) +    return false; // Empty string or "~" -    if (!std::isalpha(basename[idx]) && basename[idx] != '_') -        return false; // First charater (after removing the possible '~'') isn't in [A-Za-z_] +  if (!std::isalpha(basename[idx]) && basename[idx] != '_') +    return false; // First charater (after removing the possible '~'') isn't in +                  // [A-Za-z_] -    // Read all characters matching [A-Za-z_0-9] +  // Read all characters matching [A-Za-z_0-9] +  ++idx; +  while (idx < basename.size()) { +    if (!std::isalnum(basename[idx]) && basename[idx] != '_') +      break;      ++idx; -    while (idx < basename.size()) -    { -        if (!std::isalnum(basename[idx]) && basename[idx] != '_') -            break; -        ++idx; -    } +  } -    // We processed all characters. It is a vaild basename. -    if (idx == basename.size()) -        return true; +  // We processed all characters. It is a vaild basename. +  if (idx == basename.size()) +    return true; -    // Check for basename with template arguments -    // TODO: Improve the quality of the validation with validating the template arguments -    if (basename[idx] == '<' && basename.back() == '>') -        return true; +  // Check for basename with template arguments +  // TODO: Improve the quality of the validation with validating the template +  // arguments +  if (basename[idx] == '<' && basename.back() == '>') +    return true; -    // Check if the basename is a vaild C++ operator name -    if (!basename.startswith("operator")) -        return false; +  // Check if the basename is a vaild C++ operator name +  if (!basename.startswith("operator")) +    return false; -    static RegularExpression g_operator_regex("^(operator)( ?)([A-Za-z_][A-Za-z_0-9]*|\\(\\)|\\[\\]|[\\^<>=!\\/*+-]+)(<.*>)?(\\[\\])?$"); -    std::string basename_str(basename.str()); -    return g_operator_regex.Execute(basename_str.c_str(), nullptr); +  static RegularExpression g_operator_regex( +      llvm::StringRef("^(operator)( " +                      "?)([A-Za-z_][A-Za-z_0-9]*|\\(\\)|" +                      "\\[\\]|[\\^<>=!\\/" +                      "*+-]+)(<.*>)?(\\[\\])?$")); +  std::string basename_str(basename.str()); +  return g_operator_regex.Execute(basename_str, nullptr);  } -void -CPlusPlusLanguage::MethodName::Parse() -{ -    if (!m_parsed && m_full) -    { -//        ConstString mangled; -//        m_full.GetMangledCounterpart(mangled); -//        printf ("\n   parsing = '%s'\n", m_full.GetCString()); -//        if (mangled) -//            printf ("   mangled = '%s'\n", mangled.GetCString()); -        m_parse_error = false; -        m_parsed = true; -        llvm::StringRef full (m_full.GetCString()); -         -        size_t arg_start, arg_end; -        llvm::StringRef parens("()", 2); -        if (ReverseFindMatchingChars (full, parens, arg_start, arg_end)) -        { -            m_arguments = full.substr(arg_start, arg_end - arg_start + 1); -            if (arg_end + 1 < full.size()) -                m_qualifiers = full.substr(arg_end + 1); -            if (arg_start > 0) -            { -                size_t basename_end = arg_start; -                size_t context_start = 0; -                size_t context_end = llvm::StringRef::npos; -                if (basename_end > 0 && full[basename_end-1] == '>') -                { -                    // TODO: handle template junk... -                    // Templated function -                    size_t template_start, template_end; -                    llvm::StringRef lt_gt("<>", 2); -                    if (ReverseFindMatchingChars (full, lt_gt, template_start, template_end, basename_end)) -                    { -                        // Check for templated functions that include return type like: 'void foo<Int>()' -                        context_start = full.rfind(' ', template_start); -                        if (context_start == llvm::StringRef::npos) -                            context_start = 0; - -                        context_end = full.rfind(':', template_start); -                        if (context_end == llvm::StringRef::npos || context_end < context_start) -                            context_end = context_start; -                    } -                    else -                    { -                        context_end = full.rfind(':', basename_end); -                    } -                } -                else if (context_end == llvm::StringRef::npos) -                { -                    context_end = full.rfind(':', basename_end); -                } - -                if (context_end == llvm::StringRef::npos) -                    m_basename = full.substr(0, basename_end); -                else -                { -                    if (context_start < context_end) -                        m_context = full.substr(context_start, context_end - 1); -                    const size_t basename_begin = context_end + 1; -                    m_basename = full.substr(basename_begin, basename_end - basename_begin); -                } -                m_type = eTypeUnknownMethod; -            } +void CPlusPlusLanguage::MethodName::Parse() { +  if (!m_parsed && m_full) { +    //        ConstString mangled; +    //        m_full.GetMangledCounterpart(mangled); +    //        printf ("\n   parsing = '%s'\n", m_full.GetCString()); +    //        if (mangled) +    //            printf ("   mangled = '%s'\n", mangled.GetCString()); +    m_parse_error = false; +    m_parsed = true; +    llvm::StringRef full(m_full.GetCString()); + +    size_t arg_start, arg_end; +    llvm::StringRef parens("()", 2); +    if (ReverseFindMatchingChars(full, parens, arg_start, arg_end)) { +      m_arguments = full.substr(arg_start, arg_end - arg_start + 1); +      if (arg_end + 1 < full.size()) +        m_qualifiers = full.substr(arg_end + 1); +      if (arg_start > 0) { +        size_t basename_end = arg_start; +        size_t context_start = 0; +        size_t context_end = llvm::StringRef::npos; +        if (basename_end > 0 && full[basename_end - 1] == '>') { +          // TODO: handle template junk... +          // Templated function +          size_t template_start, template_end; +          llvm::StringRef lt_gt("<>", 2); +          if (ReverseFindMatchingChars(full, lt_gt, template_start, +                                       template_end, basename_end)) { +            // Check for templated functions that include return type like: +            // 'void foo<Int>()' +            context_start = full.rfind(' ', template_start); +            if (context_start == llvm::StringRef::npos) +              context_start = 0;              else -            { -                m_parse_error = true; -                return; -            } - -            if (!IsValidBasename(m_basename)) -            { -                // The C++ basename doesn't match our regular expressions so this can't -                // be a valid C++ method, clear everything out and indicate an error -                m_context = llvm::StringRef(); -                m_basename = llvm::StringRef(); -                m_arguments = llvm::StringRef(); -                m_qualifiers = llvm::StringRef(); -                m_parse_error = true; -            } +              ++context_start; + +            context_end = full.rfind(':', template_start); +            if (context_end == llvm::StringRef::npos || +                context_end < context_start) +              context_end = context_start; +          } else { +            context_end = full.rfind(':', basename_end); +          } +        } else if (context_end == llvm::StringRef::npos) { +          context_end = full.rfind(':', basename_end);          } -        else -        { -            m_parse_error = true; + +        if (context_end == llvm::StringRef::npos) +          m_basename = full.substr(0, basename_end); +        else { +          if (context_start < context_end) +            m_context = +                full.substr(context_start, context_end - 1 - context_start); +          const size_t basename_begin = context_end + 1; +          m_basename = +              full.substr(basename_begin, basename_end - basename_begin);          } +        m_type = eTypeUnknownMethod; +      } else { +        m_parse_error = true; +        return; +      } + +      if (!IsValidBasename(m_basename)) { +        // The C++ basename doesn't match our regular expressions so this can't +        // be a valid C++ method, clear everything out and indicate an error +        m_context = llvm::StringRef(); +        m_basename = llvm::StringRef(); +        m_arguments = llvm::StringRef(); +        m_qualifiers = llvm::StringRef(); +        m_parse_error = true; +      } +    } else { +      m_parse_error = true;      } +  }  } -llvm::StringRef -CPlusPlusLanguage::MethodName::GetBasename () -{ -    if (!m_parsed) -        Parse(); -    return m_basename; +llvm::StringRef CPlusPlusLanguage::MethodName::GetBasename() { +  if (!m_parsed) +    Parse(); +  return m_basename;  } -llvm::StringRef -CPlusPlusLanguage::MethodName::GetContext () -{ -    if (!m_parsed) -        Parse(); -    return m_context; +llvm::StringRef CPlusPlusLanguage::MethodName::GetContext() { +  if (!m_parsed) +    Parse(); +  return m_context;  } -llvm::StringRef -CPlusPlusLanguage::MethodName::GetArguments () -{ -    if (!m_parsed) -        Parse(); -    return m_arguments; +llvm::StringRef CPlusPlusLanguage::MethodName::GetArguments() { +  if (!m_parsed) +    Parse(); +  return m_arguments;  } -llvm::StringRef -CPlusPlusLanguage::MethodName::GetQualifiers () -{ -    if (!m_parsed) -        Parse(); -    return m_qualifiers; +llvm::StringRef CPlusPlusLanguage::MethodName::GetQualifiers() { +  if (!m_parsed) +    Parse(); +  return m_qualifiers;  } -std::string -CPlusPlusLanguage::MethodName::GetScopeQualifiedName () -{ -    if (!m_parsed) -        Parse(); -    if (m_basename.empty() || m_context.empty()) -        return std::string(); +std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() { +  if (!m_parsed) +    Parse(); +  if (m_basename.empty() || m_context.empty()) +    return std::string(); -    std::string res; -    res += m_context; -    res += "::"; -    res += m_basename; +  std::string res; +  res += m_context; +  res += "::"; +  res += m_basename; -    return res; +  return res;  } -bool -CPlusPlusLanguage::IsCPPMangledName (const char *name) -{ -    // FIXME, we should really run through all the known C++ Language plugins and ask each one if -    // this is a C++ mangled name, but we can put that off till there is actually more than one -    // we care about. -     -    return (name != nullptr && name[0] == '_' && name[1] == 'Z'); +bool CPlusPlusLanguage::IsCPPMangledName(const char *name) { +  // FIXME, we should really run through all the known C++ Language plugins and +  // ask each one if +  // this is a C++ mangled name, but we can put that off till there is actually +  // more than one +  // we care about. + +  return (name != nullptr && name[0] == '_' && name[1] == 'Z');  } -bool -CPlusPlusLanguage::ExtractContextAndIdentifier (const char *name, llvm::StringRef &context, llvm::StringRef &identifier) -{ -    static RegularExpression g_basename_regex("^(([A-Za-z_][A-Za-z_0-9]*::)*)(~?[A-Za-z_~][A-Za-z_0-9]*)$"); -    RegularExpression::Match match(4); -    if (g_basename_regex.Execute (name, &match)) -    { -        match.GetMatchAtIndex(name, 1, context); -        match.GetMatchAtIndex(name, 3, identifier); -        return true; -    } -    return false; +bool CPlusPlusLanguage::ExtractContextAndIdentifier( +    const char *name, llvm::StringRef &context, llvm::StringRef &identifier) { +  static RegularExpression g_basename_regex(llvm::StringRef( +      "^(([A-Za-z_][A-Za-z_0-9]*::)*)(~?[A-Za-z_~][A-Za-z_0-9]*)$")); +  RegularExpression::Match match(4); +  if (g_basename_regex.Execute(llvm::StringRef::withNullAsEmpty(name), +                               &match)) { +    match.GetMatchAtIndex(name, 1, context); +    match.GetMatchAtIndex(name, 3, identifier); +    return true; +  } +  return false;  } -class CPPRuntimeEquivalents -{ +class CPPRuntimeEquivalents {  public: -    CPPRuntimeEquivalents () -    { -        m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >").AsCString(), ConstString("basic_string<char>")); - -        // these two (with a prefixed std::) occur when c++stdlib string class occurs as a template argument in some STL container -        m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >").AsCString(), ConstString("std::basic_string<char>")); -         -        m_impl.Sort(); -    } -     -    void -    Add (ConstString& type_name, -         ConstString& type_equivalent) -    { -        m_impl.Insert(type_name.AsCString(), type_equivalent); -    } -     -    uint32_t -    FindExactMatches (ConstString& type_name, -                      std::vector<ConstString>& equivalents) -    { -        uint32_t count = 0; - -        for (ImplData match = m_impl.FindFirstValueForName(type_name.AsCString()); -             match != nullptr; -             match = m_impl.FindNextValueForName(match)) -        { -            equivalents.push_back(match->value); -            count++; -        } +  CPPRuntimeEquivalents() { +    m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, " +                              "std::allocator<char> >") +                      .GetStringRef(), +                  ConstString("basic_string<char>")); + +    // these two (with a prefixed std::) occur when c++stdlib string class +    // occurs as a template argument in some STL container +    m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, " +                              "std::allocator<char> >") +                      .GetStringRef(), +                  ConstString("std::basic_string<char>")); + +    m_impl.Sort(); +  } + +  void Add(ConstString &type_name, ConstString &type_equivalent) { +    m_impl.Insert(type_name.GetStringRef(), type_equivalent); +  } -        return count;         +  uint32_t FindExactMatches(ConstString &type_name, +                            std::vector<ConstString> &equivalents) { +    uint32_t count = 0; + +    for (ImplData match = +             m_impl.FindFirstValueForName(type_name.GetStringRef()); +         match != nullptr; match = m_impl.FindNextValueForName(match)) { +      equivalents.push_back(match->value); +      count++;      } -     -    // partial matches can occur when a name with equivalents is a template argument. -    // e.g. we may have "class Foo" be a match for "struct Bar". if we have a typename -    // such as "class Templatized<class Foo, Anything>" we want this to be replaced with -    // "class Templatized<struct Bar, Anything>". Since partial matching is time consuming -    // once we get a partial match, we add it to the exact matches list for faster retrieval -    uint32_t -    FindPartialMatches (ConstString& type_name, -                        std::vector<ConstString>& equivalents) -    { -        uint32_t count = 0; -         -        const char* type_name_cstr = type_name.AsCString(); -         -        size_t items_count = m_impl.GetSize(); -         -        for (size_t item = 0; item < items_count; item++) -        { -            const char* key_cstr = m_impl.GetCStringAtIndex(item); -            if ( strstr(type_name_cstr,key_cstr) ) -            { -                count += AppendReplacements(type_name_cstr, -                                            key_cstr, -                                            equivalents); -            } -        } -         -        return count; + +    return count; +  } + +  // partial matches can occur when a name with equivalents is a template +  // argument. +  // e.g. we may have "class Foo" be a match for "struct Bar". if we have a +  // typename +  // such as "class Templatized<class Foo, Anything>" we want this to be +  // replaced with +  // "class Templatized<struct Bar, Anything>". Since partial matching is time +  // consuming +  // once we get a partial match, we add it to the exact matches list for faster +  // retrieval +  uint32_t FindPartialMatches(ConstString &type_name, +                              std::vector<ConstString> &equivalents) { +    uint32_t count = 0; + +    llvm::StringRef type_name_cstr = type_name.GetStringRef(); + +    size_t items_count = m_impl.GetSize(); + +    for (size_t item = 0; item < items_count; item++) { +      llvm::StringRef key_cstr = m_impl.GetCStringAtIndex(item); +      if (type_name_cstr.contains(key_cstr)) { +        count += AppendReplacements(type_name_cstr, key_cstr, equivalents); +      }      } -     + +    return count; +  } +  private: -    std::string& replace (std::string& target, -                          std::string& pattern, -                          std::string& with) -    { -        size_t pos; -        size_t pattern_len = pattern.size(); -         -        while ( (pos = target.find(pattern)) != std::string::npos ) -            target.replace(pos, pattern_len, with); -         -        return target; -    } -     -    uint32_t -    AppendReplacements (const char* original, -                        const char *matching_key, -                        std::vector<ConstString>& equivalents) -    { -        std::string matching_key_str(matching_key); -        ConstString original_const(original); -         -        uint32_t count = 0; -         -        for (ImplData match = m_impl.FindFirstValueForName(matching_key); -             match != nullptr; -             match = m_impl.FindNextValueForName(match)) -        { -            std::string target(original); -            std::string equiv_class(match->value.AsCString()); -             -            replace (target, matching_key_str, equiv_class); -             -            ConstString target_const(target.c_str()); - -// you will most probably want to leave this off since it might make this map grow indefinitely +  std::string &replace(std::string &target, std::string &pattern, +                       std::string &with) { +    size_t pos; +    size_t pattern_len = pattern.size(); + +    while ((pos = target.find(pattern)) != std::string::npos) +      target.replace(pos, pattern_len, with); + +    return target; +  } + +  uint32_t AppendReplacements(llvm::StringRef original, +                              llvm::StringRef matching_key, +                              std::vector<ConstString> &equivalents) { +    std::string matching_key_str(matching_key); +    ConstString original_const(original); + +    uint32_t count = 0; + +    for (ImplData match = m_impl.FindFirstValueForName(matching_key); +         match != nullptr; match = m_impl.FindNextValueForName(match)) { +      std::string target(original); +      std::string equiv_class(match->value.AsCString()); + +      replace(target, matching_key_str, equiv_class); + +      ConstString target_const(target.c_str()); + +// you will most probably want to leave this off since it might make this map +// grow indefinitely  #ifdef ENABLE_CPP_EQUIVALENTS_MAP_TO_GROW -            Add(original_const, target_const); +      Add(original_const, target_const);  #endif -            equivalents.push_back(target_const); -             -            count++; -        } -         -        return count; +      equivalents.push_back(target_const); + +      count++;      } -     -    typedef UniqueCStringMap<ConstString> Impl; -    typedef const Impl::Entry* ImplData; -    Impl m_impl; + +    return count; +  } + +  typedef UniqueCStringMap<ConstString> Impl; +  typedef const Impl::Entry *ImplData; +  Impl m_impl;  }; -static CPPRuntimeEquivalents& -GetEquivalentsMap () -{ -    static CPPRuntimeEquivalents g_equivalents_map; -    return g_equivalents_map; +static CPPRuntimeEquivalents &GetEquivalentsMap() { +  static CPPRuntimeEquivalents g_equivalents_map; +  return g_equivalents_map;  }  uint32_t -CPlusPlusLanguage::FindEquivalentNames(ConstString type_name, std::vector<ConstString>& equivalents) -{ -    uint32_t count = GetEquivalentsMap().FindExactMatches(type_name, equivalents); - -    bool might_have_partials=  -        ( count == 0 )  // if we have a full name match just use it -        && (strchr(type_name.AsCString(), '<') != nullptr  // we should only have partial matches when templates are involved, check that we have -            && strchr(type_name.AsCString(), '>') != nullptr); // angle brackets in the type_name before trying to scan for partial matches -     -    if ( might_have_partials ) -        count = GetEquivalentsMap().FindPartialMatches(type_name, equivalents); -     -    return count; +CPlusPlusLanguage::FindEquivalentNames(ConstString type_name, +                                       std::vector<ConstString> &equivalents) { +  uint32_t count = GetEquivalentsMap().FindExactMatches(type_name, equivalents); + +  bool might_have_partials = +      (count == 0) // if we have a full name match just use it +      && (strchr(type_name.AsCString(), '<') != +              nullptr // we should only have partial matches when templates are +                      // involved, check that we have +          && strchr(type_name.AsCString(), '>') != nullptr); // angle brackets +                                                             // in the type_name +                                                             // before trying to +                                                             // scan for partial +                                                             // matches + +  if (might_have_partials) +    count = GetEquivalentsMap().FindPartialMatches(type_name, equivalents); + +  return count;  } -static void -LoadLibCxxFormatters (lldb::TypeCategoryImplSP cpp_category_sp) -{ -    if (!cpp_category_sp) -        return; -     -    TypeSummaryImpl::Flags stl_summary_flags; -    stl_summary_flags.SetCascades(true) -    .SetSkipPointers(false) -    .SetSkipReferences(false) -    .SetDontShowChildren(true) -    .SetDontShowValue(true) -    .SetShowMembersOneLiner(false) -    .SetHideItemNames(false); -     +/// Given a mangled function `mangled`, replace all the primitive function type +/// arguments of `search` with type `replace`. +static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled, +                                            llvm::StringRef search, +                                            llvm::StringRef replace) { +  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + +  const size_t max_len = +      mangled.size() + mangled.count(search) * replace.size() + 1; + +  // Make a temporary buffer to fix up the mangled parameter types and copy the +  // original there +  std::string output_buf; +  output_buf.reserve(max_len); +  output_buf.insert(0, mangled.str()); +  ptrdiff_t replaced_offset = 0; + +  auto swap_parms_hook = [&](const char *parsee) { +    if (!parsee || !*parsee) +      return; + +    // Check whether we've found a substitutee +    llvm::StringRef s(parsee); +    if (s.startswith(search)) { +      // account for the case where a replacement is of a different length to +      // the original +      replaced_offset += replace.size() - search.size(); + +      ptrdiff_t replace_idx = (mangled.size() - s.size()) + replaced_offset; +      output_buf.erase(replace_idx, search.size()); +      output_buf.insert(replace_idx, replace.str()); +    } +  }; + +  // FastDemangle will call our hook for each instance of a primitive type, +  // allowing us to perform substitution +  const char *const demangled = +      FastDemangle(mangled.str().c_str(), mangled.size(), swap_parms_hook); + +  if (log) +    log->Printf("substituted mangling for %s:{%s} %s:{%s}\n", +                mangled.str().c_str(), demangled, output_buf.c_str(), +                FastDemangle(output_buf.c_str())); + +  return output_buf == mangled ? ConstString() : ConstString(output_buf); +} + +uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( +    const ConstString mangled_name, std::set<ConstString> &alternates) { +  const auto start_size = alternates.size(); +  /// Get a basic set of alternative manglings for the given symbol `name`, by +  /// making a few basic possible substitutions on basic types, storage duration +  /// and `const`ness for the given symbol. The output parameter `alternates` +  /// is filled with a best-guess, non-exhaustive set of different manglings +  /// for the given name. + +  // Maybe we're looking for a const symbol but the debug info told us it was +  // non-const... +  if (!strncmp(mangled_name.GetCString(), "_ZN", 3) && +      strncmp(mangled_name.GetCString(), "_ZNK", 4)) { +    std::string fixed_scratch("_ZNK"); +    fixed_scratch.append(mangled_name.GetCString() + 3); +    alternates.insert(ConstString(fixed_scratch)); +  } + +  // Maybe we're looking for a static symbol but we thought it was global... +  if (!strncmp(mangled_name.GetCString(), "_Z", 2) && +      strncmp(mangled_name.GetCString(), "_ZL", 3)) { +    std::string fixed_scratch("_ZL"); +    fixed_scratch.append(mangled_name.GetCString() + 2); +    alternates.insert(ConstString(fixed_scratch)); +  } + +  // `char` is implementation defined as either `signed` or `unsigned`.  As a +  // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed +  // char, 'h'-unsigned char.  If we're looking for symbols with a signed char +  // parameter, try finding matches which have the general case 'c'. +  if (ConstString char_fixup = +          SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "a", "c")) +    alternates.insert(char_fixup); + +  // long long parameter mangling 'x', may actually just be a long 'l' argument +  if (ConstString long_fixup = +          SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "x", "l")) +    alternates.insert(long_fixup); + +  // unsigned long long parameter mangling 'y', may actually just be unsigned +  // long 'm' argument +  if (ConstString ulong_fixup = +          SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "y", "m")) +    alternates.insert(ulong_fixup); + +  return alternates.size() - start_size; +} + +static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { +  if (!cpp_category_sp) +    return; + +  TypeSummaryImpl::Flags stl_summary_flags; +  stl_summary_flags.SetCascades(true) +      .SetSkipPointers(false) +      .SetSkipReferences(false) +      .SetDontShowChildren(true) +      .SetDontShowValue(true) +      .SetShowMembersOneLiner(false) +      .SetHideItemNames(false); +  #ifndef LLDB_DISABLE_PYTHON -    lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxStringSummaryProvider, "std::string summary provider")); -    lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider, "std::wstring summary provider")); -     -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::string"), -                                                         std_string_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::string"), -                                                         std_string_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >"), -                                                         std_string_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >"), -                                                         std_string_summary_sp); -     -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::wstring"), -                                                         std_wstring_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::wstring"), -                                                         std_wstring_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >"), -                                                         std_wstring_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::basic_string<wchar_t, std::__ndk1::char_traits<wchar_t>, std::__ndk1::allocator<wchar_t> >"), -                                                         std_wstring_summary_sp); -     -    SyntheticChildren::Flags stl_synth_flags; -    stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false); -     -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("^std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >$"), stl_synth_flags, true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator, "libc++ std::vector synthetic children", ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags, true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, "libc++ std::list synthetic children", ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_synth_flags, true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::map synthetic children", ConstString("^std::__(ndk)?1::map<.+> >(( )?&)?$"), stl_synth_flags, true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__(ndk)?1::vector<std::__(ndk)?1::allocator<bool> >"), stl_synth_flags); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_synth_flags); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::set synthetic children", ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_synth_flags, true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multiset synthetic children", ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_synth_flags, true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multimap synthetic children", ConstString("^std::__(ndk)?1::multimap<.+> >(( )?&)?$"), stl_synth_flags, true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator, "libc++ std::unordered containers synthetic children", ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"), stl_synth_flags, true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator, "libc++ std::initializer_list synthetic children", ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags, true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, "libc++ std::atomic synthetic children", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_synth_flags, true); - -    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^(std::__(ndk)?1::)deque<.+>(( )?&)?$")), -                                                               SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags, -                                                                                                                 "lldb.formatters.cpp.libcxx.stddeque_SynthProvider"))); -     -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "shared_ptr synthetic children", ConstString("^(std::__(ndk)?1::)shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "weak_ptr synthetic children", ConstString("^(std::__(ndk)?1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true); -     -    stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(false); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector summary provider", ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::list summary provider", ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::map summary provider", ConstString("^std::__(ndk)?1::map<.+>(( )?&)?$"), stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::deque summary provider", ConstString("^std::__(ndk)?1::deque<.+>(( )?&)?$"), stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::set summary provider", ConstString("^std::__(ndk)?1::set<.+>(( )?&)?$"), stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multiset summary provider", ConstString("^std::__(ndk)?1::multiset<.+>(( )?&)?$"), stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multimap summary provider", ConstString("^std::__(ndk)?1::multimap<.+>(( )?&)?$"), stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::unordered containers summary provider", ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"), stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider, "libc++ std::atomic summary provider", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true); -     -    stl_summary_flags.SetSkipPointers(true); -     -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::shared_ptr summary provider", ConstString("^std::__(ndk)?1::shared_ptr<.+>(( )?&)?$"), stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::weak_ptr summary provider", ConstString("^std::__(ndk)?1::weak_ptr<.+>(( )?&)?$"), stl_summary_flags, true); -     -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^std::__(ndk)?1::__wrap_iter<.+>$"), stl_synth_flags, true); -     -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_summary_flags); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::__(ndk)?1::__map_iterator<.+>$"), stl_synth_flags, true); +  lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat( +      stl_summary_flags, lldb_private::formatters::LibcxxStringSummaryProvider, +      "std::string summary provider")); +  lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat( +      stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider, +      "std::wstring summary provider")); + +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__1::string"), std_string_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__ndk1::string"), std_string_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, " +                  "std::__1::allocator<char> >"), +      std_string_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__ndk1::basic_string<char, " +                  "std::__ndk1::char_traits<char>, " +                  "std::__ndk1::allocator<char> >"), +      std_string_summary_sp); + +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__1::wstring"), std_wstring_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__ndk1::wstring"), std_wstring_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__1::basic_string<wchar_t, " +                  "std::__1::char_traits<wchar_t>, " +                  "std::__1::allocator<wchar_t> >"), +      std_wstring_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__ndk1::basic_string<wchar_t, " +                  "std::__ndk1::char_traits<wchar_t>, " +                  "std::__ndk1::allocator<wchar_t> >"), +      std_wstring_summary_sp); + +  SyntheticChildren::Flags stl_synth_flags; +  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences( +      false); + +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, +      "libc++ std::vector<bool> synthetic children", +      ConstString( +          "^std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >$"), +      stl_synth_flags, true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator, +      "libc++ std::vector synthetic children", +      ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags, +      true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, +      "libc++ std::list synthetic children", +      ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_synth_flags, true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, +      "libc++ std::map synthetic children", +      ConstString("^std::__(ndk)?1::map<.+> >(( )?&)?$"), stl_synth_flags, +      true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, +      "libc++ std::vector<bool> synthetic children", +      ConstString("std::__(ndk)?1::vector<std::__(ndk)?1::allocator<bool> >"), +      stl_synth_flags); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, +      "libc++ std::vector<bool> synthetic children", +      ConstString( +          "std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), +      stl_synth_flags); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, +      "libc++ std::set synthetic children", +      ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_synth_flags, +      true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, +      "libc++ std::multiset synthetic children", +      ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_synth_flags, +      true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, +      "libc++ std::multimap synthetic children", +      ConstString("^std::__(ndk)?1::multimap<.+> >(( )?&)?$"), stl_synth_flags, +      true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator, +      "libc++ std::unordered containers synthetic children", +      ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"), +      stl_synth_flags, true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator, +      "libc++ std::initializer_list synthetic children", +      ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags, +      true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, +      "libc++ std::atomic synthetic children", +      ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_synth_flags, true); + +  cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( +      RegularExpressionSP(new RegularExpression( +          llvm::StringRef("^(std::__(ndk)?1::)deque<.+>(( )?&)?$"))), +      SyntheticChildrenSP(new ScriptedSyntheticChildren( +          stl_synth_flags, +          "lldb.formatters.cpp.libcxx.stddeque_SynthProvider"))); + +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, +      "shared_ptr synthetic children", +      ConstString("^(std::__(ndk)?1::)shared_ptr<.+>(( )?&)?$"), +      stl_synth_flags, true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, +      "weak_ptr synthetic children", +      ConstString("^(std::__(ndk)?1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, +      true); + +  stl_summary_flags.SetDontShowChildren(false); +  stl_summary_flags.SetSkipPointers(false); +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, +      "libc++ std::vector<bool> summary provider", +      ConstString( +          "std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), +      stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxContainerSummaryProvider, +                "libc++ std::vector summary provider", +                ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxContainerSummaryProvider, +                "libc++ std::list summary provider", +                ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxContainerSummaryProvider, +                "libc++ std::map summary provider", +                ConstString("^std::__(ndk)?1::map<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxContainerSummaryProvider, +                "libc++ std::deque summary provider", +                ConstString("^std::__(ndk)?1::deque<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxContainerSummaryProvider, +                "libc++ std::set summary provider", +                ConstString("^std::__(ndk)?1::set<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxContainerSummaryProvider, +                "libc++ std::multiset summary provider", +                ConstString("^std::__(ndk)?1::multiset<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxContainerSummaryProvider, +                "libc++ std::multimap summary provider", +                ConstString("^std::__(ndk)?1::multimap<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, +      "libc++ std::unordered containers summary provider", +      ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"), +      stl_summary_flags, true); +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider, +      "libc++ std::atomic summary provider", +      ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true); + +  stl_summary_flags.SetSkipPointers(true); + +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxSmartPointerSummaryProvider, +                "libc++ std::shared_ptr summary provider", +                ConstString("^std::__(ndk)?1::shared_ptr<.+>(( )?&)?$"), +                stl_summary_flags, true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibcxxSmartPointerSummaryProvider, +                "libc++ std::weak_ptr summary provider", +                ConstString("^std::__(ndk)?1::weak_ptr<.+>(( )?&)?$"), +                stl_summary_flags, true); + +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator, +      "std::vector iterator synthetic children", +      ConstString("^std::__(ndk)?1::__wrap_iter<.+>$"), stl_synth_flags, true); + +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, +      "libc++ std::vector<bool> summary provider", +      ConstString( +          "std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), +      stl_summary_flags); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator, +      "std::map iterator synthetic children", +      ConstString("^std::__(ndk)?1::__map_iterator<.+>$"), stl_synth_flags, +      true); + +  AddCXXSynthetic( +      cpp_category_sp, lldb_private::formatters::LibcxxFunctionFrontEndCreator, +      "std::function synthetic value provider", +      ConstString("^std::__1::function<.+>$"), stl_synth_flags, true);  #endif  } -static void -LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) -{ -    if (!cpp_category_sp) -        return; -     -    TypeSummaryImpl::Flags stl_summary_flags; -    stl_summary_flags.SetCascades(true) -    .SetSkipPointers(false) -    .SetSkipReferences(false) -    .SetDontShowChildren(true) -    .SetDontShowValue(true) -    .SetShowMembersOneLiner(false) -    .SetHideItemNames(false); -     -    lldb::TypeSummaryImplSP std_string_summary_sp(new StringSummaryFormat(stl_summary_flags, -                                                                          "${var._M_dataplus._M_p}")); - -    lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, -                                                                                 LibStdcppStringSummaryProvider, -                                                                                 "libstdc++ c++11 std::string summary provider")); -    lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, -                                                                                 LibStdcppWStringSummaryProvider, -                                                                                 "libstdc++ c++11 std::wstring summary provider")); - -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"), -                                                      std_string_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char>"), -                                                      std_string_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char,std::char_traits<char>,std::allocator<char> >"), -                                                      std_string_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"), -                                                      std_string_summary_sp); - -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::string"), -                                                      cxx11_string_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >"), -                                                      cxx11_string_summary_sp); - -    // making sure we force-pick the summary for printing wstring (_M_p is a wchar_t*) -    lldb::TypeSummaryImplSP std_wstring_summary_sp(new StringSummaryFormat(stl_summary_flags, -                                                                           "${var._M_dataplus._M_p%S}")); -     -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::wstring"), -                                                      std_wstring_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t>"), -                                                      std_wstring_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >"), -                                                      std_wstring_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >"), -                                                      std_wstring_summary_sp); - -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::wstring"), -                                                      cxx11_wstring_summary_sp); -    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >"), -                                                      cxx11_wstring_summary_sp); +static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { +  if (!cpp_category_sp) +    return; + +  TypeSummaryImpl::Flags stl_summary_flags; +  stl_summary_flags.SetCascades(true) +      .SetSkipPointers(false) +      .SetSkipReferences(false) +      .SetDontShowChildren(true) +      .SetDontShowValue(true) +      .SetShowMembersOneLiner(false) +      .SetHideItemNames(false); + +  lldb::TypeSummaryImplSP std_string_summary_sp( +      new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p}")); + +  lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat( +      stl_summary_flags, LibStdcppStringSummaryProvider, +      "libstdc++ c++11 std::string summary provider")); +  lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat( +      stl_summary_flags, LibStdcppWStringSummaryProvider, +      "libstdc++ c++11 std::wstring summary provider")); + +  cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"), +                                                    std_string_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::basic_string<char>"), std_string_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::basic_string<char,std::char_traits<char>,std::" +                  "allocator<char> >"), +      std_string_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::basic_string<char, std::char_traits<char>, " +                  "std::allocator<char> >"), +      std_string_summary_sp); + +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__cxx11::string"), cxx11_string_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__cxx11::basic_string<char, std::char_traits<char>, " +                  "std::allocator<char> >"), +      cxx11_string_summary_sp); + +  // making sure we force-pick the summary for printing wstring (_M_p is a +  // wchar_t*) +  lldb::TypeSummaryImplSP std_wstring_summary_sp( +      new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p%S}")); + +  cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::wstring"), +                                                    std_wstring_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::basic_string<wchar_t>"), std_wstring_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::basic_string<wchar_t,std::char_traits<wchar_t>,std::" +                  "allocator<wchar_t> >"), +      std_wstring_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, " +                  "std::allocator<wchar_t> >"), +      std_wstring_summary_sp); + +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__cxx11::wstring"), cxx11_wstring_summary_sp); +  cpp_category_sp->GetTypeSummariesContainer()->Add( +      ConstString("std::__cxx11::basic_string<wchar_t, " +                  "std::char_traits<wchar_t>, std::allocator<wchar_t> >"), +      cxx11_wstring_summary_sp);  #ifndef LLDB_DISABLE_PYTHON -     -    SyntheticChildren::Flags stl_synth_flags; -    stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false); -     -    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")), -                                                            SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags, -                                                                                                              "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider"))); -    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")), -                                                            SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags, -                                                                                                              "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider"))); -    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$")), -                                                            SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags, -                                                                                                              "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider"))); -    stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(true); -    cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")), -                                                           TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, -                                                                                                     "size=${svar%#}"))); -    cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")), -                                                           TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, -                                                                                                     "size=${svar%#}"))); -    cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$")), -                                                           TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, -                                                                                                     "size=${svar%#}"))); - -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true); - -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true); - -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator, -                    "std::shared_ptr synthetic children", ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, -                    true); -    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator, -                    "std::weak_ptr synthetic children", ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags, -                    true); - -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider, -                  "libstdc++ std::shared_ptr summary provider", ConstString("^std::shared_ptr<.+>(( )?&)?$"), -                  stl_summary_flags, true); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider, -                  "libstdc++ std::weak_ptr summary provider", ConstString("^std::weak_ptr<.+>(( )?&)?$"), -                  stl_summary_flags, true); + +  SyntheticChildren::Flags stl_synth_flags; +  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences( +      false); + +  cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( +      RegularExpressionSP( +          new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))), +      SyntheticChildrenSP(new ScriptedSyntheticChildren( +          stl_synth_flags, +          "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider"))); +  cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( +      RegularExpressionSP( +          new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))), +      SyntheticChildrenSP(new ScriptedSyntheticChildren( +          stl_synth_flags, +          "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider"))); +  cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( +      RegularExpressionSP(new RegularExpression( +          llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))), +      SyntheticChildrenSP(new ScriptedSyntheticChildren( +          stl_synth_flags, +          "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider"))); +  stl_summary_flags.SetDontShowChildren(false); +  stl_summary_flags.SetSkipPointers(true); +  cpp_category_sp->GetRegexTypeSummariesContainer()->Add( +      RegularExpressionSP( +          new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))), +      TypeSummaryImplSP( +          new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); +  cpp_category_sp->GetRegexTypeSummariesContainer()->Add( +      RegularExpressionSP( +          new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))), +      TypeSummaryImplSP( +          new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); +  cpp_category_sp->GetRegexTypeSummariesContainer()->Add( +      RegularExpressionSP(new RegularExpression( +          llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))), +      TypeSummaryImplSP( +          new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); + +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, +      "std::vector iterator synthetic children", +      ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true); + +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, +      "std::map iterator synthetic children", +      ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true); + +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator, +      "std::unique_ptr synthetic children", +      ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_synth_flags, true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator, +      "std::shared_ptr synthetic children", +      ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator, +      "std::weak_ptr synthetic children", +      ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true); +  AddCXXSynthetic( +      cpp_category_sp, +      lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator, +      "std::tuple synthetic children", ConstString("^std::tuple<.+>(( )?&)?$"), +      stl_synth_flags, true); + +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibStdcppUniquePointerSummaryProvider, +                "libstdc++ std::unique_ptr summary provider", +                ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_summary_flags, +                true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibStdcppSmartPointerSummaryProvider, +                "libstdc++ std::shared_ptr summary provider", +                ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_summary_flags, +                true); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::LibStdcppSmartPointerSummaryProvider, +                "libstdc++ std::weak_ptr summary provider", +                ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_summary_flags, +                true);  #endif  } -static void -LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) -{ -    if (!cpp_category_sp) -        return; -     -    TypeSummaryImpl::Flags string_flags; -    string_flags.SetCascades(true) -    .SetSkipPointers(true) -    .SetSkipReferences(false) -    .SetDontShowChildren(true) -    .SetDontShowValue(false) -    .SetShowMembersOneLiner(false) -    .SetHideItemNames(false); -     -    TypeSummaryImpl::Flags string_array_flags; -    string_array_flags.SetCascades(true) -    .SetSkipPointers(true) -    .SetSkipReferences(false) -    .SetDontShowChildren(true) -    .SetDontShowValue(true) -    .SetShowMembersOneLiner(false) -    .SetHideItemNames(false); -     +static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { +  if (!cpp_category_sp) +    return; + +  TypeSummaryImpl::Flags string_flags; +  string_flags.SetCascades(true) +      .SetSkipPointers(true) +      .SetSkipReferences(false) +      .SetDontShowChildren(true) +      .SetDontShowValue(false) +      .SetShowMembersOneLiner(false) +      .SetHideItemNames(false); + +  TypeSummaryImpl::Flags string_array_flags; +  string_array_flags.SetCascades(true) +      .SetSkipPointers(true) +      .SetSkipReferences(false) +      .SetDontShowChildren(true) +      .SetDontShowValue(true) +      .SetShowMembersOneLiner(false) +      .SetHideItemNames(false); +  #ifndef LLDB_DISABLE_PYTHON -    // FIXME because of a bug in the FormattersContainer we need to add a summary for both X* and const X* (<rdar://problem/12717717>) -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "char16_t * summary provider", ConstString("char16_t *"), string_flags); -    AddCXXSummary(cpp_category_sp, -                  lldb_private::formatters::Char16StringSummaryProvider, -                  "char16_t [] summary provider", -                  ConstString("char16_t \\[[0-9]+\\]"), -                  string_array_flags, -                  true); -     -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider, "char32_t * summary provider", ConstString("char32_t *"), string_flags); -    AddCXXSummary(cpp_category_sp, -                  lldb_private::formatters::Char32StringSummaryProvider, -                  "char32_t [] summary provider", -                  ConstString("char32_t \\[[0-9]+\\]"), -                  string_array_flags, -                  true); -     -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("wchar_t *"), string_flags); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("wchar_t \\[[0-9]+\\]"), string_array_flags, true); -     -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "unichar * summary provider", ConstString("unichar *"), string_flags); -     -    TypeSummaryImpl::Flags widechar_flags; -    widechar_flags.SetDontShowValue(true) -    .SetSkipPointers(true) -    .SetSkipReferences(false) -    .SetCascades(true) -    .SetDontShowChildren(true) -    .SetHideItemNames(true) -    .SetShowMembersOneLiner(false); -     -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, "char16_t summary provider", ConstString("char16_t"), widechar_flags); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char32SummaryProvider, "char32_t summary provider", ConstString("char32_t"), widechar_flags); -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider, "wchar_t summary provider", ConstString("wchar_t"), widechar_flags); -     -    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, "unichar summary provider", ConstString("unichar"), widechar_flags); +  // FIXME because of a bug in the FormattersContainer we need to add a summary +  // for both X* and const X* (<rdar://problem/12717717>) +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, +      "char16_t * summary provider", ConstString("char16_t *"), string_flags); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::Char16StringSummaryProvider, +                "char16_t [] summary provider", +                ConstString("char16_t \\[[0-9]+\\]"), string_array_flags, true); + +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider, +      "char32_t * summary provider", ConstString("char32_t *"), string_flags); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::Char32StringSummaryProvider, +                "char32_t [] summary provider", +                ConstString("char32_t \\[[0-9]+\\]"), string_array_flags, true); + +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, +      "wchar_t * summary provider", ConstString("wchar_t *"), string_flags); +  AddCXXSummary(cpp_category_sp, +                lldb_private::formatters::WCharStringSummaryProvider, +                "wchar_t * summary provider", +                ConstString("wchar_t \\[[0-9]+\\]"), string_array_flags, true); + +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, +      "unichar * summary provider", ConstString("unichar *"), string_flags); + +  TypeSummaryImpl::Flags widechar_flags; +  widechar_flags.SetDontShowValue(true) +      .SetSkipPointers(true) +      .SetSkipReferences(false) +      .SetCascades(true) +      .SetDontShowChildren(true) +      .SetHideItemNames(true) +      .SetShowMembersOneLiner(false); + +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, +      "char16_t summary provider", ConstString("char16_t"), widechar_flags); +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::Char32SummaryProvider, +      "char32_t summary provider", ConstString("char32_t"), widechar_flags); +  AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider, +                "wchar_t summary provider", ConstString("wchar_t"), +                widechar_flags); + +  AddCXXSummary( +      cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, +      "unichar summary provider", ConstString("unichar"), widechar_flags);  #endif  } -lldb::TypeCategoryImplSP -CPlusPlusLanguage::GetFormatters () -{ -    static std::once_flag g_initialize; -    static TypeCategoryImplSP g_category; -     -    std::call_once(g_initialize, [this] () -> void { -        DataVisualization::Categories::GetCategory(GetPluginName(), g_category); -        if (g_category) -        { -            LoadLibCxxFormatters(g_category); -            LoadLibStdcppFormatters(g_category); -            LoadSystemFormatters(g_category); -        } -    }); -    return g_category; +std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() { +  class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger { +  public: +    virtual CompilerType AdjustForInclusion(CompilerType &candidate) override { +      LanguageType lang_type(candidate.GetMinimumLanguage()); +      if (!Language::LanguageIsC(lang_type) && +          !Language::LanguageIsCPlusPlus(lang_type)) +        return CompilerType(); +      if (candidate.IsTypedefType()) +        return candidate.GetTypedefedType(); +      return candidate; +    } +  }; + +  return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger()); +} + +lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() { +  static std::once_flag g_initialize; +  static TypeCategoryImplSP g_category; + +  std::call_once(g_initialize, [this]() -> void { +    DataVisualization::Categories::GetCategory(GetPluginName(), g_category); +    if (g_category) { +      LoadLibCxxFormatters(g_category); +      LoadLibStdcppFormatters(g_category); +      LoadSystemFormatters(g_category); +    } +  }); +  return g_category;  }  HardcodedFormatters::HardcodedSummaryFinder -CPlusPlusLanguage::GetHardcodedSummaries () -{ -    static std::once_flag g_initialize; -    static ConstString g_vectortypes("VectorTypes"); -    static HardcodedFormatters::HardcodedSummaryFinder g_formatters; -     -    std::call_once(g_initialize, [] () -> void { -        g_formatters.push_back( -                                        [](lldb_private::ValueObject& valobj, -                                           lldb::DynamicValueType, -                                           FormatManager&) -> TypeSummaryImpl::SharedPointer { -                                            static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags(), lldb_private::formatters::CXXFunctionPointerSummaryProvider, "Function pointer summary provider")); -                                            if (valobj.GetCompilerType().IsFunctionPointerType()) -                                            { -                                                return formatter_sp; -                                            } -                                            return nullptr; -                                        }); -        g_formatters.push_back( -                                        [](lldb_private::ValueObject& valobj, -                                           lldb::DynamicValueType, -                                           FormatManager& fmt_mgr) -> TypeSummaryImpl::SharedPointer { -                                            static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags() -                                                                                                                                     .SetCascades(true) -                                                                                                                                     .SetDontShowChildren(true) -                                                                                                                                     .SetHideItemNames(true) -                                                                                                                                     .SetShowMembersOneLiner(true) -                                                                                                                                     .SetSkipPointers(true) -                                                                                                                                     .SetSkipReferences(false), -                                                                                                                                     lldb_private::formatters::VectorTypeSummaryProvider, -                                                                                                                                     "vector_type pointer summary provider")); -                                            if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) -                                            { -                                                if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled()) -                                                    return formatter_sp; -                                            } -                                            return nullptr; -                                        }); -        g_formatters.push_back( -                               [](lldb_private::ValueObject& valobj, -                                  lldb::DynamicValueType, -                                  FormatManager& fmt_mgr) -> TypeSummaryImpl::SharedPointer { -                                   static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags() -                                                                                                                            .SetCascades(true) -                                                                                                                            .SetDontShowChildren(true) -                                                                                                                            .SetHideItemNames(true) -                                                                                                                            .SetShowMembersOneLiner(true) -                                                                                                                            .SetSkipPointers(true) -                                                                                                                            .SetSkipReferences(false), -                                                                                                                            lldb_private::formatters::BlockPointerSummaryProvider, -                                                                                                                            "block pointer summary provider")); -                                   if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) -                                   { -                                       return formatter_sp; -                                   } -                                   return nullptr; -                               }); -    }); -     -    return g_formatters; +CPlusPlusLanguage::GetHardcodedSummaries() { +  static std::once_flag g_initialize; +  static ConstString g_vectortypes("VectorTypes"); +  static HardcodedFormatters::HardcodedSummaryFinder g_formatters; + +  std::call_once(g_initialize, []() -> void { +    g_formatters.push_back( +        [](lldb_private::ValueObject &valobj, lldb::DynamicValueType, +           FormatManager &) -> TypeSummaryImpl::SharedPointer { +          static CXXFunctionSummaryFormat::SharedPointer formatter_sp( +              new CXXFunctionSummaryFormat( +                  TypeSummaryImpl::Flags(), +                  lldb_private::formatters::CXXFunctionPointerSummaryProvider, +                  "Function pointer summary provider")); +          if (valobj.GetCompilerType().IsFunctionPointerType()) { +            return formatter_sp; +          } +          return nullptr; +        }); +    g_formatters.push_back( +        [](lldb_private::ValueObject &valobj, lldb::DynamicValueType, +           FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer { +          static CXXFunctionSummaryFormat::SharedPointer formatter_sp( +              new CXXFunctionSummaryFormat( +                  TypeSummaryImpl::Flags() +                      .SetCascades(true) +                      .SetDontShowChildren(true) +                      .SetHideItemNames(true) +                      .SetShowMembersOneLiner(true) +                      .SetSkipPointers(true) +                      .SetSkipReferences(false), +                  lldb_private::formatters::VectorTypeSummaryProvider, +                  "vector_type pointer summary provider")); +          if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) { +            if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled()) +              return formatter_sp; +          } +          return nullptr; +        }); +    g_formatters.push_back( +        [](lldb_private::ValueObject &valobj, lldb::DynamicValueType, +           FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer { +          static CXXFunctionSummaryFormat::SharedPointer formatter_sp( +              new CXXFunctionSummaryFormat( +                  TypeSummaryImpl::Flags() +                      .SetCascades(true) +                      .SetDontShowChildren(true) +                      .SetHideItemNames(true) +                      .SetShowMembersOneLiner(true) +                      .SetSkipPointers(true) +                      .SetSkipReferences(false), +                  lldb_private::formatters::BlockPointerSummaryProvider, +                  "block pointer summary provider")); +          if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) { +            return formatter_sp; +          } +          return nullptr; +        }); +  }); + +  return g_formatters;  }  HardcodedFormatters::HardcodedSyntheticFinder -CPlusPlusLanguage::GetHardcodedSynthetics () -{ -    static std::once_flag g_initialize; -    static ConstString g_vectortypes("VectorTypes"); -    static HardcodedFormatters::HardcodedSyntheticFinder g_formatters; -     -    std::call_once(g_initialize, [] () -> void { -        g_formatters.push_back( -                                         [](lldb_private::ValueObject& valobj, -                                            lldb::DynamicValueType, -                                            FormatManager& fmt_mgr) -> SyntheticChildren::SharedPointer { -                                             static CXXSyntheticChildren::SharedPointer formatter_sp(new CXXSyntheticChildren(SyntheticChildren::Flags().SetCascades(true).SetSkipPointers(true).SetSkipReferences(true).SetNonCacheable(true), -                                                                                                                              "vector_type synthetic children", -                                                                                                                              lldb_private::formatters::VectorTypeSyntheticFrontEndCreator)); -                                             if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) -                                             { -                                                 if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled()) -                                                     return formatter_sp; -                                             } -                                             return nullptr; -                                         }); -        g_formatters.push_back( -                                         [](lldb_private::ValueObject& valobj, -                                            lldb::DynamicValueType, -                                            FormatManager& fmt_mgr) -> SyntheticChildren::SharedPointer { -                                             static CXXSyntheticChildren::SharedPointer formatter_sp(new CXXSyntheticChildren(SyntheticChildren::Flags().SetCascades(true).SetSkipPointers(true).SetSkipReferences(true).SetNonCacheable(true), -                                                                                                                              "block pointer synthetic children", -                                                                                                                              lldb_private::formatters::BlockPointerSyntheticFrontEndCreator)); -                                             if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) -                                             { -                                                 return formatter_sp; -                                             } -                                             return nullptr; -                                         }); +CPlusPlusLanguage::GetHardcodedSynthetics() { +  static std::once_flag g_initialize; +  static ConstString g_vectortypes("VectorTypes"); +  static HardcodedFormatters::HardcodedSyntheticFinder g_formatters; +  std::call_once(g_initialize, []() -> void { +    g_formatters.push_back([](lldb_private::ValueObject &valobj, +                              lldb::DynamicValueType, +                              FormatManager & +                                  fmt_mgr) -> SyntheticChildren::SharedPointer { +      static CXXSyntheticChildren::SharedPointer formatter_sp( +          new CXXSyntheticChildren( +              SyntheticChildren::Flags() +                  .SetCascades(true) +                  .SetSkipPointers(true) +                  .SetSkipReferences(true) +                  .SetNonCacheable(true), +              "vector_type synthetic children", +              lldb_private::formatters::VectorTypeSyntheticFrontEndCreator)); +      if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) { +        if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled()) +          return formatter_sp; +      } +      return nullptr; +    }); +    g_formatters.push_back([](lldb_private::ValueObject &valobj, +                              lldb::DynamicValueType, +                              FormatManager & +                                  fmt_mgr) -> SyntheticChildren::SharedPointer { +      static CXXSyntheticChildren::SharedPointer formatter_sp( +          new CXXSyntheticChildren( +              SyntheticChildren::Flags() +                  .SetCascades(true) +                  .SetSkipPointers(true) +                  .SetSkipReferences(true) +                  .SetNonCacheable(true), +              "block pointer synthetic children", +              lldb_private::formatters::BlockPointerSyntheticFrontEndCreator)); +      if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) { +        return formatter_sp; +      } +      return nullptr;      }); -     -    return g_formatters; + +  }); + +  return g_formatters;  } diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h index f0fc07e20066..be5cbae57de2 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -12,178 +12,150 @@  // C Includes  // C++ Includes +#include <set>  #include <vector>  // Other libraries and framework includes  #include "llvm/ADT/StringRef.h"  // Project includes -#include "lldb/lldb-private.h"  #include "lldb/Core/ConstString.h"  #include "lldb/Target/Language.h" +#include "lldb/lldb-private.h"  namespace lldb_private { -     -class CPlusPlusLanguage : -    public Language -{ -public: -    class MethodName -    { -    public: -        enum Type -        { -            eTypeInvalid, -            eTypeUnknownMethod, -            eTypeClassMethod, -            eTypeInstanceMethod -        }; -         -        MethodName () : -            m_full(), -            m_basename(), -            m_context(), -            m_arguments(), -            m_qualifiers(), -            m_type (eTypeInvalid), -            m_parsed (false), -            m_parse_error (false) -        { -        } - -        MethodName (const ConstString &s) : -            m_full(s), -            m_basename(), -            m_context(), -            m_arguments(), -            m_qualifiers(), -            m_type (eTypeInvalid), -            m_parsed (false), -            m_parse_error (false) -        { -        } - -        void -        Clear(); -         -        bool -        IsValid () -        { -            if (!m_parsed) -                Parse(); -            if (m_parse_error) -                return false; -            if (m_type == eTypeInvalid) -                return false; -            return (bool)m_full; -        } - -        Type -        GetType () const -        { -            return m_type; -        } -         -        const ConstString & -        GetFullName () const -        { -            return m_full; -        } - -        std::string -        GetScopeQualifiedName (); -         -        llvm::StringRef -        GetBasename (); - -        llvm::StringRef -        GetContext (); -         -        llvm::StringRef -        GetArguments (); -         -        llvm::StringRef -        GetQualifiers (); - -    protected: -        void -        Parse(); -        ConstString     m_full;         // Full name:    "lldb::SBTarget::GetBreakpointAtIndex(unsigned int) const" -        llvm::StringRef m_basename;     // Basename:     "GetBreakpointAtIndex" -        llvm::StringRef m_context;      // Decl context: "lldb::SBTarget" -        llvm::StringRef m_arguments;    // Arguments:    "(unsigned int)" -        llvm::StringRef m_qualifiers;   // Qualifiers:   "const" -        Type m_type; -        bool m_parsed; -        bool m_parse_error; +class CPlusPlusLanguage : public Language { +public: +  class MethodName { +  public: +    enum Type { +      eTypeInvalid, +      eTypeUnknownMethod, +      eTypeClassMethod, +      eTypeInstanceMethod      }; -    CPlusPlusLanguage() = default; +    MethodName() +        : m_full(), m_basename(), m_context(), m_arguments(), m_qualifiers(), +          m_type(eTypeInvalid), m_parsed(false), m_parse_error(false) {} -    ~CPlusPlusLanguage() override = default; +    MethodName(const ConstString &s) +        : m_full(s), m_basename(), m_context(), m_arguments(), m_qualifiers(), +          m_type(eTypeInvalid), m_parsed(false), m_parse_error(false) {} -    lldb::LanguageType -    GetLanguageType () const override -    { -        return lldb::eLanguageTypeC_plus_plus; +    void Clear(); + +    bool IsValid() { +      if (!m_parsed) +        Parse(); +      if (m_parse_error) +        return false; +      if (m_type == eTypeInvalid) +        return false; +      return (bool)m_full;      } -     -    lldb::TypeCategoryImplSP -    GetFormatters () override; -     -    HardcodedFormatters::HardcodedSummaryFinder -    GetHardcodedSummaries () override; -     -    HardcodedFormatters::HardcodedSyntheticFinder -    GetHardcodedSynthetics () override; -     -    //------------------------------------------------------------------ -    // Static Functions -    //------------------------------------------------------------------ -    static void -    Initialize(); -     -    static void -    Terminate(); -     -    static lldb_private::Language * -    CreateInstance (lldb::LanguageType language); -     -    static lldb_private::ConstString -    GetPluginNameStatic(); - -    static bool -    IsCPPMangledName(const char *name); - -    // Extract C++ context and identifier from a string using heuristic matching (as opposed to -    // CPlusPlusLanguage::MethodName which has to have a fully qualified C++ name with parens and arguments. -    // If the name is a lone C identifier (e.g. C) or a qualified C identifier (e.g. A::B::C) it will return true, -    // and identifier will be the identifier (C and C respectively) and the context will be "" and "A::B::" respectively. -    // If the name fails the heuristic matching for a qualified or unqualified C/C++ identifier, then it will return false -    // and identifier and context will be unchanged. - -    static bool -    ExtractContextAndIdentifier (const char *name, llvm::StringRef &context, llvm::StringRef &identifier); -     -    // in some cases, compilers will output different names for one same type. when that happens, it might be impossible -    // to construct SBType objects for a valid type, because the name that is available is not the same as the name that -    // can be used as a search key in FindTypes(). the equivalents map here is meant to return possible alternative names -    // for a type through which a search can be conducted. Currently, this is only enabled for C++ but can be extended -    // to ObjC or other languages if necessary -    static uint32_t -    FindEquivalentNames(ConstString type_name, std::vector<ConstString>& equivalents); - -    //------------------------------------------------------------------ -    // PluginInterface protocol -    //------------------------------------------------------------------ -    ConstString -    GetPluginName() override; -     -    uint32_t -    GetPluginVersion() override; + +    Type GetType() const { return m_type; } + +    const ConstString &GetFullName() const { return m_full; } + +    std::string GetScopeQualifiedName(); + +    llvm::StringRef GetBasename(); + +    llvm::StringRef GetContext(); + +    llvm::StringRef GetArguments(); + +    llvm::StringRef GetQualifiers(); + +  protected: +    void Parse(); + +    ConstString m_full; // Full name: +                        // "lldb::SBTarget::GetBreakpointAtIndex(unsigned int) +                        // const" +    llvm::StringRef m_basename;   // Basename:     "GetBreakpointAtIndex" +    llvm::StringRef m_context;    // Decl context: "lldb::SBTarget" +    llvm::StringRef m_arguments;  // Arguments:    "(unsigned int)" +    llvm::StringRef m_qualifiers; // Qualifiers:   "const" +    Type m_type; +    bool m_parsed; +    bool m_parse_error; +  }; + +  CPlusPlusLanguage() = default; + +  ~CPlusPlusLanguage() override = default; + +  lldb::LanguageType GetLanguageType() const override { +    return lldb::eLanguageTypeC_plus_plus; +  } + +  std::unique_ptr<TypeScavenger> GetTypeScavenger() override; +  lldb::TypeCategoryImplSP GetFormatters() override; + +  HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override; + +  HardcodedFormatters::HardcodedSyntheticFinder +  GetHardcodedSynthetics() override; + +  //------------------------------------------------------------------ +  // Static Functions +  //------------------------------------------------------------------ +  static void Initialize(); + +  static void Terminate(); + +  static lldb_private::Language *CreateInstance(lldb::LanguageType language); + +  static lldb_private::ConstString GetPluginNameStatic(); + +  static bool IsCPPMangledName(const char *name); + +  // Extract C++ context and identifier from a string using heuristic matching +  // (as opposed to +  // CPlusPlusLanguage::MethodName which has to have a fully qualified C++ name +  // with parens and arguments. +  // If the name is a lone C identifier (e.g. C) or a qualified C identifier +  // (e.g. A::B::C) it will return true, +  // and identifier will be the identifier (C and C respectively) and the +  // context will be "" and "A::B::" respectively. +  // If the name fails the heuristic matching for a qualified or unqualified +  // C/C++ identifier, then it will return false +  // and identifier and context will be unchanged. + +  static bool ExtractContextAndIdentifier(const char *name, +                                          llvm::StringRef &context, +                                          llvm::StringRef &identifier); + +  // in some cases, compilers will output different names for one same type. +  // when that happens, it might be impossible +  // to construct SBType objects for a valid type, because the name that is +  // available is not the same as the name that +  // can be used as a search key in FindTypes(). the equivalents map here is +  // meant to return possible alternative names +  // for a type through which a search can be conducted. Currently, this is only +  // enabled for C++ but can be extended +  // to ObjC or other languages if necessary +  static uint32_t FindEquivalentNames(ConstString type_name, +                                      std::vector<ConstString> &equivalents); + +  // Given a mangled function name, calculates some alternative manglings since +  // the compiler mangling may not line up with the symbol we are expecting +  static uint32_t +  FindAlternateFunctionManglings(const ConstString mangled, +                                 std::set<ConstString> &candidates); + +  //------------------------------------------------------------------ +  // PluginInterface protocol +  //------------------------------------------------------------------ +  ConstString GetPluginName() override; + +  uint32_t GetPluginVersion() override;  }; -     +  } // namespace lldb_private  #endif // liblldb_CPlusPlusLanguage_h_ diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index a2c45fb99893..346ea0bbd519 100644 --- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -1,4 +1,4 @@ -//===-- CXXStringTypes.cpp --------------------------------------*- C++ -*-===// +//===-- CxxStringTypes.cpp --------------------------------------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -16,209 +16,208 @@  #include "lldb/Core/Stream.h"  #include "lldb/Core/ValueObject.h"  #include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/DataFormatters/FormattersHelpers.h"  #include "lldb/DataFormatters/StringPrinter.h"  #include "lldb/DataFormatters/TypeSummary.h"  #include "lldb/Host/Endian.h" +#include "lldb/Host/Time.h"  #include "lldb/Symbol/ClangASTContext.h"  #include "lldb/Target/SectionLoadList.h"  #include "lldb/Target/Target.h"  #include "lldb/Target/Thread.h"  #include "lldb/Utility/ProcessStructReader.h" -#include "lldb/DataFormatters/FormattersHelpers.h"  #include <algorithm> -#if __ANDROID_NDK__ -#include <sys/types.h> -#endif - -#include "lldb/Host/Time.h" -  using namespace lldb;  using namespace lldb_private;  using namespace lldb_private::formatters; -bool -lldb_private::formatters::Char16StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&) -{ -    ProcessSP process_sp = valobj.GetProcessSP(); -    if (!process_sp) -        return false; -     -    lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); -    if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) -        return false; -     -    StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); -    options.SetLocation(valobj_addr); -    options.SetProcessSP(process_sp); -    options.SetStream(&stream); -    options.SetPrefixToken("u"); -     -    if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options)) -    { -        stream.Printf("Summary Unavailable"); -        return true; -    } -     +bool lldb_private::formatters::Char16StringSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { +  ProcessSP process_sp = valobj.GetProcessSP(); +  if (!process_sp) +    return false; + +  lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); +  if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) +    return false; + +  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); +  options.SetLocation(valobj_addr); +  options.SetProcessSP(process_sp); +  options.SetStream(&stream); +  options.SetPrefixToken("u"); + +  if (!StringPrinter::ReadStringAndDumpToStream< +          StringPrinter::StringElementType::UTF16>(options)) { +    stream.Printf("Summary Unavailable");      return true; +  } + +  return true;  } -bool -lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&) -{ -    ProcessSP process_sp = valobj.GetProcessSP(); -    if (!process_sp) -        return false; -     -    lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); -    if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) -        return false; -     -    StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); -    options.SetLocation(valobj_addr); -    options.SetProcessSP(process_sp); -    options.SetStream(&stream); -    options.SetPrefixToken("U"); -     -    if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options)) -    { -        stream.Printf("Summary Unavailable"); -        return true; -    } -     +bool lldb_private::formatters::Char32StringSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { +  ProcessSP process_sp = valobj.GetProcessSP(); +  if (!process_sp) +    return false; + +  lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); +  if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) +    return false; + +  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); +  options.SetLocation(valobj_addr); +  options.SetProcessSP(process_sp); +  options.SetStream(&stream); +  options.SetPrefixToken("U"); + +  if (!StringPrinter::ReadStringAndDumpToStream< +          StringPrinter::StringElementType::UTF32>(options)) { +    stream.Printf("Summary Unavailable");      return true; +  } + +  return true;  } -bool -lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&) -{ -    ProcessSP process_sp = valobj.GetProcessSP(); -    if (!process_sp) -        return false; -     -    lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); -    if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) -        return false; -     -    // Get a wchar_t basic type from the current type system -    CompilerType wchar_compiler_type = valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); -     -    if (!wchar_compiler_type) -        return false; -     -    const uint32_t wchar_size = wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here -     -    StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); -    options.SetLocation(valobj_addr); -    options.SetProcessSP(process_sp); -    options.SetStream(&stream); -    options.SetPrefixToken("L"); -     -    switch (wchar_size) -    { -        case 8: -            return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options); -        case 16: -            return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options); -        case 32: -            return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options); -        default: -            stream.Printf("size for wchar_t is not valid"); -            return true; -    } +bool lldb_private::formatters::WCharStringSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { +  ProcessSP process_sp = valobj.GetProcessSP(); +  if (!process_sp) +    return false; + +  lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); +  if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) +    return false; + +  // Get a wchar_t basic type from the current type system +  CompilerType wchar_compiler_type = +      valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); + +  if (!wchar_compiler_type) +    return false; + +  const uint32_t wchar_size = wchar_compiler_type.GetBitSize( +      nullptr); // Safe to pass NULL for exe_scope here + +  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); +  options.SetLocation(valobj_addr); +  options.SetProcessSP(process_sp); +  options.SetStream(&stream); +  options.SetPrefixToken("L"); + +  switch (wchar_size) { +  case 8: +    return StringPrinter::ReadStringAndDumpToStream< +        StringPrinter::StringElementType::UTF8>(options); +  case 16: +    return StringPrinter::ReadStringAndDumpToStream< +        StringPrinter::StringElementType::UTF16>(options); +  case 32: +    return StringPrinter::ReadStringAndDumpToStream< +        StringPrinter::StringElementType::UTF32>(options); +  default: +    stream.Printf("size for wchar_t is not valid");      return true; +  } +  return true;  } -bool -lldb_private::formatters::Char16SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&) -{ -    DataExtractor data; -    Error error; -    valobj.GetData(data, error); -     -    if (error.Fail()) -        return false; -     -    std::string value; -    valobj.GetValueAsCString(lldb::eFormatUnicode16, value); -    if (!value.empty()) -        stream.Printf("%s ", value.c_str()); -     -    StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); -    options.SetData(data); -    options.SetStream(&stream); -    options.SetPrefixToken("u"); -    options.SetQuote('\''); -    options.SetSourceSize(1); -    options.SetBinaryZeroIsTerminator(false); -     -    return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options); +bool lldb_private::formatters::Char16SummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { +  DataExtractor data; +  Error error; +  valobj.GetData(data, error); + +  if (error.Fail()) +    return false; + +  std::string value; +  valobj.GetValueAsCString(lldb::eFormatUnicode16, value); +  if (!value.empty()) +    stream.Printf("%s ", value.c_str()); + +  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); +  options.SetData(data); +  options.SetStream(&stream); +  options.SetPrefixToken("u"); +  options.SetQuote('\''); +  options.SetSourceSize(1); +  options.SetBinaryZeroIsTerminator(false); + +  return StringPrinter::ReadBufferAndDumpToStream< +      StringPrinter::StringElementType::UTF16>(options);  } -bool -lldb_private::formatters::Char32SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&) -{ -    DataExtractor data; -    Error error; -    valobj.GetData(data, error); -     -    if (error.Fail()) -        return false; -     -    std::string value; -    valobj.GetValueAsCString(lldb::eFormatUnicode32, value); -    if (!value.empty()) -        stream.Printf("%s ", value.c_str()); -     -    StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); -    options.SetData(data); -    options.SetStream(&stream); -    options.SetPrefixToken("U"); -    options.SetQuote('\''); -    options.SetSourceSize(1); -    options.SetBinaryZeroIsTerminator(false); -     -    return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF32>(options); +bool lldb_private::formatters::Char32SummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { +  DataExtractor data; +  Error error; +  valobj.GetData(data, error); + +  if (error.Fail()) +    return false; + +  std::string value; +  valobj.GetValueAsCString(lldb::eFormatUnicode32, value); +  if (!value.empty()) +    stream.Printf("%s ", value.c_str()); + +  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); +  options.SetData(data); +  options.SetStream(&stream); +  options.SetPrefixToken("U"); +  options.SetQuote('\''); +  options.SetSourceSize(1); +  options.SetBinaryZeroIsTerminator(false); + +  return StringPrinter::ReadBufferAndDumpToStream< +      StringPrinter::StringElementType::UTF32>(options);  } -bool -lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&) -{ -    DataExtractor data; -    Error error; -    valobj.GetData(data, error); -     -    if (error.Fail()) -        return false; -     -    // Get a wchar_t basic type from the current type system -    CompilerType wchar_compiler_type = valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); - -    if (!wchar_compiler_type) -        return false; - -    const uint32_t wchar_size = wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here - -    StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); -    options.SetData(data); -    options.SetStream(&stream); -    options.SetPrefixToken("L"); -    options.SetQuote('\''); -    options.SetSourceSize(1); -    options.SetBinaryZeroIsTerminator(false); -     -    switch (wchar_size) -    { -        case 8: -            return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF8>(options); -        case 16: -            return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options); -        case 32: -            return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF32>(options); -        default: -            stream.Printf("size for wchar_t is not valid"); -            return true; -    } +bool lldb_private::formatters::WCharSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { +  DataExtractor data; +  Error error; +  valobj.GetData(data, error); + +  if (error.Fail()) +    return false; + +  // Get a wchar_t basic type from the current type system +  CompilerType wchar_compiler_type = +      valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); + +  if (!wchar_compiler_type) +    return false; + +  const uint32_t wchar_size = wchar_compiler_type.GetBitSize( +      nullptr); // Safe to pass NULL for exe_scope here + +  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); +  options.SetData(data); +  options.SetStream(&stream); +  options.SetPrefixToken("L"); +  options.SetQuote('\''); +  options.SetSourceSize(1); +  options.SetBinaryZeroIsTerminator(false); + +  switch (wchar_size) { +  case 8: +    return StringPrinter::ReadBufferAndDumpToStream< +        StringPrinter::StringElementType::UTF8>(options); +  case 16: +    return StringPrinter::ReadBufferAndDumpToStream< +        StringPrinter::StringElementType::UTF16>(options); +  case 32: +    return StringPrinter::ReadBufferAndDumpToStream< +        StringPrinter::StringElementType::UTF32>(options); +  default: +    stream.Printf("size for wchar_t is not valid");      return true; +  } +  return true;  } diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h index bfb03bda7ee0..0bee3bd3b0f2 100644 --- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h +++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h @@ -1,4 +1,5 @@ -//===-- CxxStringTypes.h ----------------------------------------------*- C++ -*-===// +//===-- CxxStringTypes.h ----------------------------------------------*- C++ +//-*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -15,27 +16,29 @@  #include "lldb/DataFormatters/TypeSummary.h"  namespace lldb_private { -    namespace formatters -    { -        bool -        Char16StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char16_t* and unichar* -         -        bool -        Char32StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char32_t* -         -        bool -        WCharStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // wchar_t* -         -        bool -        Char16SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char16_t and unichar -         -        bool -        Char32SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // char32_t -         -        bool -        WCharSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // wchar_t -         -    } // namespace formatters +namespace formatters { +bool Char16StringSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &options); // char16_t* and unichar* + +bool Char32StringSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &options); // char32_t* + +bool WCharStringSummaryProvider(ValueObject &valobj, Stream &stream, +                                const TypeSummaryOptions &options); // wchar_t* + +bool Char16SummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &options); // char16_t and unichar + +bool Char32SummaryProvider(ValueObject &valobj, Stream &stream, +                           const TypeSummaryOptions &options); // char32_t + +bool WCharSummaryProvider(ValueObject &valobj, Stream &stream, +                          const TypeSummaryOptions &options); // wchar_t + +} // namespace formatters  } // namespace lldb_private  #endif // liblldb_CxxStringTypes_h_ diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp index beb89b89c635..82441a69b1d4 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -27,202 +27,211 @@  #include "lldb/Host/Endian.h"  #include "lldb/Symbol/ClangASTContext.h"  #include "lldb/Target/Target.h" +#include "lldb/Utility/ProcessStructReader.h"  using namespace lldb;  using namespace lldb_private;  using namespace lldb_private::formatters; -bool -lldb_private::formatters::LibcxxSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) -{ -    ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); -    if (!valobj_sp) -        return false; -    ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)); -    ValueObjectSP count_sp(valobj_sp->GetChildAtNamePath( {ConstString("__cntrl_"),ConstString("__shared_owners_")} )); -    ValueObjectSP weakcount_sp(valobj_sp->GetChildAtNamePath( {ConstString("__cntrl_"),ConstString("__shared_weak_owners_")} )); -     -    if (!ptr_sp) -        return false; -     -    if (ptr_sp->GetValueAsUnsigned(0) == 0) -    { -        stream.Printf("nullptr"); -        return true; -    } -    else -    { -        bool print_pointee = false; -        Error error; -        ValueObjectSP pointee_sp = ptr_sp->Dereference(error); -        if (pointee_sp && error.Success()) -        { -            if (pointee_sp->DumpPrintableRepresentation(stream, -                                                        ValueObject::eValueObjectRepresentationStyleSummary, -                                                        lldb::eFormatInvalid, -                                                        ValueObject::ePrintableRepresentationSpecialCasesDisable, -                                                        false)) -                print_pointee = true; -        } -        if (!print_pointee) -            stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0)); -    } -     -    if (count_sp) -        stream.Printf(" strong=%" PRIu64, 1+count_sp->GetValueAsUnsigned(0)); +bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { +  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); +  if (!valobj_sp) +    return false; +  ValueObjectSP ptr_sp( +      valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)); +  ValueObjectSP count_sp(valobj_sp->GetChildAtNamePath( +      {ConstString("__cntrl_"), ConstString("__shared_owners_")})); +  ValueObjectSP weakcount_sp(valobj_sp->GetChildAtNamePath( +      {ConstString("__cntrl_"), ConstString("__shared_weak_owners_")})); + +  if (!ptr_sp) +    return false; -    if (weakcount_sp) -        stream.Printf(" weak=%" PRIu64, 1+weakcount_sp->GetValueAsUnsigned(0)); -     +  if (ptr_sp->GetValueAsUnsigned(0) == 0) { +    stream.Printf("nullptr");      return true; +  } else { +    bool print_pointee = false; +    Error error; +    ValueObjectSP pointee_sp = ptr_sp->Dereference(error); +    if (pointee_sp && error.Success()) { +      if (pointee_sp->DumpPrintableRepresentation( +              stream, ValueObject::eValueObjectRepresentationStyleSummary, +              lldb::eFormatInvalid, +              ValueObject::PrintableRepresentationSpecialCases::eDisable, +              false)) +        print_pointee = true; +    } +    if (!print_pointee) +      stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0)); +  } + +  if (count_sp) +    stream.Printf(" strong=%" PRIu64, 1 + count_sp->GetValueAsUnsigned(0)); + +  if (weakcount_sp) +    stream.Printf(" weak=%" PRIu64, 1 + weakcount_sp->GetValueAsUnsigned(0)); + +  return true;  } -lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_bool_type(), -    m_exe_ctx_ref(), -    m_count(0), -    m_base_data_address(0), -    m_children() -{ -    if (valobj_sp) -    { -        Update(); -        m_bool_type = valobj_sp->GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeBool); -    } +lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd:: +    LibcxxVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_bool_type(), m_exe_ctx_ref(), +      m_count(0), m_base_data_address(0), m_children() { +  if (valobj_sp) { +    Update(); +    m_bool_type = +        valobj_sp->GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeBool); +  }  } -size_t -lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::CalculateNumChildren () -{ -    return m_count; +size_t lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd:: +    CalculateNumChildren() { +  return m_count;  }  lldb::ValueObjectSP -lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex (size_t idx) -{ -    auto iter = m_children.find(idx), -        end = m_children.end(); -    if (iter != end) -        return iter->second; -    if (idx >= m_count) -        return ValueObjectSP(); -    if (m_base_data_address == 0 || m_count == 0) -        return ValueObjectSP(); -    if (!m_bool_type) -        return ValueObjectSP(); -    size_t byte_idx = (idx >> 3); // divide by 8 to get byte index -    size_t bit_index = (idx & 7); // efficient idx % 8 for bit index -    lldb::addr_t byte_location = m_base_data_address + byte_idx; -    ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP()); -    if (!process_sp) -        return ValueObjectSP(); -    uint8_t byte = 0; -    uint8_t mask = 0; -    Error err; -    size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err); -    if (err.Fail() || bytes_read == 0) -        return ValueObjectSP(); -    switch (bit_index) -    { -        case 0: -            mask = 1; break; -        case 1: -            mask = 2; break; -        case 2: -            mask = 4; break; -        case 3: -            mask = 8; break; -        case 4: -            mask = 16; break; -        case 5: -            mask = 32; break; -        case 6: -            mask = 64; break; -        case 7: -            mask = 128; break; -        default: -            return ValueObjectSP(); -    } -    bool bit_set = ((byte & mask) != 0); -    DataBufferSP buffer_sp(new DataBufferHeap(m_bool_type.GetByteSize(nullptr), 0)); -    if (bit_set && buffer_sp && buffer_sp->GetBytes()) -        *(buffer_sp->GetBytes()) = 1; // regardless of endianness, anything non-zero is true -    StreamString name; name.Printf("[%" PRIu64 "]", (uint64_t)idx); -    ValueObjectSP retval_sp(CreateValueObjectFromData(name.GetData(), DataExtractor(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()), m_exe_ctx_ref, m_bool_type)); -    if (retval_sp) -        m_children[idx] = retval_sp; -    return retval_sp; +lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex( +    size_t idx) { +  auto iter = m_children.find(idx), end = m_children.end(); +  if (iter != end) +    return iter->second; +  if (idx >= m_count) +    return ValueObjectSP(); +  if (m_base_data_address == 0 || m_count == 0) +    return ValueObjectSP(); +  if (!m_bool_type) +    return ValueObjectSP(); +  size_t byte_idx = (idx >> 3); // divide by 8 to get byte index +  size_t bit_index = (idx & 7); // efficient idx % 8 for bit index +  lldb::addr_t byte_location = m_base_data_address + byte_idx; +  ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP()); +  if (!process_sp) +    return ValueObjectSP(); +  uint8_t byte = 0; +  uint8_t mask = 0; +  Error err; +  size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err); +  if (err.Fail() || bytes_read == 0) +    return ValueObjectSP(); +  switch (bit_index) { +  case 0: +    mask = 1; +    break; +  case 1: +    mask = 2; +    break; +  case 2: +    mask = 4; +    break; +  case 3: +    mask = 8; +    break; +  case 4: +    mask = 16; +    break; +  case 5: +    mask = 32; +    break; +  case 6: +    mask = 64; +    break; +  case 7: +    mask = 128; +    break; +  default: +    return ValueObjectSP(); +  } +  bool bit_set = ((byte & mask) != 0); +  DataBufferSP buffer_sp( +      new DataBufferHeap(m_bool_type.GetByteSize(nullptr), 0)); +  if (bit_set && buffer_sp && buffer_sp->GetBytes()) +    *(buffer_sp->GetBytes()) = +        1; // regardless of endianness, anything non-zero is true +  StreamString name; +  name.Printf("[%" PRIu64 "]", (uint64_t)idx); +  ValueObjectSP retval_sp(CreateValueObjectFromData( +      name.GetString(), DataExtractor(buffer_sp, process_sp->GetByteOrder(), +                                      process_sp->GetAddressByteSize()), +      m_exe_ctx_ref, m_bool_type)); +  if (retval_sp) +    m_children[idx] = retval_sp; +  return retval_sp;  }  /*(std::__1::vector<std::__1::allocator<bool> >) vBool = {   __begin_ = 0x00000001001000e0   __size_ = 56   __cap_alloc_ = { - std::__1::__libcpp_compressed_pair_imp<unsigned long, std::__1::allocator<unsigned long> > = { + std::__1::__libcpp_compressed_pair_imp<unsigned long, + std::__1::allocator<unsigned long> > = {   __first_ = 1   }   }   }*/ -bool -lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update() -{ -    m_children.clear(); -    ValueObjectSP valobj_sp = m_backend.GetSP(); -    if (!valobj_sp) -        return false; -    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); -    ValueObjectSP size_sp(valobj_sp->GetChildMemberWithName(ConstString("__size_"), true)); -    if (!size_sp) -        return false; -    m_count = size_sp->GetValueAsUnsigned(0); -    if (!m_count) -        return true; -    ValueObjectSP begin_sp(valobj_sp->GetChildMemberWithName(ConstString("__begin_"), true)); -    if (!begin_sp) -    { -        m_count = 0; -        return false; -    } -    m_base_data_address = begin_sp->GetValueAsUnsigned(0); -    if (!m_base_data_address) -    { -        m_count = 0; -        return false; -    } +bool lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update() { +  m_children.clear(); +  ValueObjectSP valobj_sp = m_backend.GetSP(); +  if (!valobj_sp)      return false; +  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); +  ValueObjectSP size_sp( +      valobj_sp->GetChildMemberWithName(ConstString("__size_"), true)); +  if (!size_sp) +    return false; +  m_count = size_sp->GetValueAsUnsigned(0); +  if (!m_count) +    return true; +  ValueObjectSP begin_sp( +      valobj_sp->GetChildMemberWithName(ConstString("__begin_"), true)); +  if (!begin_sp) { +    m_count = 0; +    return false; +  } +  m_base_data_address = begin_sp->GetValueAsUnsigned(0); +  if (!m_base_data_address) { +    m_count = 0; +    return false; +  } +  return false;  } -bool -lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::MightHaveChildren () -{ -    return true; +bool lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd:: +    MightHaveChildren() { +  return true;  } -size_t -lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) -{ -    if (!m_count || !m_base_data_address) -        return UINT32_MAX; -    const char* item_name = name.GetCString(); -    uint32_t idx = ExtractIndexFromString(item_name); -    if (idx < UINT32_MAX && idx >= CalculateNumChildren()) -        return UINT32_MAX; -    return idx; +size_t lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd:: +    GetIndexOfChildWithName(const ConstString &name) { +  if (!m_count || !m_base_data_address) +    return UINT32_MAX; +  const char *item_name = name.GetCString(); +  uint32_t idx = ExtractIndexFromString(item_name); +  if (idx < UINT32_MAX && idx >= CalculateNumChildren()) +    return UINT32_MAX; +  return idx;  } -lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::~LibcxxVectorBoolSyntheticFrontEnd() = default; +lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd:: +    ~LibcxxVectorBoolSyntheticFrontEnd() = default; -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    return (valobj_sp ? new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp) : nullptr); +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp) +                    : nullptr);  }  /*   (lldb) fr var ibeg --raw --ptr-depth 1 - (std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::pair<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, void *> *, long> >) ibeg = { + (std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int, + std::__1::basic_string<char, std::__1::char_traits<char>, + std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::pair<int, + std::__1::basic_string<char, std::__1::char_traits<char>, + std::__1::allocator<char> > >, void *> *, long> >) ibeg = {   __i_ = {   __ptr_ = 0x0000000100103870 {   std::__1::__tree_node_base<void *> = { @@ -238,82 +247,144 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator (CXXSynthetic   second = { std::string }   */ -lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::LibCxxMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_pair_ptr() -{ -    if (valobj_sp) -        Update(); +lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd:: +    LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr(), m_pair_sp() { +  if (valobj_sp) +    Update();  } -bool -lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() -{ -    ValueObjectSP valobj_sp = m_backend.GetSP(); -    if (!valobj_sp) -        return false; -     -    TargetSP target_sp(valobj_sp->GetTargetSP()); -     -    if (!target_sp) -        return false; +bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { +  m_pair_sp.reset(); +  m_pair_ptr = nullptr; -    if (!valobj_sp) -        return false; +  ValueObjectSP valobj_sp = m_backend.GetSP(); +  if (!valobj_sp) +    return false; + +  TargetSP target_sp(valobj_sp->GetTargetSP()); -    // this must be a ValueObject* because it is a child of the ValueObject we are producing children for -    // it if were a ValueObjectSP, we would end up with a loop (iterator -> synthetic -> child -> parent == iterator) -    // and that would in turn leak memory by never allowing the ValueObjects to die and free their memory -    m_pair_ptr = valobj_sp->GetValueForExpressionPath(".__i_.__ptr_->__value_", -                                                      nullptr, -                                                      nullptr, -                                                      nullptr, -                                                      ValueObject::GetValueForExpressionPathOptions().DontCheckDotVsArrowSyntax().SetSyntheticChildrenTraversal(ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None), -                                                      nullptr).get(); -     +  if (!target_sp)      return false; + +  if (!valobj_sp) +    return false; +   +  static ConstString g___i_("__i_"); +   +  // this must be a ValueObject* because it is a child of the ValueObject we are +  // producing children for +  // it if were a ValueObjectSP, we would end up with a loop (iterator -> +  // synthetic -> child -> parent == iterator) +  // and that would in turn leak memory by never allowing the ValueObjects to +  // die and free their memory +  m_pair_ptr = valobj_sp +                   ->GetValueForExpressionPath( +                       ".__i_.__ptr_->__value_", nullptr, nullptr, +                       ValueObject::GetValueForExpressionPathOptions() +                           .DontCheckDotVsArrowSyntax() +                           .SetSyntheticChildrenTraversal( +                               ValueObject::GetValueForExpressionPathOptions:: +                                   SyntheticChildrenTraversal::None), +                       nullptr) +                   .get(); + +  if (!m_pair_ptr) { +    m_pair_ptr = valobj_sp +                     ->GetValueForExpressionPath( +                         ".__i_.__ptr_", nullptr, nullptr, +                         ValueObject::GetValueForExpressionPathOptions() +                             .DontCheckDotVsArrowSyntax() +                             .SetSyntheticChildrenTraversal( +                                 ValueObject::GetValueForExpressionPathOptions:: +                                     SyntheticChildrenTraversal::None), +                         nullptr) +                     .get(); +    if (m_pair_ptr) { +      auto __i_(valobj_sp->GetChildMemberWithName(g___i_, true)); +      lldb::TemplateArgumentKind kind; +      if (!__i_) { +        m_pair_ptr = nullptr; +        return false; +      } +      CompilerType pair_type(__i_->GetCompilerType().GetTemplateArgument(0, kind)); +      std::string name; uint64_t bit_offset_ptr; uint32_t bitfield_bit_size_ptr; bool is_bitfield_ptr; +      pair_type = pair_type.GetFieldAtIndex(0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr); +      if (!pair_type) { +        m_pair_ptr = nullptr; +        return false; +      } +       +      auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS)); +      m_pair_ptr = nullptr; +      if (addr && addr!=LLDB_INVALID_ADDRESS) { +        ClangASTContext *ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(pair_type.GetTypeSystem()); +        if (!ast_ctx) +          return false; +        CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(ConstString(), { +          {"ptr0",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, +          {"ptr1",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, +          {"ptr2",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, +          {"cw",ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, +          {"payload",pair_type} +        }); +        DataBufferSP buffer_sp(new DataBufferHeap(tree_node_type.GetByteSize(nullptr),0)); +        ProcessSP process_sp(target_sp->GetProcessSP()); +        Error error; +        process_sp->ReadMemory(addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), error); +        if (error.Fail()) +          return false; +        DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); +        auto pair_sp = CreateValueObjectFromData("pair", extractor, valobj_sp->GetExecutionContextRef(), tree_node_type); +        if (pair_sp) +          m_pair_sp = pair_sp->GetChildAtIndex(4,true); +      } +    } +  } + +  return false;  } -size_t -lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::CalculateNumChildren () -{ -    return 2; +size_t lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd:: +    CalculateNumChildren() { +  return 2;  }  lldb::ValueObjectSP -lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx) -{ -    if (!m_pair_ptr) -        return lldb::ValueObjectSP(); +lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetChildAtIndex( +    size_t idx) { +  if (m_pair_ptr)      return m_pair_ptr->GetChildAtIndex(idx, true); +  if (m_pair_sp) +    return m_pair_sp->GetChildAtIndex(idx, true); +  return lldb::ValueObjectSP();  } -bool -lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::MightHaveChildren () -{ -    return true; +bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd:: +    MightHaveChildren() { +  return true;  } -size_t -lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) -{ -    if (name == ConstString("first")) -        return 0; -    if (name == ConstString("second")) -        return 1; -    return UINT32_MAX; +size_t lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd:: +    GetIndexOfChildWithName(const ConstString &name) { +  if (name == ConstString("first")) +    return 0; +  if (name == ConstString("second")) +    return 1; +  return UINT32_MAX;  } -lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::~LibCxxMapIteratorSyntheticFrontEnd () -{ -    // this will be deleted when its parent dies (since it's a child object) -    //delete m_pair_ptr; +lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd:: +    ~LibCxxMapIteratorSyntheticFrontEnd() { +  // this will be deleted when its parent dies (since it's a child object) +  // delete m_pair_ptr;  } -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    return (valobj_sp ? new LibCxxMapIteratorSyntheticFrontEnd(valobj_sp) : nullptr); +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibCxxMapIteratorSyntheticFrontEnd(valobj_sp) +                    : nullptr);  }  /* @@ -325,323 +396,341 @@ lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheti   }  */ -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    static ConstString g_item_name; -    if (!g_item_name) -        g_item_name.SetCString("__i"); -    return (valobj_sp ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name) : nullptr); +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  static ConstString g_item_name; +  if (!g_item_name) +    g_item_name.SetCString("__i"); +  return (valobj_sp +              ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name) +              : nullptr);  } -lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_cntrl(nullptr), -    m_count_sp(), -    m_weak_count_sp(), -    m_ptr_size(0), -    m_byte_order(lldb::eByteOrderInvalid) -{ -    if (valobj_sp) -        Update(); +lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: +    LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr), m_count_sp(), +      m_weak_count_sp(), m_ptr_size(0), m_byte_order(lldb::eByteOrderInvalid) { +  if (valobj_sp) +    Update();  } -size_t -lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::CalculateNumChildren () -{ -    return (m_cntrl ? 1 : 0); +size_t lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: +    CalculateNumChildren() { +  return (m_cntrl ? 1 : 0);  }  lldb::ValueObjectSP -lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex (size_t idx) -{ -    if (!m_cntrl) -        return lldb::ValueObjectSP(); - -    ValueObjectSP valobj_sp = m_backend.GetSP(); -    if (!valobj_sp) +lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex( +    size_t idx) { +  if (!m_cntrl) +    return lldb::ValueObjectSP(); + +  ValueObjectSP valobj_sp = m_backend.GetSP(); +  if (!valobj_sp) +    return lldb::ValueObjectSP(); + +  if (idx == 0) +    return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true); + +  if (idx > 2) +    return lldb::ValueObjectSP(); + +  if (idx == 1) { +    if (!m_count_sp) { +      ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName( +          ConstString("__shared_owners_"), true)); +      if (!shared_owners_sp)          return lldb::ValueObjectSP(); - -    if (idx == 0) -        return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true); - -    if (idx > 2) -        return lldb::ValueObjectSP(); - -    if (idx == 1) -    { -        if (!m_count_sp) -        { -            ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName(ConstString("__shared_owners_"),true)); -            if (!shared_owners_sp) -                return lldb::ValueObjectSP(); -            uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0); -            DataExtractor data(&count, 8, m_byte_order, m_ptr_size); -            m_count_sp = CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), shared_owners_sp->GetCompilerType()); -        } -        return m_count_sp; +      uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0); +      DataExtractor data(&count, 8, m_byte_order, m_ptr_size); +      m_count_sp = CreateValueObjectFromData( +          "count", data, valobj_sp->GetExecutionContextRef(), +          shared_owners_sp->GetCompilerType());      } -    else /* if (idx == 2) */ -    { -        if (!m_weak_count_sp) -        { -            ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName(ConstString("__shared_weak_owners_"),true)); -            if (!shared_weak_owners_sp) -                return lldb::ValueObjectSP(); -            uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0); -            DataExtractor data(&count, 8, m_byte_order, m_ptr_size); -            m_weak_count_sp = CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), shared_weak_owners_sp->GetCompilerType()); -        } -        return m_weak_count_sp; +    return m_count_sp; +  } else /* if (idx == 2) */ +  { +    if (!m_weak_count_sp) { +      ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName( +          ConstString("__shared_weak_owners_"), true)); +      if (!shared_weak_owners_sp) +        return lldb::ValueObjectSP(); +      uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0); +      DataExtractor data(&count, 8, m_byte_order, m_ptr_size); +      m_weak_count_sp = CreateValueObjectFromData( +          "count", data, valobj_sp->GetExecutionContextRef(), +          shared_weak_owners_sp->GetCompilerType());      } +    return m_weak_count_sp; +  }  } -bool -lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() -{ -    m_count_sp.reset(); -    m_weak_count_sp.reset(); -    m_cntrl = nullptr; -     -    ValueObjectSP valobj_sp = m_backend.GetSP(); -    if (!valobj_sp) -        return false; -     -    TargetSP target_sp(valobj_sp->GetTargetSP()); -    if (!target_sp) -        return false; -     -    m_byte_order = target_sp->GetArchitecture().GetByteOrder(); -    m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize(); -     -    lldb::ValueObjectSP cntrl_sp(valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"),true)); -     -    m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular dependency +bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() { +  m_count_sp.reset(); +  m_weak_count_sp.reset(); +  m_cntrl = nullptr; + +  ValueObjectSP valobj_sp = m_backend.GetSP(); +  if (!valobj_sp) +    return false; + +  TargetSP target_sp(valobj_sp->GetTargetSP()); +  if (!target_sp)      return false; + +  m_byte_order = target_sp->GetArchitecture().GetByteOrder(); +  m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize(); + +  lldb::ValueObjectSP cntrl_sp( +      valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"), true)); + +  m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular +                            // dependency +  return false;  } -bool -lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::MightHaveChildren () -{ -    return true; +bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: +    MightHaveChildren() { +  return true;  } -size_t -lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) -{ -    if (name == ConstString("__ptr_")) -        return 0; -    if (name == ConstString("count")) -        return 1; -    if (name == ConstString("weak_count")) -        return 2; -    return UINT32_MAX; +size_t lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: +    GetIndexOfChildWithName(const ConstString &name) { +  if (name == ConstString("__ptr_")) +    return 0; +  if (name == ConstString("count")) +    return 1; +  if (name == ConstString("weak_count")) +    return 2; +  return UINT32_MAX;  } -lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::~LibcxxSharedPtrSyntheticFrontEnd() = default; +lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: +    ~LibcxxSharedPtrSyntheticFrontEnd() = default; -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    return (valobj_sp ? new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp) : nullptr); +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp) +                    : nullptr);  } -bool -lldb_private::formatters::LibcxxContainerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) -{ -    if (valobj.IsPointerType()) -    { -        uint64_t value = valobj.GetValueAsUnsigned(0); -        if (!value) -            return false; -        stream.Printf("0x%016" PRIx64 " ", value); -    } -    return FormatEntity::FormatStringRef("size=${svar%#}", stream, nullptr, nullptr, nullptr, &valobj, false, false); +bool lldb_private::formatters::LibcxxContainerSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { +  if (valobj.IsPointerType()) { +    uint64_t value = valobj.GetValueAsUnsigned(0); +    if (!value) +      return false; +    stream.Printf("0x%016" PRIx64 " ", value); +  } +  return FormatEntity::FormatStringRef("size=${svar%#}", stream, nullptr, +                                       nullptr, nullptr, &valobj, false, false);  }  // the field layout in a libc++ string (cap, side, data or data, size, cap) -enum LibcxxStringLayoutMode -{ -    eLibcxxStringLayoutModeCSD = 0, -    eLibcxxStringLayoutModeDSC = 1, -    eLibcxxStringLayoutModeInvalid = 0xffff +enum LibcxxStringLayoutMode { +  eLibcxxStringLayoutModeCSD = 0, +  eLibcxxStringLayoutModeDSC = 1, +  eLibcxxStringLayoutModeInvalid = 0xffff  };  // this function abstracts away the layout and mode details of a libc++ string  // and returns the address of the data and the size ready for callers to consume -static bool -ExtractLibcxxStringInfo (ValueObject& valobj, -                         ValueObjectSP &location_sp, -                         uint64_t& size) -{ -    ValueObjectSP D(valobj.GetChildAtIndexPath({0,0,0,0})); -    if (!D) -        return false; -     -    ValueObjectSP layout_decider(D->GetChildAtIndexPath({0,0})); -     -    // this child should exist -    if (!layout_decider) +static bool ExtractLibcxxStringInfo(ValueObject &valobj, +                                    ValueObjectSP &location_sp, +                                    uint64_t &size) { +  ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0})); +  if (!D) +    return false; + +  ValueObjectSP layout_decider(D->GetChildAtIndexPath({0, 0})); + +  // this child should exist +  if (!layout_decider) +    return false; + +  ConstString g_data_name("__data_"); +  ConstString g_size_name("__size_"); +  bool short_mode = false; // this means the string is in short-mode and the +                           // data is stored inline +  LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name) +                                      ? eLibcxxStringLayoutModeDSC +                                      : eLibcxxStringLayoutModeCSD; +  uint64_t size_mode_value = 0; + +  if (layout == eLibcxxStringLayoutModeDSC) { +    ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0})); +    if (!size_mode) +      return false; + +    if (size_mode->GetName() != g_size_name) { +      // we are hitting the padding structure, move along +      size_mode = D->GetChildAtIndexPath({1, 1, 1}); +      if (!size_mode)          return false; -     -    ConstString g_data_name("__data_"); -    ConstString g_size_name("__size_"); -    bool short_mode = false; // this means the string is in short-mode and the data is stored inline -    LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name) ? eLibcxxStringLayoutModeDSC : eLibcxxStringLayoutModeCSD; -    uint64_t size_mode_value = 0; -     -    if (layout == eLibcxxStringLayoutModeDSC) -    { -        ValueObjectSP size_mode(D->GetChildAtIndexPath({1,1,0})); -        if (!size_mode) -            return false; -         -        if (size_mode->GetName() != g_size_name) -        { -            // we are hitting the padding structure, move along -            size_mode = D->GetChildAtIndexPath({1,1,1}); -            if (!size_mode) -                return false; -        } -         -        size_mode_value = (size_mode->GetValueAsUnsigned(0)); -        short_mode = ((size_mode_value & 0x80) == 0); -    } -    else -    { -        ValueObjectSP size_mode(D->GetChildAtIndexPath({1,0,0})); -        if (!size_mode) -            return false; -         -        size_mode_value = (size_mode->GetValueAsUnsigned(0)); -        short_mode = ((size_mode_value & 1) == 0); -    } -     -    if (short_mode) -    { -        ValueObjectSP s(D->GetChildAtIndex(1, true)); -        if (!s) -            return false; -        location_sp = s->GetChildAtIndex((layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true); -        size = (layout == eLibcxxStringLayoutModeDSC) ? size_mode_value : ((size_mode_value >> 1) % 256); -        return (location_sp.get() != nullptr); -    } -    else -    { -        ValueObjectSP l(D->GetChildAtIndex(0, true)); -        if (!l) -            return false; -        // we can use the layout_decider object as the data pointer -        location_sp = (layout == eLibcxxStringLayoutModeDSC) ? layout_decider : l->GetChildAtIndex(2, true); -        ValueObjectSP size_vo(l->GetChildAtIndex(1, true)); -        if (!size_vo || !location_sp) -            return false; -        size = size_vo->GetValueAsUnsigned(0); -        return true;      } + +    size_mode_value = (size_mode->GetValueAsUnsigned(0)); +    short_mode = ((size_mode_value & 0x80) == 0); +  } else { +    ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0})); +    if (!size_mode) +      return false; + +    size_mode_value = (size_mode->GetValueAsUnsigned(0)); +    short_mode = ((size_mode_value & 1) == 0); +  } + +  if (short_mode) { +    ValueObjectSP s(D->GetChildAtIndex(1, true)); +    if (!s) +      return false; +    location_sp = s->GetChildAtIndex( +        (layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true); +    size = (layout == eLibcxxStringLayoutModeDSC) +               ? size_mode_value +               : ((size_mode_value >> 1) % 256); +    return (location_sp.get() != nullptr); +  } else { +    ValueObjectSP l(D->GetChildAtIndex(0, true)); +    if (!l) +      return false; +    // we can use the layout_decider object as the data pointer +    location_sp = (layout == eLibcxxStringLayoutModeDSC) +                      ? layout_decider +                      : l->GetChildAtIndex(2, true); +    ValueObjectSP size_vo(l->GetChildAtIndex(1, true)); +    if (!size_vo || !location_sp) +      return false; +    size = size_vo->GetValueAsUnsigned(0); +    return true; +  }  } -bool -lldb_private::formatters::LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options) -{ -    uint64_t size = 0; -    ValueObjectSP location_sp; -    if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) -        return false; -    if (size == 0) -    { -        stream.Printf("L\"\""); -        return true; -    } -    if (!location_sp) -        return false; -     -    DataExtractor extractor; -     -    StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); -     -    if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) -    { -        const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); -        if (size > max_size) -        { -            size = max_size; -            options.SetIsTruncated(true); -        } -    } -    location_sp->GetPointeeData(extractor, 0, size); -     -    // std::wstring::size() is measured in 'characters', not bytes -    auto wchar_t_size = valobj.GetTargetSP()->GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeWChar).GetByteSize(nullptr); -     -    options.SetData(extractor); -    options.SetStream(&stream); -    options.SetPrefixToken("L"); -    options.SetQuote('"'); -    options.SetSourceSize(size); -    options.SetBinaryZeroIsTerminator(false); -     -    switch (wchar_t_size) -    { -        case 1: -            StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::UTF8>(options); -            break; -             -        case 2: -            lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::UTF16>(options); -            break; -             -        case 4: -            lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::UTF32>(options); -            break; -             -        default: -            stream.Printf("size for wchar_t is not valid"); -            return true; +bool lldb_private::formatters::LibcxxWStringSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &summary_options) { +  uint64_t size = 0; +  ValueObjectSP location_sp; +  if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) +    return false; +  if (size == 0) { +    stream.Printf("L\"\""); +    return true; +  } +  if (!location_sp) +    return false; + +  DataExtractor extractor; + +  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); + +  if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { +    const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); +    if (size > max_size) { +      size = max_size; +      options.SetIsTruncated(true);      } -     +  } +  location_sp->GetPointeeData(extractor, 0, size); + +  // std::wstring::size() is measured in 'characters', not bytes +  auto wchar_t_size = valobj.GetTargetSP() +                          ->GetScratchClangASTContext() +                          ->GetBasicType(lldb::eBasicTypeWChar) +                          .GetByteSize(nullptr); + +  options.SetData(extractor); +  options.SetStream(&stream); +  options.SetPrefixToken("L"); +  options.SetQuote('"'); +  options.SetSourceSize(size); +  options.SetBinaryZeroIsTerminator(false); + +  switch (wchar_t_size) { +  case 1: +    StringPrinter::ReadBufferAndDumpToStream< +        lldb_private::formatters::StringPrinter::StringElementType::UTF8>( +        options); +    break; + +  case 2: +    lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream< +        lldb_private::formatters::StringPrinter::StringElementType::UTF16>( +        options); +    break; + +  case 4: +    lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream< +        lldb_private::formatters::StringPrinter::StringElementType::UTF32>( +        options); +    break; + +  default: +    stream.Printf("size for wchar_t is not valid");      return true; +  } + +  return true;  } -bool -lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options) -{ -    uint64_t size = 0; -    ValueObjectSP location_sp; -     -    if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) -        return false; -     -    if (size == 0) -    { -        stream.Printf("\"\""); -        return true; -    } -     -    if (!location_sp) -        return false; -     -    StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); -     -    DataExtractor extractor; -    if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) -    { -        const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); -        if (size > max_size) -        { -            size = max_size; -            options.SetIsTruncated(true); -        } -    } -    location_sp->GetPointeeData(extractor, 0, size); -     -    options.SetData(extractor); -    options.SetStream(&stream); -    options.SetPrefixToken(nullptr); -    options.SetQuote('"'); -    options.SetSourceSize(size); -    options.SetBinaryZeroIsTerminator(false); -    StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::ASCII>(options); -     +bool lldb_private::formatters::LibcxxStringSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &summary_options) { +  uint64_t size = 0; +  ValueObjectSP location_sp; + +  if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) +    return false; + +  if (size == 0) { +    stream.Printf("\"\"");      return true; +  } + +  if (!location_sp) +    return false; + +  StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); + +  DataExtractor extractor; +  if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { +    const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); +    if (size > max_size) { +      size = max_size; +      options.SetIsTruncated(true); +    } +  } +  location_sp->GetPointeeData(extractor, 0, size); + +  options.SetData(extractor); +  options.SetStream(&stream); +  options.SetPrefixToken(nullptr); +  options.SetQuote('"'); +  options.SetSourceSize(size); +  options.SetBinaryZeroIsTerminator(false); +  StringPrinter::ReadBufferAndDumpToStream< +      StringPrinter::StringElementType::ASCII>(options); + +  return true; +} + +class LibcxxFunctionFrontEnd : public SyntheticValueProviderFrontEnd { +public: +  LibcxxFunctionFrontEnd(ValueObject &backend) +      : SyntheticValueProviderFrontEnd(backend) {} + +  lldb::ValueObjectSP GetSyntheticValue() override { +    static ConstString g___f_("__f_"); +    return m_backend.GetChildMemberWithName(g___f_, true); +  } +}; + +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxFunctionFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  if (valobj_sp) +    return new LibcxxFunctionFrontEnd(*valobj_sp); +  return nullptr;  } diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.h b/source/Plugins/Language/CPlusPlus/LibCxx.h index ae00bc0ade34..a8638513376c 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -1,4 +1,5 @@ -//===-- LibCxx.h ---------------------------------------------------*- C++ -*-===// +//===-- LibCxx.h ---------------------------------------------------*- C++ +//-*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -16,126 +17,133 @@  #include "lldb/DataFormatters/TypeSynthetic.h"  namespace lldb_private { -    namespace formatters -    { -         -        bool -        LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::string -         -        bool -        LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::wstring -         -        bool -        LibcxxSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::shared_ptr<> and std::weak_ptr<> -         -        class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd -        { -        public: -            LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); -             -            size_t -            CalculateNumChildren() override; -             -            lldb::ValueObjectSP -            GetChildAtIndex(size_t idx) override; -             -            bool -            Update() override; -             -            bool -            MightHaveChildren() override; -             -            size_t -            GetIndexOfChildWithName(const ConstString &name) override; -             -            ~LibcxxVectorBoolSyntheticFrontEnd() override; -             -        private: -            CompilerType m_bool_type; -            ExecutionContextRef m_exe_ctx_ref; -            uint64_t m_count; -            lldb::addr_t m_base_data_address; -            std::map<size_t,lldb::ValueObjectSP> m_children; -        }; -         -        SyntheticChildrenFrontEnd* LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); -         -        bool -        LibcxxContainerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); -         -        class LibCxxMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd -        { -        public: -            LibCxxMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); -             -            size_t -            CalculateNumChildren() override; -             -            lldb::ValueObjectSP -            GetChildAtIndex(size_t idx) override; -             -            bool -            Update() override; -             -            bool -            MightHaveChildren() override; -             -            size_t -            GetIndexOfChildWithName(const ConstString &name) override; -             -            ~LibCxxMapIteratorSyntheticFrontEnd() override; -             -        private: -            ValueObject *m_pair_ptr; -        }; -         -        SyntheticChildrenFrontEnd* LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); -         -        SyntheticChildrenFrontEnd* LibCxxVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); -         -        class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd -        { -        public: -            LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); -             -            size_t -            CalculateNumChildren() override; -             -            lldb::ValueObjectSP -            GetChildAtIndex(size_t idx) override; -             -            bool -            Update() override; -             -            bool -            MightHaveChildren() override; -             -            size_t -            GetIndexOfChildWithName(const ConstString &name) override; -             -            ~LibcxxSharedPtrSyntheticFrontEnd() override; -             -        private: -            ValueObject* m_cntrl; -            lldb::ValueObjectSP m_count_sp; -            lldb::ValueObjectSP m_weak_count_sp; -            uint8_t m_ptr_size; -            lldb::ByteOrder m_byte_order; -        }; -         -        SyntheticChildrenFrontEnd* LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); -         -        SyntheticChildrenFrontEnd* LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); -         -        SyntheticChildrenFrontEnd* LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); -         -        SyntheticChildrenFrontEnd* LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); -         -        SyntheticChildrenFrontEnd* LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); -         -        SyntheticChildrenFrontEnd* LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); - -    } // namespace formatters +namespace formatters { + +bool LibcxxStringSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &options); // libc++ std::string + +bool LibcxxWStringSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &options); // libc++ std::wstring + +bool LibcxxSmartPointerSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions +        &options); // libc++ std::shared_ptr<> and std::weak_ptr<> + +class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: +  LibcxxVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +  ~LibcxxVectorBoolSyntheticFrontEnd() override; + +private: +  CompilerType m_bool_type; +  ExecutionContextRef m_exe_ctx_ref; +  uint64_t m_count; +  lldb::addr_t m_base_data_address; +  std::map<size_t, lldb::ValueObjectSP> m_children; +}; + +SyntheticChildrenFrontEnd * +LibcxxVectorBoolSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                         lldb::ValueObjectSP); + +bool LibcxxContainerSummaryProvider(ValueObject &valobj, Stream &stream, +                                    const TypeSummaryOptions &options); + +class LibCxxMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: +  LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +  ~LibCxxMapIteratorSyntheticFrontEnd() override; + +private: +  ValueObject *m_pair_ptr; +  lldb::ValueObjectSP m_pair_sp; +}; + +SyntheticChildrenFrontEnd * +LibCxxMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                          lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * +LibCxxVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                             lldb::ValueObjectSP); + +class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: +  LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +  ~LibcxxSharedPtrSyntheticFrontEnd() override; + +private: +  ValueObject *m_cntrl; +  lldb::ValueObjectSP m_count_sp; +  lldb::ValueObjectSP m_weak_count_sp; +  uint8_t m_ptr_size; +  lldb::ByteOrder m_byte_order; +}; + +SyntheticChildrenFrontEnd * +LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                        lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * +LibcxxStdVectorSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                        lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * +LibcxxStdListSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                      lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * +LibcxxStdMapSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                     lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * +LibcxxStdUnorderedMapSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                              lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * +LibcxxInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                              lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd *LibcxxFunctionFrontEndCreator(CXXSyntheticChildren *, +                                                         lldb::ValueObjectSP); + +} // namespace formatters  } // namespace lldb_private  #endif // liblldb_LibCxx_h_ diff --git a/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp index a20d7f7d9871..dea52e2f30b6 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp @@ -1,4 +1,5 @@ -//===-- LibCxxAtomic.cpp ------------------------------------------*- C++ -*-===// +//===-- LibCxxAtomic.cpp ------------------------------------------*- C++ +//-*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -13,109 +14,92 @@ using namespace lldb;  using namespace lldb_private;  using namespace lldb_private::formatters; -bool -lldb_private::formatters::LibCxxAtomicSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) -{ -    static ConstString g___a_("__a_"); -     -    if (ValueObjectSP child = valobj.GetChildMemberWithName(g___a_, true)) -    { -        std::string summary; -        if (child->GetSummaryAsCString(summary, options) && summary.size() > 0) -        { -            stream.Printf("%s", summary.c_str()); -            return true; -        } +bool lldb_private::formatters::LibCxxAtomicSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { +  static ConstString g___a_("__a_"); + +  if (ValueObjectSP child = valobj.GetChildMemberWithName(g___a_, true)) { +    std::string summary; +    if (child->GetSummaryAsCString(summary, options) && summary.size() > 0) { +      stream.Printf("%s", summary.c_str()); +      return true;      } -     -    return false; +  } + +  return false;  }  namespace lldb_private { -    namespace formatters { -        class LibcxxStdAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd -        { -        public: -            LibcxxStdAtomicSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); -             -            ~LibcxxStdAtomicSyntheticFrontEnd() override = default; -             -            size_t -            CalculateNumChildren() override; -             -            lldb::ValueObjectSP -            GetChildAtIndex(size_t idx) override; -             -            bool -            Update() override; -             -            bool -            MightHaveChildren() override; -             -            size_t -            GetIndexOfChildWithName(const ConstString &name) override; -             -            lldb::ValueObjectSP -            GetSyntheticValue () override; -        private: -            ValueObject *m_real_child; -        }; -    } // namespace formatters +namespace formatters { +class LibcxxStdAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: +  LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  ~LibcxxStdAtomicSyntheticFrontEnd() override = default; + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +  lldb::ValueObjectSP GetSyntheticValue() override; + +private: +  ValueObject *m_real_child; +}; +} // namespace formatters  } // namespace lldb_private -lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::LibcxxStdAtomicSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_real_child(nullptr) -{ -} +lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: +    LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_real_child(nullptr) {} -bool -lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::Update() -{ -    static ConstString g___a_("__a_"); +bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::Update() { +  static ConstString g___a_("__a_"); -    m_real_child = m_backend.GetChildMemberWithName(g___a_, true).get(); -     -    return false; +  m_real_child = m_backend.GetChildMemberWithName(g___a_, true).get(); + +  return false;  } -bool -lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::MightHaveChildren() -{ -    return true; +bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: +    MightHaveChildren() { +  return true;  } -size_t -lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::CalculateNumChildren() -{ -    return m_real_child ? m_real_child->GetNumChildren() : 0; +size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: +    CalculateNumChildren() { +  return m_real_child ? m_real_child->GetNumChildren() : 0;  }  lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex(size_t idx) -{ -    return m_real_child ? m_real_child->GetChildAtIndex(idx, true) : nullptr; +lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex( +    size_t idx) { +  return m_real_child ? m_real_child->GetChildAtIndex(idx, true) : nullptr;  } -size_t -lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name) -{ -    return m_real_child ? m_real_child->GetIndexOfChildWithName(name) : UINT32_MAX; +size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: +    GetIndexOfChildWithName(const ConstString &name) { +  return m_real_child ? m_real_child->GetIndexOfChildWithName(name) +                      : UINT32_MAX;  } -lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetSyntheticValue () -{ -    if (m_real_child && m_real_child->CanProvideValue()) -        return m_real_child->GetSP(); -    return nullptr; +lldb::ValueObjectSP lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: +    GetSyntheticValue() { +  if (m_real_child && m_real_child->CanProvideValue()) +    return m_real_child->GetSP(); +  return nullptr;  } -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    if (valobj_sp) -        return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp); -    return nullptr; +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  if (valobj_sp) +    return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp); +  return nullptr;  } - diff --git a/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h index 5cf729bfa45f..e2cc01150a2e 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h +++ b/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h @@ -1,4 +1,5 @@ -//===-- LibCxxAtomic.h -------------------------------------------*- C++ -*-===// +//===-- LibCxxAtomic.h -------------------------------------------*- C++ +//-*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -16,14 +17,15 @@  #include "lldb/DataFormatters/TypeSynthetic.h"  namespace lldb_private { -    namespace formatters -    { -        bool -        LibCxxAtomicSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); -         -        SyntheticChildrenFrontEnd* LibcxxAtomicSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); -         -    } // namespace formatters +namespace formatters { +bool LibCxxAtomicSummaryProvider(ValueObject &valobj, Stream &stream, +                                 const TypeSummaryOptions &options); + +SyntheticChildrenFrontEnd * +LibcxxAtomicSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                     lldb::ValueObjectSP); + +} // namespace formatters  } // namespace lldb_private  #endif // liblldb_LibCxxAtomic_h_ diff --git a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp index 54fddd15dd0b..b7aa70c0d2e7 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp @@ -22,115 +22,108 @@ using namespace lldb_private;  using namespace lldb_private::formatters;  namespace lldb_private { -    namespace formatters { -        class LibcxxInitializerListSyntheticFrontEnd : public SyntheticChildrenFrontEnd -        { -        public: -            LibcxxInitializerListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - -            ~LibcxxInitializerListSyntheticFrontEnd() override; - -            size_t -            CalculateNumChildren() override; -             -            lldb::ValueObjectSP -            GetChildAtIndex(size_t idx) override; -             -            bool -            Update() override; -             -            bool -            MightHaveChildren() override; -             -            size_t -            GetIndexOfChildWithName(const ConstString &name) override; -             -        private: -            ValueObject* m_start; -            CompilerType m_element_type; -            uint32_t m_element_size; -            size_t m_num_elements; -        }; -    } // namespace formatters +namespace formatters { +class LibcxxInitializerListSyntheticFrontEnd +    : public SyntheticChildrenFrontEnd { +public: +  LibcxxInitializerListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  ~LibcxxInitializerListSyntheticFrontEnd() override; + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +private: +  ValueObject *m_start; +  CompilerType m_element_type; +  uint32_t m_element_size; +  size_t m_num_elements; +}; +} // namespace formatters  } // namespace lldb_private -lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::LibcxxInitializerListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_start(nullptr), -    m_element_type(), -    m_element_size(0), -    m_num_elements(0) -{ -    if (valobj_sp) -        Update(); +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: +    LibcxxInitializerListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_start(nullptr), m_element_type(), +      m_element_size(0), m_num_elements(0) { +  if (valobj_sp) +    Update();  } -lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::~LibcxxInitializerListSyntheticFrontEnd() -{ -    // this needs to stay around because it's a child object who will follow its parent's life cycle -    // delete m_start; +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: +    ~LibcxxInitializerListSyntheticFrontEnd() { +  // this needs to stay around because it's a child object who will follow its +  // parent's life cycle +  // delete m_start;  } -size_t -lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::CalculateNumChildren () -{ -    static ConstString g___size_("__size_"); -    m_num_elements = 0; -    ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g___size_, true)); -    if (size_sp) -        m_num_elements = size_sp->GetValueAsUnsigned(0); -    return m_num_elements; +size_t lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: +    CalculateNumChildren() { +  static ConstString g___size_("__size_"); +  m_num_elements = 0; +  ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g___size_, true)); +  if (size_sp) +    m_num_elements = size_sp->GetValueAsUnsigned(0); +  return m_num_elements;  } -lldb::ValueObjectSP -lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::GetChildAtIndex (size_t idx) -{ -    if (!m_start) -        return lldb::ValueObjectSP(); -     -    uint64_t offset = idx * m_element_size; -    offset = offset + m_start->GetValueAsUnsigned(0); -    StreamString name; -    name.Printf("[%" PRIu64 "]", (uint64_t)idx); -    return CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type); +lldb::ValueObjectSP lldb_private::formatters:: +    LibcxxInitializerListSyntheticFrontEnd::GetChildAtIndex(size_t idx) { +  if (!m_start) +    return lldb::ValueObjectSP(); + +  uint64_t offset = idx * m_element_size; +  offset = offset + m_start->GetValueAsUnsigned(0); +  StreamString name; +  name.Printf("[%" PRIu64 "]", (uint64_t)idx); +  return CreateValueObjectFromAddress(name.GetString(), offset, +                                      m_backend.GetExecutionContextRef(), +                                      m_element_type);  } -bool -lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::Update() -{ -    static ConstString g___begin_("__begin_"); - -    m_start = nullptr; -    m_num_elements = 0; -    lldb::TemplateArgumentKind kind; -    m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind); -    if (kind != lldb::eTemplateArgumentKindType || !m_element_type.IsValid()) -        return false; -     -    m_element_size = m_element_type.GetByteSize(nullptr); -     -    if (m_element_size > 0) -        m_start = m_backend.GetChildMemberWithName(g___begin_,true).get(); // store raw pointers or end up with a circular dependency +bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: +    Update() { +  static ConstString g___begin_("__begin_"); +  m_start = nullptr; +  m_num_elements = 0; +  lldb::TemplateArgumentKind kind; +  m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind); +  if (kind != lldb::eTemplateArgumentKindType || !m_element_type.IsValid())      return false; + +  m_element_size = m_element_type.GetByteSize(nullptr); + +  if (m_element_size > 0) +    m_start = +        m_backend.GetChildMemberWithName(g___begin_, true) +            .get(); // store raw pointers or end up with a circular dependency + +  return false;  } -bool -lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::MightHaveChildren () -{ -    return true; +bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: +    MightHaveChildren() { +  return true;  } -size_t -lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) -{ -    if (!m_start) -        return UINT32_MAX; -    return ExtractIndexFromString(name.GetCString()); +size_t lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: +    GetIndexOfChildWithName(const ConstString &name) { +  if (!m_start) +    return UINT32_MAX; +  return ExtractIndexFromString(name.GetCString());  } -lldb_private::SyntheticChildrenFrontEnd* -lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    return (valobj_sp ? new LibcxxInitializerListSyntheticFrontEnd(valobj_sp) : nullptr); +lldb_private::SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibcxxInitializerListSyntheticFrontEnd(valobj_sp) +                    : nullptr);  } diff --git a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp index 35cee566a773..16bd631a6c2f 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp @@ -29,380 +29,331 @@ using namespace lldb_private::formatters;  namespace { -    class ListEntry -    { -    public: -        ListEntry() = default; -        ListEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {} -        ListEntry(const ListEntry& rhs) = default; -        ListEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {} - -        ListEntry -        next () -        { -            if (!m_entry_sp) -                return ListEntry(); -            return ListEntry(m_entry_sp->GetChildAtIndexPath({0,1})); -        } - -        ListEntry -        prev () -        { -            if (!m_entry_sp) -                return ListEntry(); -            return ListEntry(m_entry_sp->GetChildAtIndexPath({0,0})); -        } - -        uint64_t -        value () const -        { -            if (!m_entry_sp) -                return 0; -            return m_entry_sp->GetValueAsUnsigned(0); -        } - -        bool -        null() -        { -            return (value() == 0); -        } - -        explicit operator bool () -        { -            return GetEntry() && !null(); -        } - -        ValueObjectSP -        GetEntry () -        { -            return m_entry_sp; -        } - -        void -        SetEntry (ValueObjectSP entry) -        { -            m_entry_sp = entry; -        } - -        bool -        operator == (const ListEntry& rhs) const -        { -            return value() == rhs.value(); -        } - -        bool -        operator != (const ListEntry& rhs) const -        { -            return !(*this == rhs); -        } - -    private: -        ValueObjectSP m_entry_sp; -    }; -     -    class ListIterator -    { -    public: -        ListIterator() = default; -        ListIterator (ListEntry entry) : m_entry(entry) {} -        ListIterator (ValueObjectSP entry) : m_entry(entry) {} -        ListIterator(const ListIterator& rhs) = default; -        ListIterator (ValueObject* entry) : m_entry(entry) {} -         -        ValueObjectSP -        value () -        { -            return m_entry.GetEntry(); -        } -         -        ValueObjectSP -        advance (size_t count) -        { -            if (count == 0) -                return m_entry.GetEntry(); -            if (count == 1) -            { -                next (); -                return m_entry.GetEntry(); -            } -            while (count > 0) -            { -                next (); -                count--; -                if (m_entry.null()) -                    return lldb::ValueObjectSP(); -            } -            return m_entry.GetEntry(); -        } -         -        bool -        operator == (const ListIterator& rhs) const -        { -            return (rhs.m_entry == m_entry); -        } -         -    protected: -        void -        next () -        { -            m_entry = m_entry.next(); -        } -         -        void -        prev () -        { -            m_entry = m_entry.prev(); -        } -         -    private: -        ListEntry m_entry; -    }; +class ListEntry { +public: +  ListEntry() = default; +  ListEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {} +  ListEntry(const ListEntry &rhs) = default; +  ListEntry(ValueObject *entry) +      : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {} + +  ListEntry next() { +    static ConstString g_next("__next_"); + +    if (!m_entry_sp) +      return ListEntry(); +    return ListEntry(m_entry_sp->GetChildMemberWithName(g_next, true)); +  } + +  ListEntry prev() { +    static ConstString g_prev("__prev_"); + +    if (!m_entry_sp) +      return ListEntry(); +    return ListEntry(m_entry_sp->GetChildMemberWithName(g_prev, true)); +  } + +  uint64_t value() const { +    if (!m_entry_sp) +      return 0; +    return m_entry_sp->GetValueAsUnsigned(0); +  } + +  bool null() { return (value() == 0); } + +  explicit operator bool() { return GetEntry() && !null(); } + +  ValueObjectSP GetEntry() { return m_entry_sp; } + +  void SetEntry(ValueObjectSP entry) { m_entry_sp = entry; } + +  bool operator==(const ListEntry &rhs) const { return value() == rhs.value(); } + +  bool operator!=(const ListEntry &rhs) const { return !(*this == rhs); } + +private: +  ValueObjectSP m_entry_sp; +}; + +class ListIterator { +public: +  ListIterator() = default; +  ListIterator(ListEntry entry) : m_entry(entry) {} +  ListIterator(ValueObjectSP entry) : m_entry(entry) {} +  ListIterator(const ListIterator &rhs) = default; +  ListIterator(ValueObject *entry) : m_entry(entry) {} + +  ValueObjectSP value() { return m_entry.GetEntry(); } + +  ValueObjectSP advance(size_t count) { +    if (count == 0) +      return m_entry.GetEntry(); +    if (count == 1) { +      next(); +      return m_entry.GetEntry(); +    } +    while (count > 0) { +      next(); +      count--; +      if (m_entry.null()) +        return lldb::ValueObjectSP(); +    } +    return m_entry.GetEntry(); +  } + +  bool operator==(const ListIterator &rhs) const { +    return (rhs.m_entry == m_entry); +  } + +protected: +  void next() { m_entry = m_entry.next(); } + +  void prev() { m_entry = m_entry.prev(); } + +private: +  ListEntry m_entry; +};  } // end anonymous namespace  namespace lldb_private { -    namespace formatters { -        class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd -        { -        public: -            LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - -            ~LibcxxStdListSyntheticFrontEnd() override = default; - -            size_t -            CalculateNumChildren() override; -             -            lldb::ValueObjectSP -            GetChildAtIndex(size_t idx) override; -             -            bool -            Update() override; -             -            bool -            MightHaveChildren() override; -             -            size_t -            GetIndexOfChildWithName(const ConstString &name) override; -             -        private: -            bool -            HasLoop(size_t count); -             -            size_t m_list_capping_size; -            static const bool g_use_loop_detect = true; - -            size_t m_loop_detected; // The number of elements that have had loop detection run over them. -            ListEntry m_slow_runner; // Used for loop detection -            ListEntry m_fast_runner; // Used for loop detection - -            lldb::addr_t m_node_address; -            ValueObject* m_head; -            ValueObject* m_tail; -            CompilerType m_element_type; -            size_t m_count; -            std::map<size_t, ListIterator> m_iterators; -        }; -    } // namespace formatters +namespace formatters { +class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: +  LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  ~LibcxxStdListSyntheticFrontEnd() override = default; + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +private: +  bool HasLoop(size_t count); + +  size_t m_list_capping_size; +  static const bool g_use_loop_detect = true; + +  size_t m_loop_detected; // The number of elements that have had loop detection +                          // run over them. +  ListEntry m_slow_runner; // Used for loop detection +  ListEntry m_fast_runner; // Used for loop detection + +  lldb::addr_t m_node_address; +  ValueObject *m_head; +  ValueObject *m_tail; +  CompilerType m_element_type; +  size_t m_count; +  std::map<size_t, ListIterator> m_iterators; +}; +} // namespace formatters  } // namespace lldb_private -lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_list_capping_size(0), -    m_loop_detected(0), -    m_node_address(), -    m_head(nullptr), -    m_tail(nullptr), -    m_element_type(), -    m_count(UINT32_MAX), -    m_iterators() -{ -    if (valobj_sp) -        Update(); +lldb_private::formatters::LibcxxStdListSyntheticFrontEnd:: +    LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_list_capping_size(0), +      m_loop_detected(0), m_node_address(), m_head(nullptr), m_tail(nullptr), +      m_element_type(), m_count(UINT32_MAX), m_iterators() { +  if (valobj_sp) +    Update();  } -bool -lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop(size_t count) -{ -    if (!g_use_loop_detect) -        return false; -    // don't bother checking for a loop if we won't actually need to jump nodes -    if (m_count < 2) -        return false; - -    if (m_loop_detected == 0) -    { -        // This is the first time we are being run (after the last update). Set up the loop -        // invariant for the first element. -        m_slow_runner = ListEntry(m_head).next(); -        m_fast_runner = m_slow_runner.next(); -        m_loop_detected = 1; -    } +bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop( +    size_t count) { +  if (!g_use_loop_detect) +    return false; +  // don't bother checking for a loop if we won't actually need to jump nodes +  if (m_count < 2) +    return false; -    // Loop invariant: -    // Loop detection has been run over the first m_loop_detected elements. If m_slow_runner == -    // m_fast_runner then the loop has been detected after m_loop_detected elements. -    const size_t steps_to_run = std::min(count,m_count); -    while (m_loop_detected < steps_to_run -            && m_slow_runner -            && m_fast_runner -            && m_slow_runner != m_fast_runner) { - -        m_slow_runner = m_slow_runner.next(); -        m_fast_runner = m_fast_runner.next().next(); -        m_loop_detected++; -    } -    if (count <= m_loop_detected) -        return false; // No loop in the first m_loop_detected elements. -    if (!m_slow_runner || !m_fast_runner) -        return false; // Reached the end of the list. Definitely no loops. -    return m_slow_runner == m_fast_runner; +  if (m_loop_detected == 0) { +    // This is the first time we are being run (after the last update). Set up +    // the loop +    // invariant for the first element. +    m_slow_runner = ListEntry(m_head).next(); +    m_fast_runner = m_slow_runner.next(); +    m_loop_detected = 1; +  } + +  // Loop invariant: +  // Loop detection has been run over the first m_loop_detected elements. If +  // m_slow_runner == +  // m_fast_runner then the loop has been detected after m_loop_detected +  // elements. +  const size_t steps_to_run = std::min(count, m_count); +  while (m_loop_detected < steps_to_run && m_slow_runner && m_fast_runner && +         m_slow_runner != m_fast_runner) { + +    m_slow_runner = m_slow_runner.next(); +    m_fast_runner = m_fast_runner.next().next(); +    m_loop_detected++; +  } +  if (count <= m_loop_detected) +    return false; // No loop in the first m_loop_detected elements. +  if (!m_slow_runner || !m_fast_runner) +    return false; // Reached the end of the list. Definitely no loops. +  return m_slow_runner == m_fast_runner;  } -size_t -lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::CalculateNumChildren () -{ -    if (m_count != UINT32_MAX) -        return m_count; -    if (!m_head || !m_tail || m_node_address == 0) -        return 0; -    ValueObjectSP size_alloc(m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true)); -    if (size_alloc) -    { -        ValueObjectSP first(size_alloc->GetChildMemberWithName(ConstString("__first_"), true)); -        if (first) -        { -            m_count = first->GetValueAsUnsigned(UINT32_MAX); -        } +size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd:: +    CalculateNumChildren() { +  if (m_count != UINT32_MAX) +    return m_count; +  if (!m_head || !m_tail || m_node_address == 0) +    return 0; +  ValueObjectSP size_alloc( +      m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true)); +  if (size_alloc) { +    ValueObjectSP first( +        size_alloc->GetChildMemberWithName(ConstString("__first_"), true)); +    if (first) { +      m_count = first->GetValueAsUnsigned(UINT32_MAX);      } -    if (m_count != UINT32_MAX) -    { -        return m_count; -    } -    else -    { -        uint64_t next_val = m_head->GetValueAsUnsigned(0); -        uint64_t prev_val = m_tail->GetValueAsUnsigned(0); -        if (next_val == 0 || prev_val == 0) -            return 0; -        if (next_val == m_node_address) -            return 0; -        if (next_val == prev_val) -            return 1; -        uint64_t size = 2; -        ListEntry current(m_head); -        while (current.next() && current.next().value() != m_node_address) -        { -            size++; -            current = current.next(); -            if (size > m_list_capping_size) -                break; -        } -        return m_count = (size-1); +  } +  if (m_count != UINT32_MAX) { +    return m_count; +  } else { +    uint64_t next_val = m_head->GetValueAsUnsigned(0); +    uint64_t prev_val = m_tail->GetValueAsUnsigned(0); +    if (next_val == 0 || prev_val == 0) +      return 0; +    if (next_val == m_node_address) +      return 0; +    if (next_val == prev_val) +      return 1; +    uint64_t size = 2; +    ListEntry current(m_head); +    while (current.next() && current.next().value() != m_node_address) { +      size++; +      current = current.next(); +      if (size > m_list_capping_size) +        break;      } +    return m_count = (size - 1); +  }  }  lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex (size_t idx) -{ -    if (idx >= CalculateNumChildren()) -        return lldb::ValueObjectSP(); -     -    if (!m_head || !m_tail || m_node_address == 0) -        return lldb::ValueObjectSP(); -     -    if (HasLoop(idx+1)) -        return lldb::ValueObjectSP(); -     -    size_t actual_advance = idx; -     -    ListIterator current(m_head); -    if (idx > 0) -    { -        auto cached_iterator = m_iterators.find(idx-1); -        if (cached_iterator != m_iterators.end()) -        { -            current = cached_iterator->second; -            actual_advance = 1; -        } +lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex( +    size_t idx) { +  static ConstString g_value("__value_"); +  static ConstString g_next("__next_"); + +  if (idx >= CalculateNumChildren()) +    return lldb::ValueObjectSP(); + +  if (!m_head || !m_tail || m_node_address == 0) +    return lldb::ValueObjectSP(); + +  if (HasLoop(idx + 1)) +    return lldb::ValueObjectSP(); + +  size_t actual_advance = idx; + +  ListIterator current(m_head); +  if (idx > 0) { +    auto cached_iterator = m_iterators.find(idx - 1); +    if (cached_iterator != m_iterators.end()) { +      current = cached_iterator->second; +      actual_advance = 1;      } -     -    ValueObjectSP current_sp(current.advance(actual_advance)); -    if (!current_sp) -        return lldb::ValueObjectSP(); -     -    m_iterators[idx] = current; -     -    current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child -    if (!current_sp) -        return lldb::ValueObjectSP(); -    // we need to copy current_sp into a new object otherwise we will end up with all items named __value_ -    DataExtractor data; -    Error error; -    current_sp->GetData(data, error); -    if (error.Fail()) -        return lldb::ValueObjectSP(); -     -    StreamString name; -    name.Printf("[%" PRIu64 "]", (uint64_t)idx); -    return CreateValueObjectFromData(name.GetData(), -                                     data, -                                     m_backend.GetExecutionContextRef(), -                                     m_element_type); +  } + +  ValueObjectSP current_sp(current.advance(actual_advance)); +  if (!current_sp) +    return lldb::ValueObjectSP(); + +  m_iterators[idx] = current; + +  current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child +  if (!current_sp) +    return lldb::ValueObjectSP(); + +  if (current_sp->GetName() == g_next) { +    ProcessSP process_sp(current_sp->GetProcessSP()); +    if (!process_sp) +      return nullptr; + +    // if we grabbed the __next_ pointer, then the child is one pointer deep-er +    lldb::addr_t addr = current_sp->GetParent()->GetPointerValue(); +    addr = addr + 2 * process_sp->GetAddressByteSize(); +    ExecutionContext exe_ctx(process_sp); +    current_sp = +        CreateValueObjectFromAddress("__value_", addr, exe_ctx, m_element_type); +  } + +  // we need to copy current_sp into a new object otherwise we will end up with +  // all items named __value_ +  DataExtractor data; +  Error error; +  current_sp->GetData(data, error); +  if (error.Fail()) +    return lldb::ValueObjectSP(); + +  StreamString name; +  name.Printf("[%" PRIu64 "]", (uint64_t)idx); +  return CreateValueObjectFromData(name.GetString(), data, +                                   m_backend.GetExecutionContextRef(), +                                   m_element_type);  } -bool -lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() -{ -    m_iterators.clear(); -    m_head = m_tail = nullptr; -    m_node_address = 0; -    m_count = UINT32_MAX; -    m_loop_detected = 0; -    m_slow_runner.SetEntry(nullptr); -    m_fast_runner.SetEntry(nullptr); - -    Error err; -    ValueObjectSP backend_addr(m_backend.AddressOf(err)); -    m_list_capping_size = 0; -    if (m_backend.GetTargetSP()) -        m_list_capping_size = m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); -    if (m_list_capping_size == 0) -        m_list_capping_size = 255; -    if (err.Fail() || !backend_addr) -        return false; -    m_node_address = backend_addr->GetValueAsUnsigned(0); -    if (!m_node_address || m_node_address == LLDB_INVALID_ADDRESS) -        return false; -    ValueObjectSP impl_sp(m_backend.GetChildMemberWithName(ConstString("__end_"),true)); -    if (!impl_sp) -        return false; -    CompilerType list_type = m_backend.GetCompilerType(); -    if (list_type.IsReferenceType()) -        list_type = list_type.GetNonReferenceType(); - -    if (list_type.GetNumTemplateArguments() == 0) -        return false; -    lldb::TemplateArgumentKind kind; -    m_element_type = list_type.GetTemplateArgument(0, kind); -    m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get(); -    m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get(); +bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() { +  m_iterators.clear(); +  m_head = m_tail = nullptr; +  m_node_address = 0; +  m_count = UINT32_MAX; +  m_loop_detected = 0; +  m_slow_runner.SetEntry(nullptr); +  m_fast_runner.SetEntry(nullptr); + +  Error err; +  ValueObjectSP backend_addr(m_backend.AddressOf(err)); +  m_list_capping_size = 0; +  if (m_backend.GetTargetSP()) +    m_list_capping_size = +        m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); +  if (m_list_capping_size == 0) +    m_list_capping_size = 255; +  if (err.Fail() || !backend_addr) +    return false; +  m_node_address = backend_addr->GetValueAsUnsigned(0); +  if (!m_node_address || m_node_address == LLDB_INVALID_ADDRESS) +    return false; +  ValueObjectSP impl_sp( +      m_backend.GetChildMemberWithName(ConstString("__end_"), true)); +  if (!impl_sp) +    return false; +  CompilerType list_type = m_backend.GetCompilerType(); +  if (list_type.IsReferenceType()) +    list_type = list_type.GetNonReferenceType(); + +  if (list_type.GetNumTemplateArguments() == 0)      return false; +  lldb::TemplateArgumentKind kind; +  m_element_type = list_type.GetTemplateArgument(0, kind); +  m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get(); +  m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get(); +  return false;  } -bool -lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::MightHaveChildren () -{ -    return true; +bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd:: +    MightHaveChildren() { +  return true;  } -size_t -lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) -{ -    return ExtractIndexFromString(name.GetCString()); +size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd:: +    GetIndexOfChildWithName(const ConstString &name) { +  return ExtractIndexFromString(name.GetCString());  } -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    return (valobj_sp ? new LibcxxStdListSyntheticFrontEnd(valobj_sp) : nullptr); +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibcxxStdListSyntheticFrontEnd(valobj_sp) : nullptr);  } diff --git a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index d89869283cd3..759a7008d3f3 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxList.cpp ------------------------------------------*- C++ -*-===// +//===-- LibCxxMap.cpp -------------------------------------------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -27,442 +27,428 @@ using namespace lldb;  using namespace lldb_private;  using namespace lldb_private::formatters; -class MapEntry -{ +class MapEntry {  public: -    MapEntry() = default; -    explicit MapEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {} -    MapEntry(const MapEntry& rhs) = default; -    explicit MapEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {} -     -    ValueObjectSP -    left () const -    { -        static ConstString g_left("__left_"); -        if (!m_entry_sp) -            return m_entry_sp; -        return m_entry_sp->GetChildMemberWithName(g_left, true); -    } -     -    ValueObjectSP -    right () const -    { -        static ConstString g_right("__right_"); -        if (!m_entry_sp) -            return m_entry_sp; -        return m_entry_sp->GetChildMemberWithName(g_right, true); -    } -     -    ValueObjectSP -    parent () const -    { -        static ConstString g_parent("__parent_"); -        if (!m_entry_sp) -            return m_entry_sp; -        return m_entry_sp->GetChildMemberWithName(g_parent, true); -    } -     -    uint64_t -    value () const -    { -        if (!m_entry_sp) -            return 0; -        return m_entry_sp->GetValueAsUnsigned(0); -    } -     -    bool -    error () const -    { -        if (!m_entry_sp) -            return true; -        return m_entry_sp->GetError().Fail(); -    } -     -    bool -    null() const -    { -        return (value() == 0); -    } -     -    ValueObjectSP -    GetEntry () const -    { -        return m_entry_sp; -    } -     -    void -    SetEntry (ValueObjectSP entry) -    { -        m_entry_sp = entry; -    } -     -    bool -    operator == (const MapEntry& rhs) const -    { -        return (rhs.m_entry_sp.get() == m_entry_sp.get()); -    } -     +  MapEntry() = default; +  explicit MapEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {} +  MapEntry(const MapEntry &rhs) = default; +  explicit MapEntry(ValueObject *entry) +      : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {} + +  ValueObjectSP left() const { +    static ConstString g_left("__left_"); +    if (!m_entry_sp) +      return m_entry_sp; +    return m_entry_sp->GetSyntheticChildAtOffset( +        0, m_entry_sp->GetCompilerType(), true); +  } + +  ValueObjectSP right() const { +    static ConstString g_right("__right_"); +    if (!m_entry_sp) +      return m_entry_sp; +    return m_entry_sp->GetSyntheticChildAtOffset( +        m_entry_sp->GetProcessSP()->GetAddressByteSize(), +        m_entry_sp->GetCompilerType(), true); +  } + +  ValueObjectSP parent() const { +    static ConstString g_parent("__parent_"); +    if (!m_entry_sp) +      return m_entry_sp; +    return m_entry_sp->GetSyntheticChildAtOffset( +        2 * m_entry_sp->GetProcessSP()->GetAddressByteSize(), +        m_entry_sp->GetCompilerType(), true); +  } + +  uint64_t value() const { +    if (!m_entry_sp) +      return 0; +    return m_entry_sp->GetValueAsUnsigned(0); +  } + +  bool error() const { +    if (!m_entry_sp) +      return true; +    return m_entry_sp->GetError().Fail(); +  } + +  bool null() const { return (value() == 0); } + +  ValueObjectSP GetEntry() const { return m_entry_sp; } + +  void SetEntry(ValueObjectSP entry) { m_entry_sp = entry; } + +  bool operator==(const MapEntry &rhs) const { +    return (rhs.m_entry_sp.get() == m_entry_sp.get()); +  } +  private: -    ValueObjectSP m_entry_sp; +  ValueObjectSP m_entry_sp;  }; -class MapIterator -{ +class MapIterator {  public: -    MapIterator() = default; -    MapIterator (MapEntry entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth), m_error(false) {} -    MapIterator (ValueObjectSP entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth), m_error(false) {} -    MapIterator (const MapIterator& rhs) : m_entry(rhs.m_entry),m_max_depth(rhs.m_max_depth), m_error(false) {} -    MapIterator (ValueObject* entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth), m_error(false) {} -     -    ValueObjectSP -    value () -    { -        return m_entry.GetEntry(); -    } -     -    ValueObjectSP -    advance (size_t count) -    { -        ValueObjectSP fail; -        if (m_error) -            return fail; -        size_t steps = 0; -        while (count > 0) -        { -            next(); -            count--, steps++; -            if (m_error || -                m_entry.null() || -                (steps > m_max_depth)) -                return fail; -        } -        return m_entry.GetEntry(); +  MapIterator() = default; +  MapIterator(MapEntry entry, size_t depth = 0) +      : m_entry(entry), m_max_depth(depth), m_error(false) {} +  MapIterator(ValueObjectSP entry, size_t depth = 0) +      : m_entry(entry), m_max_depth(depth), m_error(false) {} +  MapIterator(const MapIterator &rhs) +      : m_entry(rhs.m_entry), m_max_depth(rhs.m_max_depth), m_error(false) {} +  MapIterator(ValueObject *entry, size_t depth = 0) +      : m_entry(entry), m_max_depth(depth), m_error(false) {} + +  ValueObjectSP value() { return m_entry.GetEntry(); } + +  ValueObjectSP advance(size_t count) { +    ValueObjectSP fail; +    if (m_error) +      return fail; +    size_t steps = 0; +    while (count > 0) { +      next(); +      count--, steps++; +      if (m_error || m_entry.null() || (steps > m_max_depth)) +        return fail;      } -     +    return m_entry.GetEntry(); +  } +  protected: -    void -    next () -    { -        if (m_entry.null()) -            return; -        MapEntry right(m_entry.right()); -        if (!right.null()) -        { -            m_entry = tree_min(std::move(right)); -            return; -        } -        size_t steps = 0; -        while (!is_left_child(m_entry)) -        { -            if (m_entry.error()) -            { -                m_error = true; -                return; -            } -            m_entry.SetEntry(m_entry.parent()); -            steps++; -            if (steps > m_max_depth) -            { -                m_entry = MapEntry(); -                return; -            } -        } -        m_entry = MapEntry(m_entry.parent()); +  void next() { +    if (m_entry.null()) +      return; +    MapEntry right(m_entry.right()); +    if (!right.null()) { +      m_entry = tree_min(std::move(right)); +      return;      } -     -private: -    MapEntry -    tree_min (MapEntry&& x) -    { -        if (x.null()) -            return MapEntry(); -        MapEntry left(x.left()); -        size_t steps = 0; -        while (!left.null()) -        { -            if (left.error()) -            { -                m_error = true; -                return MapEntry(); -            } -            x = left; -            left.SetEntry(x.left()); -            steps++; -            if (steps > m_max_depth) -                return MapEntry(); -        } -        return x; +    size_t steps = 0; +    while (!is_left_child(m_entry)) { +      if (m_entry.error()) { +        m_error = true; +        return; +      } +      m_entry.SetEntry(m_entry.parent()); +      steps++; +      if (steps > m_max_depth) { +        m_entry = MapEntry(); +        return; +      }      } -     -    bool -    is_left_child (const MapEntry& x) -    { -        if (x.null()) -            return false; -        MapEntry rhs(x.parent()); -        rhs.SetEntry(rhs.left()); -        return x.value() == rhs.value(); +    m_entry = MapEntry(m_entry.parent()); +  } + +private: +  MapEntry tree_min(MapEntry &&x) { +    if (x.null()) +      return MapEntry(); +    MapEntry left(x.left()); +    size_t steps = 0; +    while (!left.null()) { +      if (left.error()) { +        m_error = true; +        return MapEntry(); +      } +      x = left; +      left.SetEntry(x.left()); +      steps++; +      if (steps > m_max_depth) +        return MapEntry();      } -     -    MapEntry m_entry; -    size_t m_max_depth; -    bool m_error; +    return x; +  } + +  bool is_left_child(const MapEntry &x) { +    if (x.null()) +      return false; +    MapEntry rhs(x.parent()); +    rhs.SetEntry(rhs.left()); +    return x.value() == rhs.value(); +  } + +  MapEntry m_entry; +  size_t m_max_depth; +  bool m_error;  };  namespace lldb_private { -    namespace formatters { -        class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd -        { -        public: -            LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - -            ~LibcxxStdMapSyntheticFrontEnd() override = default; - -            size_t -            CalculateNumChildren() override; -             -            lldb::ValueObjectSP -            GetChildAtIndex(size_t idx) override; -             -            bool -            Update() override; -             -            bool -            MightHaveChildren() override; -             -            size_t -            GetIndexOfChildWithName(const ConstString &name) override; -             -        private: -            bool -            GetDataType(); -             -            void -            GetValueOffset (const lldb::ValueObjectSP& node); -             -            ValueObject* m_tree; -            ValueObject* m_root_node; -            CompilerType m_element_type; -            uint32_t m_skip_size; -            size_t m_count; -            std::map<size_t, MapIterator> m_iterators; -        }; -    } // namespace formatters +namespace formatters { +class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: +  LibcxxStdMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  ~LibcxxStdMapSyntheticFrontEnd() override = default; + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +private: +  bool GetDataType(); + +  void GetValueOffset(const lldb::ValueObjectSP &node); + +  ValueObject *m_tree; +  ValueObject *m_root_node; +  CompilerType m_element_type; +  uint32_t m_skip_size; +  size_t m_count; +  std::map<size_t, MapIterator> m_iterators; +}; +} // namespace formatters  } // namespace lldb_private -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_tree(nullptr), -    m_root_node(nullptr), -    m_element_type(), -    m_skip_size(UINT32_MAX), -    m_count(UINT32_MAX), -    m_iterators() -{ -    if (valobj_sp) -        Update(); +lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: +    LibcxxStdMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_tree(nullptr), +      m_root_node(nullptr), m_element_type(), m_skip_size(UINT32_MAX), +      m_count(UINT32_MAX), m_iterators() { +  if (valobj_sp) +    Update();  } -size_t -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::CalculateNumChildren () -{ -    static ConstString g___pair3_("__pair3_"); -    static ConstString g___first_("__first_"); - -    if (m_count != UINT32_MAX) -        return m_count; -    if (m_tree == nullptr) -        return 0; -    ValueObjectSP m_item(m_tree->GetChildMemberWithName(g___pair3_, true)); -    if (!m_item) -        return 0; -    m_item = m_item->GetChildMemberWithName(g___first_, true); -    if (!m_item) -        return 0; -    m_count = m_item->GetValueAsUnsigned(0); +size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: +    CalculateNumChildren() { +  static ConstString g___pair3_("__pair3_"); +  static ConstString g___first_("__first_"); + +  if (m_count != UINT32_MAX)      return m_count; +  if (m_tree == nullptr) +    return 0; +  ValueObjectSP m_item(m_tree->GetChildMemberWithName(g___pair3_, true)); +  if (!m_item) +    return 0; +  m_item = m_item->GetChildMemberWithName(g___first_, true); +  if (!m_item) +    return 0; +  m_count = m_item->GetValueAsUnsigned(0); +  return m_count;  } -bool -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() -{ -    static ConstString g___value_("__value_"); -     -    if (m_element_type.GetOpaqueQualType() && m_element_type.GetTypeSystem()) -        return true; -    m_element_type.Clear(); -    ValueObjectSP deref; -    Error error; -    deref = m_root_node->Dereference(error); -    if (!deref || error.Fail()) -        return false; -    deref = deref->GetChildMemberWithName(g___value_, true); -    if (!deref) -        return false; +bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() { +  static ConstString g___value_("__value_"); +  static ConstString g_tree_("__tree_"); +  static ConstString g_pair3("__pair3_"); + +  if (m_element_type.GetOpaqueQualType() && m_element_type.GetTypeSystem()) +    return true; +  m_element_type.Clear(); +  ValueObjectSP deref; +  Error error; +  deref = m_root_node->Dereference(error); +  if (!deref || error.Fail()) +    return false; +  deref = deref->GetChildMemberWithName(g___value_, true); +  if (deref) {      m_element_type = deref->GetCompilerType();      return true; +  } +  lldb::TemplateArgumentKind kind; +  deref = m_backend.GetChildAtNamePath({g_tree_, g_pair3}); +  if (!deref) +    return false; +  m_element_type = +      deref->GetCompilerType().GetTemplateArgument(1, kind).GetTemplateArgument( +          1, kind); +  if (m_element_type) { +    std::string name; +    uint64_t bit_offset_ptr; +    uint32_t bitfield_bit_size_ptr; +    bool is_bitfield_ptr; +    m_element_type = m_element_type.GetFieldAtIndex( +        0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr); +    m_element_type = m_element_type.GetTypedefedType(); +    return m_element_type.IsValid(); +  } else { +    m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind); +    return m_element_type.IsValid(); +  }  } -void -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset (const lldb::ValueObjectSP& node) -{ -    if (m_skip_size != UINT32_MAX) -        return; -    if (!node) -        return; -    CompilerType node_type(node->GetCompilerType()); -    uint64_t bit_offset; -    if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) == UINT32_MAX) -        return; +void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( +    const lldb::ValueObjectSP &node) { +  if (m_skip_size != UINT32_MAX) +    return; +  if (!node) +    return; +  CompilerType node_type(node->GetCompilerType()); +  uint64_t bit_offset; +  if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) != +      UINT32_MAX) {      m_skip_size = bit_offset / 8u; +  } else { +    ClangASTContext *ast_ctx = +        llvm::dyn_cast_or_null<ClangASTContext>(node_type.GetTypeSystem()); +    if (!ast_ctx) +      return; +    CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( +        ConstString(), +        {{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, +         {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, +         {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, +         {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, +         {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); +    std::string child_name; +    uint32_t child_byte_size; +    int32_t child_byte_offset = 0; +    uint32_t child_bitfield_bit_size; +    uint32_t child_bitfield_bit_offset; +    bool child_is_base_class; +    bool child_is_deref_of_parent; +    uint64_t language_flags; +    if (tree_node_type +            .GetChildCompilerTypeAtIndex( +                nullptr, 4, true, true, true, child_name, child_byte_size, +                child_byte_offset, child_bitfield_bit_size, +                child_bitfield_bit_offset, child_is_base_class, +                child_is_deref_of_parent, nullptr, language_flags) +            .IsValid()) +      m_skip_size = (uint32_t)child_byte_offset; +  }  }  lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t idx) -{ -    static ConstString g___cc("__cc"); -    static ConstString g___nc("__nc"); -    static ConstString g___value_("__value_"); +lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( +    size_t idx) { +  static ConstString g___cc("__cc"); +  static ConstString g___nc("__nc"); +  static ConstString g___value_("__value_"); + +  if (idx >= CalculateNumChildren()) +    return lldb::ValueObjectSP(); +  if (m_tree == nullptr || m_root_node == nullptr) +    return lldb::ValueObjectSP(); + +  MapIterator iterator(m_root_node, CalculateNumChildren()); -    if (idx >= CalculateNumChildren()) +  const bool need_to_skip = (idx > 0); +  size_t actual_advancde = idx; +  if (need_to_skip) { +    auto cached_iterator = m_iterators.find(idx - 1); +    if (cached_iterator != m_iterators.end()) { +      iterator = cached_iterator->second; +      actual_advancde = 1; +    } +  } + +  ValueObjectSP iterated_sp(iterator.advance(actual_advancde)); +  if (!iterated_sp) { +    // this tree is garbage - stop +    m_tree = +        nullptr; // this will stop all future searches until an Update() happens +    return iterated_sp; +  } +  if (GetDataType()) { +    if (!need_to_skip) { +      Error error; +      iterated_sp = iterated_sp->Dereference(error); +      if (!iterated_sp || error.Fail()) { +        m_tree = nullptr;          return lldb::ValueObjectSP(); -    if (m_tree == nullptr || m_root_node == nullptr) +      } +      GetValueOffset(iterated_sp); +      auto child_sp = iterated_sp->GetChildMemberWithName(g___value_, true); +      if (child_sp) +        iterated_sp = child_sp; +      else +        iterated_sp = iterated_sp->GetSyntheticChildAtOffset( +            m_skip_size, m_element_type, true); +      if (!iterated_sp) { +        m_tree = nullptr;          return lldb::ValueObjectSP(); -     -    MapIterator iterator(m_root_node, CalculateNumChildren()); -     -    const bool need_to_skip = (idx > 0); -    size_t actual_advancde = idx; -    if (need_to_skip) -    { -        auto cached_iterator = m_iterators.find(idx-1); -        if (cached_iterator != m_iterators.end()) -        { -            iterator = cached_iterator->second; -            actual_advancde = 1; -        } -    } -     -    ValueObjectSP iterated_sp(iterator.advance(actual_advancde)); -    if (!iterated_sp) -    { -        // this tree is garbage - stop -        m_tree = nullptr; // this will stop all future searches until an Update() happens -        return iterated_sp; -    } -    if (GetDataType()) -    { -        if (!need_to_skip) -        { -            Error error; -            iterated_sp = iterated_sp->Dereference(error); -            if (!iterated_sp || error.Fail()) -            { -                m_tree = nullptr; -                return lldb::ValueObjectSP(); -            } -            GetValueOffset(iterated_sp); -            iterated_sp = iterated_sp->GetChildMemberWithName(g___value_, true); -            if (!iterated_sp) -            { -                m_tree = nullptr; -                return lldb::ValueObjectSP(); -            } -        } -        else -        { -            // because of the way our debug info is made, we need to read item 0 first -            // so that we can cache information used to generate other elements -            if (m_skip_size == UINT32_MAX) -                GetChildAtIndex(0); -            if (m_skip_size == UINT32_MAX) -            { -                m_tree = nullptr; -                return lldb::ValueObjectSP(); -            } -            iterated_sp = iterated_sp->GetSyntheticChildAtOffset(m_skip_size, m_element_type, true); -            if (!iterated_sp) -            { -                m_tree = nullptr; -                return lldb::ValueObjectSP(); -            } -        } -    } -    else -    { +      } +    } else { +      // because of the way our debug info is made, we need to read item 0 first +      // so that we can cache information used to generate other elements +      if (m_skip_size == UINT32_MAX) +        GetChildAtIndex(0); +      if (m_skip_size == UINT32_MAX) {          m_tree = nullptr;          return lldb::ValueObjectSP(); -    } -    // at this point we have a valid  -    // we need to copy current_sp into a new object otherwise we will end up with all items named __value_ -    DataExtractor data; -    Error error; -    iterated_sp->GetData(data, error); -    if (error.Fail()) -    { +      } +      iterated_sp = iterated_sp->GetSyntheticChildAtOffset( +          m_skip_size, m_element_type, true); +      if (!iterated_sp) {          m_tree = nullptr;          return lldb::ValueObjectSP(); +      }      } -    StreamString name; -    name.Printf("[%" PRIu64 "]", (uint64_t)idx); -    auto potential_child_sp = CreateValueObjectFromData(name.GetData(), data, m_backend.GetExecutionContextRef(), m_element_type); -    if (potential_child_sp) -    { -        switch (potential_child_sp->GetNumChildren()) -        { -            case 1: -            { -                auto child0_sp = potential_child_sp->GetChildAtIndex(0, true); -                if (child0_sp && child0_sp->GetName() == g___cc) -                    potential_child_sp = child0_sp; -                break; -            } -            case 2: -            { -                auto child0_sp = potential_child_sp->GetChildAtIndex(0, true); -                auto child1_sp = potential_child_sp->GetChildAtIndex(1, true); -                if (child0_sp && child0_sp->GetName() == g___cc && -                    child1_sp && child1_sp->GetName() == g___nc) -                    potential_child_sp = child0_sp; -                break; -            } -        } -        potential_child_sp->SetName(ConstString(name.GetData())); +  } else { +    m_tree = nullptr; +    return lldb::ValueObjectSP(); +  } +  // at this point we have a valid +  // we need to copy current_sp into a new object otherwise we will end up with +  // all items named __value_ +  DataExtractor data; +  Error error; +  iterated_sp->GetData(data, error); +  if (error.Fail()) { +    m_tree = nullptr; +    return lldb::ValueObjectSP(); +  } +  StreamString name; +  name.Printf("[%" PRIu64 "]", (uint64_t)idx); +  auto potential_child_sp = CreateValueObjectFromData( +      name.GetString(), data, m_backend.GetExecutionContextRef(), +      m_element_type); +  if (potential_child_sp) { +    switch (potential_child_sp->GetNumChildren()) { +    case 1: { +      auto child0_sp = potential_child_sp->GetChildAtIndex(0, true); +      if (child0_sp && child0_sp->GetName() == g___cc) +        potential_child_sp = child0_sp; +      break;      } -    m_iterators[idx] = iterator; -    return potential_child_sp; +    case 2: { +      auto child0_sp = potential_child_sp->GetChildAtIndex(0, true); +      auto child1_sp = potential_child_sp->GetChildAtIndex(1, true); +      if (child0_sp && child0_sp->GetName() == g___cc && child1_sp && +          child1_sp->GetName() == g___nc) +        potential_child_sp = child0_sp; +      break; +    } +    } +    potential_child_sp->SetName(ConstString(name.GetString())); +  } +  m_iterators[idx] = iterator; +  return potential_child_sp;  } -bool -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update() -{ -    static ConstString g___tree_("__tree_"); -    static ConstString g___begin_node_("__begin_node_"); -    m_count = UINT32_MAX; -    m_tree = m_root_node = nullptr; -    m_iterators.clear(); -    m_tree = m_backend.GetChildMemberWithName(g___tree_, true).get(); -    if (!m_tree) -        return false; -    m_root_node = m_tree->GetChildMemberWithName(g___begin_node_, true).get(); +bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update() { +  static ConstString g___tree_("__tree_"); +  static ConstString g___begin_node_("__begin_node_"); +  m_count = UINT32_MAX; +  m_tree = m_root_node = nullptr; +  m_iterators.clear(); +  m_tree = m_backend.GetChildMemberWithName(g___tree_, true).get(); +  if (!m_tree)      return false; +  m_root_node = m_tree->GetChildMemberWithName(g___begin_node_, true).get(); +  return false;  } -bool -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::MightHaveChildren () -{ -    return true; +bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: +    MightHaveChildren() { +  return true;  } -size_t -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) -{ -    return ExtractIndexFromString(name.GetCString()); +size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: +    GetIndexOfChildWithName(const ConstString &name) { +  return ExtractIndexFromString(name.GetCString());  } -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    return (valobj_sp ? new LibcxxStdMapSyntheticFrontEnd(valobj_sp) : nullptr); +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibcxxStdMapSyntheticFrontEnd(valobj_sp) : nullptr);  } diff --git a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp index a547695448ce..5fe4b3a9fc9e 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -28,136 +28,162 @@ using namespace lldb_private;  using namespace lldb_private::formatters;  namespace lldb_private { -    namespace formatters { -        class LibcxxStdUnorderedMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd -        { -        public: -            LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - -            ~LibcxxStdUnorderedMapSyntheticFrontEnd() override = default; - -            size_t -            CalculateNumChildren() override; -             -            lldb::ValueObjectSP -            GetChildAtIndex(size_t idx) override; -             -            bool -            Update() override; -             -            bool -            MightHaveChildren() override; -             -            size_t -            GetIndexOfChildWithName(const ConstString &name) override; - -        private: -            ValueObject* m_tree; -            size_t m_num_elements; -            ValueObject* m_next_element; -            std::vector<std::pair<ValueObject*, uint64_t> > m_elements_cache; -        }; -    } // namespace formatters +namespace formatters { +class LibcxxStdUnorderedMapSyntheticFrontEnd +    : public SyntheticChildrenFrontEnd { +public: +  LibcxxStdUnorderedMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  ~LibcxxStdUnorderedMapSyntheticFrontEnd() override = default; + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +private: +  CompilerType m_element_type; +  CompilerType m_node_type; +  ValueObject *m_tree; +  size_t m_num_elements; +  ValueObject *m_next_element; +  std::vector<std::pair<ValueObject *, uint64_t>> m_elements_cache; +}; +} // namespace formatters  } // namespace lldb_private -lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_tree(nullptr), -    m_num_elements(0), -    m_next_element(nullptr), -    m_elements_cache() -{ -    if (valobj_sp) -        Update(); +lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd:: +    LibcxxStdUnorderedMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type(), m_tree(nullptr), +      m_num_elements(0), m_next_element(nullptr), m_elements_cache() { +  if (valobj_sp) +    Update();  } -size_t -lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::CalculateNumChildren () -{ -    if (m_num_elements != UINT32_MAX) -        return m_num_elements; -    return 0; +size_t lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd:: +    CalculateNumChildren() { +  if (m_num_elements != UINT32_MAX) +    return m_num_elements; +  return 0;  } -lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtIndex (size_t idx) -{ -    if (idx >= CalculateNumChildren()) -        return lldb::ValueObjectSP(); -    if (m_tree == nullptr) -        return lldb::ValueObjectSP(); -     -    while (idx >= m_elements_cache.size()) -    { -        if (m_next_element == nullptr) -            return lldb::ValueObjectSP(); -         -        Error error; -        ValueObjectSP node_sp = m_next_element->Dereference(error); -        if (!node_sp || error.Fail()) -            return lldb::ValueObjectSP(); -         -        ValueObjectSP value_sp = node_sp->GetChildMemberWithName(ConstString("__value_"), true); -        ValueObjectSP hash_sp = node_sp->GetChildMemberWithName(ConstString("__hash_"), true); -        if (!hash_sp || !value_sp) -            return lldb::ValueObjectSP(); -        m_elements_cache.push_back({value_sp.get(),hash_sp->GetValueAsUnsigned(0)}); -        m_next_element = node_sp->GetChildMemberWithName(ConstString("__next_"),true).get(); -        if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0) -            m_next_element = nullptr; -    } -     -    std::pair<ValueObject*, uint64_t> val_hash = m_elements_cache[idx]; -    if (!val_hash.first) -        return lldb::ValueObjectSP(); -    StreamString stream; -    stream.Printf("[%" PRIu64 "]", (uint64_t)idx); -    DataExtractor data; +lldb::ValueObjectSP lldb_private::formatters:: +    LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtIndex(size_t idx) { +  if (idx >= CalculateNumChildren()) +    return lldb::ValueObjectSP(); +  if (m_tree == nullptr) +    return lldb::ValueObjectSP(); + +  while (idx >= m_elements_cache.size()) { +    if (m_next_element == nullptr) +      return lldb::ValueObjectSP(); +      Error error; -    val_hash.first->GetData(data, error); -    if (error.Fail()) -        return lldb::ValueObjectSP(); -    const bool thread_and_frame_only_if_stopped = true; -    ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped); -    return CreateValueObjectFromData(stream.GetData(), -                                     data, -                                     exe_ctx, -                                     val_hash.first->GetCompilerType()); +    ValueObjectSP node_sp = m_next_element->Dereference(error); +    if (!node_sp || error.Fail()) +      return lldb::ValueObjectSP(); + +    ValueObjectSP value_sp = +        node_sp->GetChildMemberWithName(ConstString("__value_"), true); +    ValueObjectSP hash_sp = +        node_sp->GetChildMemberWithName(ConstString("__hash_"), true); +    if (!hash_sp || !value_sp) { +      if (!m_element_type) { +        auto first_sp = m_backend.GetChildAtNamePath({ConstString("__table_"), +                                                      ConstString("__p1_"), +                                                      ConstString("__first_")}); +        if (!first_sp) +          return nullptr; +        m_element_type = first_sp->GetCompilerType(); +        lldb::TemplateArgumentKind kind; +        m_element_type = m_element_type.GetTemplateArgument(0, kind); +        m_element_type = m_element_type.GetPointeeType(); +        m_node_type = m_element_type; +        m_element_type = m_element_type.GetTemplateArgument(0, kind); +        std::string name; +        m_element_type = +            m_element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr); +        m_element_type = m_element_type.GetTypedefedType(); +      } +      if (!m_node_type) +        return nullptr; +      node_sp = node_sp->Cast(m_node_type); +      value_sp = node_sp->GetChildMemberWithName(ConstString("__value_"), true); +      hash_sp = node_sp->GetChildMemberWithName(ConstString("__hash_"), true); +      if (!value_sp || !hash_sp) +        return nullptr; +    } +    m_elements_cache.push_back( +        {value_sp.get(), hash_sp->GetValueAsUnsigned(0)}); +    m_next_element = +        node_sp->GetChildMemberWithName(ConstString("__next_"), true).get(); +    if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0) +      m_next_element = nullptr; +  } + +  std::pair<ValueObject *, uint64_t> val_hash = m_elements_cache[idx]; +  if (!val_hash.first) +    return lldb::ValueObjectSP(); +  StreamString stream; +  stream.Printf("[%" PRIu64 "]", (uint64_t)idx); +  DataExtractor data; +  Error error; +  val_hash.first->GetData(data, error); +  if (error.Fail()) +    return lldb::ValueObjectSP(); +  const bool thread_and_frame_only_if_stopped = true; +  ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock( +      thread_and_frame_only_if_stopped); +  return CreateValueObjectFromData(stream.GetString(), data, exe_ctx, +                                   val_hash.first->GetCompilerType());  } -bool -lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::Update() -{ -    m_num_elements = UINT32_MAX; -    m_next_element = nullptr; -    m_elements_cache.clear(); -    ValueObjectSP table_sp = m_backend.GetChildMemberWithName(ConstString("__table_"), true); -    if (!table_sp) -        return false; -    ValueObjectSP num_elements_sp = table_sp->GetChildAtNamePath({ConstString("__p2_"),ConstString("__first_")}); -    if (!num_elements_sp) -        return false; -    m_num_elements = num_elements_sp->GetValueAsUnsigned(0); -    m_tree = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get(); -    if (m_num_elements > 0) -        m_next_element = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get(); +bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd:: +    Update() { +  m_num_elements = UINT32_MAX; +  m_next_element = nullptr; +  m_elements_cache.clear(); +  ValueObjectSP table_sp = +      m_backend.GetChildMemberWithName(ConstString("__table_"), true); +  if (!table_sp) +    return false; +  ValueObjectSP num_elements_sp = table_sp->GetChildAtNamePath( +      {ConstString("__p2_"), ConstString("__first_")}); +  if (!num_elements_sp)      return false; +  m_num_elements = num_elements_sp->GetValueAsUnsigned(0); +  m_tree = +      table_sp +          ->GetChildAtNamePath({ConstString("__p1_"), ConstString("__first_"), +                                ConstString("__next_")}) +          .get(); +  if (m_num_elements > 0) +    m_next_element = +        table_sp +            ->GetChildAtNamePath({ConstString("__p1_"), ConstString("__first_"), +                                  ConstString("__next_")}) +            .get(); +  return false;  } -bool -lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::MightHaveChildren () -{ -    return true; +bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd:: +    MightHaveChildren() { +  return true;  } -size_t -lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) -{ -    return ExtractIndexFromString(name.GetCString()); +size_t lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd:: +    GetIndexOfChildWithName(const ConstString &name) { +  return ExtractIndexFromString(name.GetCString());  } -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    return (valobj_sp ? new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp) : nullptr); +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp) +                    : nullptr);  } diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp index ed26eaea121c..b5c9b6d0f11e 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp @@ -22,130 +22,120 @@ using namespace lldb_private;  using namespace lldb_private::formatters;  namespace lldb_private { -    namespace formatters { -        class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd -        { -        public: -            LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - -            ~LibcxxStdVectorSyntheticFrontEnd() override; - -            size_t -            CalculateNumChildren() override; -             -            lldb::ValueObjectSP -            GetChildAtIndex(size_t idx) override; -             -            bool -            Update() override; -             -            bool -            MightHaveChildren() override; -             -            size_t -            GetIndexOfChildWithName(const ConstString &name) override; - -        private: -            ValueObject* m_start; -            ValueObject* m_finish; -            CompilerType m_element_type; -            uint32_t m_element_size; -        }; -    } // namespace formatters +namespace formatters { +class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: +  LibcxxStdVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  ~LibcxxStdVectorSyntheticFrontEnd() override; + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +private: +  ValueObject *m_start; +  ValueObject *m_finish; +  CompilerType m_element_type; +  uint32_t m_element_size; +}; +} // namespace formatters  } // namespace lldb_private -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_start(nullptr), -    m_finish(nullptr), -    m_element_type(), -    m_element_size(0) -{ -    if (valobj_sp) -        Update(); +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd:: +    LibcxxStdVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_start(nullptr), +      m_finish(nullptr), m_element_type(), m_element_size(0) { +  if (valobj_sp) +    Update();  } -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd() -{ -    // these need to stay around because they are child objects who will follow their parent's life cycle -    // delete m_start; -    // delete m_finish; +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd:: +    ~LibcxxStdVectorSyntheticFrontEnd() { +  // these need to stay around because they are child objects who will follow +  // their parent's life cycle +  // delete m_start; +  // delete m_finish;  } -size_t -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren () -{ -    if (!m_start || !m_finish) -        return 0; -    uint64_t start_val = m_start->GetValueAsUnsigned(0); -    uint64_t finish_val = m_finish->GetValueAsUnsigned(0); -     -    if (start_val == 0 || finish_val == 0) -        return 0; -     -    if (start_val >= finish_val) -        return 0; -     -    size_t num_children = (finish_val - start_val); -    if (num_children % m_element_size) -        return 0; -    return num_children/m_element_size; +size_t lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd:: +    CalculateNumChildren() { +  if (!m_start || !m_finish) +    return 0; +  uint64_t start_val = m_start->GetValueAsUnsigned(0); +  uint64_t finish_val = m_finish->GetValueAsUnsigned(0); + +  if (start_val == 0 || finish_val == 0) +    return 0; + +  if (start_val >= finish_val) +    return 0; + +  size_t num_children = (finish_val - start_val); +  if (num_children % m_element_size) +    return 0; +  return num_children / m_element_size;  }  lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx) -{ -    if (!m_start || !m_finish) -        return lldb::ValueObjectSP(); -     -    uint64_t offset = idx * m_element_size; -    offset = offset + m_start->GetValueAsUnsigned(0); -    StreamString name; -    name.Printf("[%" PRIu64 "]", (uint64_t)idx); -    return CreateValueObjectFromAddress(name.GetData(), -                                        offset, -                                        m_backend.GetExecutionContextRef(), -                                        m_element_type); +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex( +    size_t idx) { +  if (!m_start || !m_finish) +    return lldb::ValueObjectSP(); + +  uint64_t offset = idx * m_element_size; +  offset = offset + m_start->GetValueAsUnsigned(0); +  StreamString name; +  name.Printf("[%" PRIu64 "]", (uint64_t)idx); +  return CreateValueObjectFromAddress(name.GetString(), offset, +                                      m_backend.GetExecutionContextRef(), +                                      m_element_type);  } -bool -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() -{ -    m_start = m_finish = nullptr; -    ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true)); -    if (!data_type_finder_sp) -        return false; -    data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true); -    if (!data_type_finder_sp) -        return false; -    m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType(); -    m_element_size = m_element_type.GetByteSize(nullptr); -     -    if (m_element_size > 0) -    { -        // store raw pointers or end up with a circular dependency -        m_start = m_backend.GetChildMemberWithName(ConstString("__begin_"),true).get(); -        m_finish = m_backend.GetChildMemberWithName(ConstString("__end_"),true).get(); -    } +bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() { +  m_start = m_finish = nullptr; +  ValueObjectSP data_type_finder_sp( +      m_backend.GetChildMemberWithName(ConstString("__end_cap_"), true)); +  if (!data_type_finder_sp) +    return false; +  data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName( +      ConstString("__first_"), true); +  if (!data_type_finder_sp)      return false; +  m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType(); +  m_element_size = m_element_type.GetByteSize(nullptr); + +  if (m_element_size > 0) { +    // store raw pointers or end up with a circular dependency +    m_start = +        m_backend.GetChildMemberWithName(ConstString("__begin_"), true).get(); +    m_finish = +        m_backend.GetChildMemberWithName(ConstString("__end_"), true).get(); +  } +  return false;  } -bool -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren () -{ -    return true; +bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd:: +    MightHaveChildren() { +  return true;  } -size_t -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) -{ -    if (!m_start || !m_finish) -        return UINT32_MAX; -    return ExtractIndexFromString(name.GetCString()); +size_t lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd:: +    GetIndexOfChildWithName(const ConstString &name) { +  if (!m_start || !m_finish) +    return UINT32_MAX; +  return ExtractIndexFromString(name.GetCString());  } -lldb_private::SyntheticChildrenFrontEnd* -lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    return (valobj_sp ? new LibcxxStdVectorSyntheticFrontEnd(valobj_sp) : nullptr); +lldb_private::SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibcxxStdVectorSyntheticFrontEnd(valobj_sp) +                    : nullptr);  } diff --git a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 6d6f915f68e2..f931a8d6a046 100644 --- a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -28,449 +28,404 @@ using namespace lldb;  using namespace lldb_private;  using namespace lldb_private::formatters; -namespace -{ - -class LibstdcppMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd -{ -    /* -     (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ibeg = { -     (_Base_ptr) _M_node = 0x0000000100103910 { -     (std::_Rb_tree_color) _M_color = _S_black -     (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0 -     (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000 -     (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000 -     } -     } -     */ +namespace { + +class LibstdcppMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +  /* +   (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char, +   std::char_traits<char>, std::allocator<char> > > >) ibeg = { +   (_Base_ptr) _M_node = 0x0000000100103910 { +   (std::_Rb_tree_color) _M_color = _S_black +   (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0 +   (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000 +   (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000 +   } +   } +   */  public: -    explicit LibstdcppMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); - -    size_t -    CalculateNumChildren() override; -     -    lldb::ValueObjectSP -    GetChildAtIndex(size_t idx) override; -     -    bool -    Update() override; -     -    bool -    MightHaveChildren() override; -     -    size_t -    GetIndexOfChildWithName (const ConstString &name) override; -     +  explicit LibstdcppMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; +  private: -    ExecutionContextRef m_exe_ctx_ref; -    lldb::addr_t m_pair_address; -    CompilerType m_pair_type; -    lldb::ValueObjectSP m_pair_sp; +  ExecutionContextRef m_exe_ctx_ref; +  lldb::addr_t m_pair_address; +  CompilerType m_pair_type; +  lldb::ValueObjectSP m_pair_sp;  }; -class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd -{ +class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {  public: -    explicit LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); +  explicit LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); -    size_t -    CalculateNumChildren() override; +  size_t CalculateNumChildren() override; -    lldb::ValueObjectSP -    GetChildAtIndex(size_t idx) override; +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; -    bool -    Update() override; +  bool Update() override; -    bool -    MightHaveChildren() override; +  bool MightHaveChildren() override; -    size_t -    GetIndexOfChildWithName(const ConstString &name) override; +  size_t GetIndexOfChildWithName(const ConstString &name) override;  };  } // end of anonymous namespace -LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_exe_ctx_ref(), -    m_pair_address(0), -    m_pair_type(), -    m_pair_sp() -{ -    if (valobj_sp) -        Update(); +LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd( +    lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_pair_address(0), +      m_pair_type(), m_pair_sp() { +  if (valobj_sp) +    Update();  } -bool -LibstdcppMapIteratorSyntheticFrontEnd::Update() -{ -    ValueObjectSP valobj_sp = m_backend.GetSP(); -    if (!valobj_sp) -        return false; -     -    TargetSP target_sp(valobj_sp->GetTargetSP()); -     -    if (!target_sp) -        return false; -     -    bool is_64bit = (target_sp->GetArchitecture().GetAddressByteSize() == 8); -     -    if (!valobj_sp) -        return false; -    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); -     -    ValueObjectSP _M_node_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_node"), true)); -    if (!_M_node_sp) -        return false; -     -    m_pair_address = _M_node_sp->GetValueAsUnsigned(0); -    if (m_pair_address == 0) -        return false; -     -    m_pair_address += (is_64bit ? 32 : 16); -     -    CompilerType my_type(valobj_sp->GetCompilerType()); -    if (my_type.GetNumTemplateArguments() >= 1) -    { -        TemplateArgumentKind kind; -        CompilerType pair_type = my_type.GetTemplateArgument(0, kind); -        if (kind != eTemplateArgumentKindType && kind != eTemplateArgumentKindTemplate && kind != eTemplateArgumentKindTemplateExpansion) -            return false; -        m_pair_type = pair_type; -    } -    else -        return false; -     -    return true; +bool LibstdcppMapIteratorSyntheticFrontEnd::Update() { +  ValueObjectSP valobj_sp = m_backend.GetSP(); +  if (!valobj_sp) +    return false; + +  TargetSP target_sp(valobj_sp->GetTargetSP()); + +  if (!target_sp) +    return false; + +  bool is_64bit = (target_sp->GetArchitecture().GetAddressByteSize() == 8); + +  if (!valobj_sp) +    return false; +  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); + +  ValueObjectSP _M_node_sp( +      valobj_sp->GetChildMemberWithName(ConstString("_M_node"), true)); +  if (!_M_node_sp) +    return false; + +  m_pair_address = _M_node_sp->GetValueAsUnsigned(0); +  if (m_pair_address == 0) +    return false; + +  m_pair_address += (is_64bit ? 32 : 16); + +  CompilerType my_type(valobj_sp->GetCompilerType()); +  if (my_type.GetNumTemplateArguments() >= 1) { +    TemplateArgumentKind kind; +    CompilerType pair_type = my_type.GetTemplateArgument(0, kind); +    if (kind != eTemplateArgumentKindType && +        kind != eTemplateArgumentKindTemplate && +        kind != eTemplateArgumentKindTemplateExpansion) +      return false; +    m_pair_type = pair_type; +  } else +    return false; + +  return true;  } -size_t -LibstdcppMapIteratorSyntheticFrontEnd::CalculateNumChildren () -{ -    return 2; +size_t LibstdcppMapIteratorSyntheticFrontEnd::CalculateNumChildren() { +  return 2;  }  lldb::ValueObjectSP -LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx) -{ -    if (m_pair_address != 0 && m_pair_type) -    { -        if (!m_pair_sp) -            m_pair_sp = CreateValueObjectFromAddress("pair", m_pair_address, m_exe_ctx_ref, m_pair_type); -        if (m_pair_sp) -            return m_pair_sp->GetChildAtIndex(idx, true); -    } -    return lldb::ValueObjectSP(); +LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex(size_t idx) { +  if (m_pair_address != 0 && m_pair_type) { +    if (!m_pair_sp) +      m_pair_sp = CreateValueObjectFromAddress("pair", m_pair_address, +                                               m_exe_ctx_ref, m_pair_type); +    if (m_pair_sp) +      return m_pair_sp->GetChildAtIndex(idx, true); +  } +  return lldb::ValueObjectSP();  } -bool -LibstdcppMapIteratorSyntheticFrontEnd::MightHaveChildren () -{ -    return true; -} +bool LibstdcppMapIteratorSyntheticFrontEnd::MightHaveChildren() { return true; } -size_t -LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) -{ -    if (name == ConstString("first")) -        return 0; -    if (name == ConstString("second")) -        return 1; -    return UINT32_MAX; +size_t LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName( +    const ConstString &name) { +  if (name == ConstString("first")) +    return 0; +  if (name == ConstString("second")) +    return 1; +  return UINT32_MAX;  } -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    return (valobj_sp ? new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp) : nullptr); +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp) +                    : nullptr);  }  /*   (lldb) fr var ibeg --ptr-depth 1 - (__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >) ibeg = { + (__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >) + ibeg = {   _M_current = 0x00000001001037a0 {   *_M_current = 1   }   }   */ -SyntheticChildrenFrontEnd* -lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) -{ -    static ConstString g_item_name; -    if (!g_item_name) -        g_item_name.SetCString("_M_current"); -    return (valobj_sp ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name) : nullptr); +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  static ConstString g_item_name; +  if (!g_item_name) +    g_item_name.SetCString("_M_current"); +  return (valobj_sp +              ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name) +              : nullptr);  } -lldb_private::formatters::VectorIteratorSyntheticFrontEnd::VectorIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp, -                                                                                            ConstString item_name) : -    SyntheticChildrenFrontEnd(*valobj_sp), -    m_exe_ctx_ref(), -    m_item_name(item_name), -    m_item_sp() -{ -    if (valobj_sp) -        Update(); +lldb_private::formatters::VectorIteratorSyntheticFrontEnd:: +    VectorIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp, +                                    ConstString item_name) +    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), +      m_item_name(item_name), m_item_sp() { +  if (valobj_sp) +    Update();  } -bool -VectorIteratorSyntheticFrontEnd::Update() -{ -    m_item_sp.reset(); -     -    ValueObjectSP valobj_sp = m_backend.GetSP(); -    if (!valobj_sp) -        return false; -     -    if (!valobj_sp) -        return false; -     -    ValueObjectSP item_ptr(valobj_sp->GetChildMemberWithName(m_item_name,true)); -    if (!item_ptr) -        return false; -    if (item_ptr->GetValueAsUnsigned(0) == 0) -        return false; -    Error err; -    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); -    m_item_sp = CreateValueObjectFromAddress("item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref, item_ptr->GetCompilerType().GetPointeeType()); -    if (err.Fail()) -        m_item_sp.reset(); +bool VectorIteratorSyntheticFrontEnd::Update() { +  m_item_sp.reset(); + +  ValueObjectSP valobj_sp = m_backend.GetSP(); +  if (!valobj_sp)      return false; -} -size_t -VectorIteratorSyntheticFrontEnd::CalculateNumChildren() -{ -    return 1; +  if (!valobj_sp) +    return false; + +  ValueObjectSP item_ptr(valobj_sp->GetChildMemberWithName(m_item_name, true)); +  if (!item_ptr) +    return false; +  if (item_ptr->GetValueAsUnsigned(0) == 0) +    return false; +  Error err; +  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); +  m_item_sp = CreateValueObjectFromAddress( +      "item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref, +      item_ptr->GetCompilerType().GetPointeeType()); +  if (err.Fail()) +    m_item_sp.reset(); +  return false;  } +size_t VectorIteratorSyntheticFrontEnd::CalculateNumChildren() { return 1; } +  lldb::ValueObjectSP -VectorIteratorSyntheticFrontEnd::GetChildAtIndex(size_t idx) -{ -    if (idx == 0) -        return m_item_sp; -    return lldb::ValueObjectSP(); +VectorIteratorSyntheticFrontEnd::GetChildAtIndex(size_t idx) { +  if (idx == 0) +    return m_item_sp; +  return lldb::ValueObjectSP();  } -bool -VectorIteratorSyntheticFrontEnd::MightHaveChildren() -{ -    return true; -} +bool VectorIteratorSyntheticFrontEnd::MightHaveChildren() { return true; } -size_t -VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name) -{ -    if (name == ConstString("item")) -        return 0; -    return UINT32_MAX; +size_t VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName( +    const ConstString &name) { +  if (name == ConstString("item")) +    return 0; +  return UINT32_MAX;  } -bool -lldb_private::formatters::LibStdcppStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) -{ -    const bool scalar_is_load_addr = true; -    AddressType addr_type; -    lldb::addr_t addr_of_string = valobj.GetAddressOf(scalar_is_load_addr, &addr_type); -    if (addr_of_string != LLDB_INVALID_ADDRESS) -    { -        switch (addr_type) -        { -            case eAddressTypeLoad: -            { -                ProcessSP process_sp(valobj.GetProcessSP()); -                if (!process_sp) -                    return false; - -                StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); -                Error error; -                lldb::addr_t addr_of_data = process_sp->ReadPointerFromMemory(addr_of_string, error); -                if (error.Fail() || addr_of_data == 0 || addr_of_data == LLDB_INVALID_ADDRESS) -                    return false; -                options.SetLocation(addr_of_data); -                options.SetProcessSP(process_sp); -                options.SetStream(&stream); -                options.SetNeedsZeroTermination(false); -                options.SetBinaryZeroIsTerminator(true); -                lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(addr_of_string + process_sp->GetAddressByteSize(), error); -                if (error.Fail()) -                    return false; -                options.SetSourceSize(size_of_data); - -                if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options)) -                { -                    stream.Printf("Summary Unavailable"); -                    return true; -                } -                else -                    return true; -            } -                break; -            case eAddressTypeHost: -                break; -            case eAddressTypeInvalid: -            case eAddressTypeFile: -                break; -        } +bool lldb_private::formatters::LibStdcppStringSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { +  const bool scalar_is_load_addr = true; +  AddressType addr_type; +  lldb::addr_t addr_of_string = +      valobj.GetAddressOf(scalar_is_load_addr, &addr_type); +  if (addr_of_string != LLDB_INVALID_ADDRESS) { +    switch (addr_type) { +    case eAddressTypeLoad: { +      ProcessSP process_sp(valobj.GetProcessSP()); +      if (!process_sp) +        return false; + +      StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); +      Error error; +      lldb::addr_t addr_of_data = +          process_sp->ReadPointerFromMemory(addr_of_string, error); +      if (error.Fail() || addr_of_data == 0 || +          addr_of_data == LLDB_INVALID_ADDRESS) +        return false; +      options.SetLocation(addr_of_data); +      options.SetProcessSP(process_sp); +      options.SetStream(&stream); +      options.SetNeedsZeroTermination(false); +      options.SetBinaryZeroIsTerminator(true); +      lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory( +          addr_of_string + process_sp->GetAddressByteSize(), error); +      if (error.Fail()) +        return false; +      options.SetSourceSize(size_of_data); + +      if (!StringPrinter::ReadStringAndDumpToStream< +              StringPrinter::StringElementType::UTF8>(options)) { +        stream.Printf("Summary Unavailable"); +        return true; +      } else +        return true; +    } break; +    case eAddressTypeHost: +      break; +    case eAddressTypeInvalid: +    case eAddressTypeFile: +      break;      } -    return false; +  } +  return false;  } -bool -lldb_private::formatters::LibStdcppWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) -{ -    const bool scalar_is_load_addr = true; -    AddressType addr_type; -    lldb::addr_t addr_of_string = valobj.GetAddressOf(scalar_is_load_addr, &addr_type); -    if (addr_of_string != LLDB_INVALID_ADDRESS) -    { -        switch (addr_type) -        { -            case eAddressTypeLoad: -            { -                ProcessSP process_sp(valobj.GetProcessSP()); -                if (!process_sp) -                    return false; - -                CompilerType wchar_compiler_type = valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); - -                if (!wchar_compiler_type) -                    return false; - -                const uint32_t wchar_size = wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here - -                StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); -                Error error; -                lldb::addr_t addr_of_data = process_sp->ReadPointerFromMemory(addr_of_string, error); -                if (error.Fail() || addr_of_data == 0 || addr_of_data == LLDB_INVALID_ADDRESS) -                    return false; -                options.SetLocation(addr_of_data); -                options.SetProcessSP(process_sp); -                options.SetStream(&stream); -                options.SetNeedsZeroTermination(false); -                options.SetBinaryZeroIsTerminator(false); -                lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(addr_of_string + process_sp->GetAddressByteSize(), error); -                if (error.Fail()) -                    return false; -                options.SetSourceSize(size_of_data); -                options.SetPrefixToken("L"); - -                switch (wchar_size) -                { -                    case 8: -                        return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options); -                    case 16: -                        return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options); -                    case 32: -                        return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options); -                    default: -                        stream.Printf("size for wchar_t is not valid"); -                        return true; -                } -                return true; -            } -                break; -            case eAddressTypeHost: -                break; -            case eAddressTypeInvalid: -            case eAddressTypeFile: -                break; -        } +bool lldb_private::formatters::LibStdcppWStringSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { +  const bool scalar_is_load_addr = true; +  AddressType addr_type; +  lldb::addr_t addr_of_string = +      valobj.GetAddressOf(scalar_is_load_addr, &addr_type); +  if (addr_of_string != LLDB_INVALID_ADDRESS) { +    switch (addr_type) { +    case eAddressTypeLoad: { +      ProcessSP process_sp(valobj.GetProcessSP()); +      if (!process_sp) +        return false; + +      CompilerType wchar_compiler_type = +          valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); + +      if (!wchar_compiler_type) +        return false; + +      const uint32_t wchar_size = wchar_compiler_type.GetBitSize( +          nullptr); // Safe to pass NULL for exe_scope here + +      StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); +      Error error; +      lldb::addr_t addr_of_data = +          process_sp->ReadPointerFromMemory(addr_of_string, error); +      if (error.Fail() || addr_of_data == 0 || +          addr_of_data == LLDB_INVALID_ADDRESS) +        return false; +      options.SetLocation(addr_of_data); +      options.SetProcessSP(process_sp); +      options.SetStream(&stream); +      options.SetNeedsZeroTermination(false); +      options.SetBinaryZeroIsTerminator(false); +      lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory( +          addr_of_string + process_sp->GetAddressByteSize(), error); +      if (error.Fail()) +        return false; +      options.SetSourceSize(size_of_data); +      options.SetPrefixToken("L"); + +      switch (wchar_size) { +      case 8: +        return StringPrinter::ReadStringAndDumpToStream< +            StringPrinter::StringElementType::UTF8>(options); +      case 16: +        return StringPrinter::ReadStringAndDumpToStream< +            StringPrinter::StringElementType::UTF16>(options); +      case 32: +        return StringPrinter::ReadStringAndDumpToStream< +            StringPrinter::StringElementType::UTF32>(options); +      default: +        stream.Printf("size for wchar_t is not valid"); +        return true; +      } +      return true; +    } break; +    case eAddressTypeHost: +      break; +    case eAddressTypeInvalid: +    case eAddressTypeFile: +      break;      } -    return false; +  } +  return false;  } -LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) -    : SyntheticChildrenFrontEnd(*valobj_sp) -{ -    if (valobj_sp) -        Update(); +LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd( +    lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp) { +  if (valobj_sp) +    Update();  } -size_t -LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren() -{ -    return 1; -} +size_t LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren() { return 1; }  lldb::ValueObjectSP -LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) -{ -    ValueObjectSP valobj_sp = m_backend.GetSP(); -    if (!valobj_sp) -        return lldb::ValueObjectSP(); - -    if (idx == 0) -        return valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true); -    else -        return lldb::ValueObjectSP(); -} +LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) { +  ValueObjectSP valobj_sp = m_backend.GetSP(); +  if (!valobj_sp) +    return lldb::ValueObjectSP(); -bool -LibStdcppSharedPtrSyntheticFrontEnd::Update() -{ -    return false; +  if (idx == 0) +    return valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true); +  else +    return lldb::ValueObjectSP();  } -bool -LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren() -{ -    return true; -} +bool LibStdcppSharedPtrSyntheticFrontEnd::Update() { return false; } + +bool LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren() { return true; } -size_t -LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name) -{ -    if (name == ConstString("_M_ptr")) -        return 0; -    return UINT32_MAX; +size_t LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName( +    const ConstString &name) { +  if (name == ConstString("_M_ptr")) +    return 0; +  return UINT32_MAX;  }  SyntheticChildrenFrontEnd * -lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, -                                                                     lldb::ValueObjectSP valobj_sp) -{ -    return (valobj_sp ? new LibStdcppSharedPtrSyntheticFrontEnd(valobj_sp) : nullptr); +lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibStdcppSharedPtrSyntheticFrontEnd(valobj_sp) +                    : nullptr);  } -bool -lldb_private::formatters::LibStdcppSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream, -                                                               const TypeSummaryOptions &options) -{ -    ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); -    if (!valobj_sp) -        return false; - -    ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true)); -    if (!ptr_sp) -        return false; +bool lldb_private::formatters::LibStdcppSmartPointerSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { +  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); +  if (!valobj_sp) +    return false; -    ValueObjectSP usecount_sp( -        valobj_sp->GetChildAtNamePath({ConstString("_M_refcount"), ConstString("_M_pi"), ConstString("_M_use_count")})); -    if (!usecount_sp) -        return false; +  ValueObjectSP ptr_sp( +      valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true)); +  if (!ptr_sp) +    return false; -    if (ptr_sp->GetValueAsUnsigned(0) == 0 || usecount_sp->GetValueAsUnsigned(0) == 0) -    { -        stream.Printf("nullptr"); -        return true; -    } +  ValueObjectSP usecount_sp(valobj_sp->GetChildAtNamePath( +      {ConstString("_M_refcount"), ConstString("_M_pi"), +       ConstString("_M_use_count")})); +  if (!usecount_sp) +    return false; -    Error error; -    ValueObjectSP pointee_sp = ptr_sp->Dereference(error); -    if (pointee_sp && error.Success()) -    { -        if (pointee_sp->DumpPrintableRepresentation(stream, ValueObject::eValueObjectRepresentationStyleSummary, -                                                    lldb::eFormatInvalid, -                                                    ValueObject::ePrintableRepresentationSpecialCasesDisable, false)) -        { -            return true; -        } +  if (ptr_sp->GetValueAsUnsigned(0) == 0 || +      usecount_sp->GetValueAsUnsigned(0) == 0) { +    stream.Printf("nullptr"); +    return true; +  } + +  Error error; +  ValueObjectSP pointee_sp = ptr_sp->Dereference(error); +  if (pointee_sp && error.Success()) { +    if (pointee_sp->DumpPrintableRepresentation( +            stream, ValueObject::eValueObjectRepresentationStyleSummary, +            lldb::eFormatInvalid, +            ValueObject::PrintableRepresentationSpecialCases::eDisable, +            false)) { +      return true;      } +  } -    stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0)); -    return true; +  stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0)); +  return true;  } diff --git a/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/source/Plugins/Language/CPlusPlus/LibStdcpp.h index b84c0ff831eb..72e169f50395 100644 --- a/source/Plugins/Language/CPlusPlus/LibStdcpp.h +++ b/source/Plugins/Language/CPlusPlus/LibStdcpp.h @@ -1,4 +1,4 @@ -//===-- LibStdCpp.h ---------------------------------------------------*- C++ -*-===// +//===-- LibStdcpp.h ---------------------------------------------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -16,23 +16,45 @@  #include "lldb/DataFormatters/TypeSynthetic.h"  namespace lldb_private { -    namespace formatters -    { -        bool -        LibStdcppStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libcstdc++ c++11 std::string +namespace formatters { +bool LibStdcppStringSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &options); // libcstdc++ c++11 std::string -        bool -        LibStdcppWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libcstdc++ c++11 std::wstring +bool LibStdcppWStringSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &options); // libcstdc++ c++11 std::wstring -        bool -        LibStdcppSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libstdc++ std::shared_ptr<> and std::weak_ptr<> +bool LibStdcppSmartPointerSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions +        &options); // libstdc++ std::shared_ptr<> and std::weak_ptr<> -        SyntheticChildrenFrontEnd* LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); +bool LibStdcppUniquePointerSummaryProvider( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &options); // libstdc++ std::unique_ptr<> -        SyntheticChildrenFrontEnd* LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); +SyntheticChildrenFrontEnd * +LibstdcppMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                             lldb::ValueObjectSP); -        SyntheticChildrenFrontEnd* LibStdcppSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); -    } // namespace formatters +SyntheticChildrenFrontEnd * +LibStdcppTupleSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                       lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * +LibStdcppVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                                lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * +LibStdcppSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                           lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * +LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, +                                           lldb::ValueObjectSP); + +} // namespace formatters  } // namespace lldb_private  #endif // liblldb_LibStdCpp_h_ diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp new file mode 100644 index 000000000000..c4a6e3d227b0 --- /dev/null +++ b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp @@ -0,0 +1,109 @@ +//===-- LibStdcppTuple.cpp --------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LibStdcpp.h" + +#include "lldb/Core/ConstString.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/DataFormatters/FormattersHelpers.h" +#include "lldb/DataFormatters/TypeSynthetic.h" + +#include <memory> +#include <vector> + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +namespace { + +class LibStdcppTupleSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: +  explicit LibStdcppTupleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +private: +  std::vector<ValueObjectSP> m_members; +}; + +} // end of anonymous namespace + +LibStdcppTupleSyntheticFrontEnd::LibStdcppTupleSyntheticFrontEnd( +    lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp) { +  Update(); +} + +bool LibStdcppTupleSyntheticFrontEnd::Update() { +  m_members.clear(); + +  ValueObjectSP valobj_backend_sp = m_backend.GetSP(); +  if (!valobj_backend_sp) +    return false; + +  ValueObjectSP next_child_sp = valobj_backend_sp->GetNonSyntheticValue(); +  while (next_child_sp != nullptr) { +    ValueObjectSP current_child = next_child_sp; +    next_child_sp = nullptr; + +    size_t child_count = current_child->GetNumChildren(); +    for (size_t i = 0; i < child_count; ++i) { +      ValueObjectSP child_sp = current_child->GetChildAtIndex(i, true); +      llvm::StringRef name_str = child_sp->GetName().GetStringRef(); +      if (name_str.startswith("std::_Tuple_impl<")) { +        next_child_sp = child_sp; +      } else if (name_str.startswith("std::_Head_base<")) { +        ValueObjectSP value_sp = +            child_sp->GetChildMemberWithName(ConstString("_M_head_impl"), true); +        if (value_sp) { +          StreamString name; +          name.Printf("[%zd]", m_members.size()); +          value_sp->SetName(ConstString(name.GetString())); + +          m_members.push_back(value_sp); +        } +      } +    } +  } + +  return false; +} + +bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; } + +lldb::ValueObjectSP +LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(size_t idx) { +  if (idx < m_members.size()) +    return m_members[idx]; +  return lldb::ValueObjectSP(); +} + +size_t LibStdcppTupleSyntheticFrontEnd::CalculateNumChildren() { +  return m_members.size(); +} + +size_t LibStdcppTupleSyntheticFrontEnd::GetIndexOfChildWithName( +    const ConstString &name) { +  return ExtractIndexFromString(name.GetCString()); +} + +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibStdcppTupleSyntheticFrontEnd(valobj_sp) : nullptr); +} diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp new file mode 100644 index 000000000000..4eb3b95afb4e --- /dev/null +++ b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp @@ -0,0 +1,151 @@ +//===-- LibStdcppUniquePointer.cpp ------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LibStdcpp.h" + +#include "lldb/Core/ConstString.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/DataFormatters/FormattersHelpers.h" +#include "lldb/DataFormatters/TypeSynthetic.h" + +#include <memory> +#include <vector> + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +namespace { + +class LibStdcppUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: +  explicit LibStdcppUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + +  size_t CalculateNumChildren() override; + +  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + +  bool Update() override; + +  bool MightHaveChildren() override; + +  size_t GetIndexOfChildWithName(const ConstString &name) override; + +  bool GetSummary(Stream &stream, const TypeSummaryOptions &options); + +private: +  ValueObjectSP m_ptr_obj; +  ValueObjectSP m_obj_obj; +  ValueObjectSP m_del_obj; +}; + +} // end of anonymous namespace + +LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd( +    lldb::ValueObjectSP valobj_sp) +    : SyntheticChildrenFrontEnd(*valobj_sp) { +  Update(); +} + +bool LibStdcppUniquePtrSyntheticFrontEnd::Update() { +  ValueObjectSP valobj_backend_sp = m_backend.GetSP(); +  if (!valobj_backend_sp) +    return false; + +  ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue(); +  if (!valobj_sp) +    return false; + +  ValueObjectSP tuple_sp = +      valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true); +  if (!tuple_sp) +    return false; + +  std::unique_ptr<SyntheticChildrenFrontEnd> tuple_frontend( +      LibStdcppTupleSyntheticFrontEndCreator(nullptr, tuple_sp)); + +  m_ptr_obj = tuple_frontend->GetChildAtIndex(0); +  if (m_ptr_obj) +    m_ptr_obj->SetName(ConstString("pointer")); + +  m_del_obj = tuple_frontend->GetChildAtIndex(1); +  if (m_del_obj) +    m_del_obj->SetName(ConstString("deleter")); + +  if (m_ptr_obj) { +    Error error; +    m_obj_obj = m_ptr_obj->Dereference(error); +    if (error.Success()) { +      m_obj_obj->SetName(ConstString("object")); +    } +  } + +  return false; +} + +bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; } + +lldb::ValueObjectSP +LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) { +  if (idx == 0) +    return m_obj_obj; +  if (idx == 1) +    return m_del_obj; +  if (idx == 2) +    return m_ptr_obj; +  return lldb::ValueObjectSP(); +} + +size_t LibStdcppUniquePtrSyntheticFrontEnd::CalculateNumChildren() { +  if (m_del_obj) +    return 2; +  if (m_ptr_obj && m_ptr_obj->GetValueAsUnsigned(0) != 0) +    return 1; +  return 0; +} + +size_t LibStdcppUniquePtrSyntheticFrontEnd::GetIndexOfChildWithName( +    const ConstString &name) { +  if (name == ConstString("obj") || name == ConstString("object")) +    return 0; +  if (name == ConstString("del") || name == ConstString("deleter")) +    return 1; +  if (name == ConstString("ptr") || name == ConstString("pointer")) +    return 2; +  return UINT32_MAX; +} + +bool LibStdcppUniquePtrSyntheticFrontEnd::GetSummary( +    Stream &stream, const TypeSummaryOptions &options) { +  if (!m_ptr_obj) +    return false; + +  bool success; +  uint64_t ptr_value = m_ptr_obj->GetValueAsUnsigned(0, &success); +  if (!success) +    return false; +  if (ptr_value == 0) +    stream.Printf("nullptr"); +  else +    stream.Printf("0x%" PRIx64, ptr_value); +  return true; +} + +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator( +    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { +  return (valobj_sp ? new LibStdcppUniquePtrSyntheticFrontEnd(valobj_sp) +                    : nullptr); +} + +bool lldb_private::formatters::LibStdcppUniquePointerSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { +  LibStdcppUniquePtrSyntheticFrontEnd formatter(valobj.GetSP()); +  return formatter.GetSummary(stream, options); +} | 
