diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus')
19 files changed, 3938 insertions, 3404 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp index 92e30d5..db7c246 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h index 5e6c748..e5008a8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 33d22bf..b5527ed 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h index f0fc07e..be5cbae 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index a2c45fb..346ea0b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h index bfb03bd..0bee3bd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index beb89b8..82441a6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h index ae00bc0..a863851 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp index a20d7f7..dea52e2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h index 5cf729b..e2cc011 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp index 54fddd1..b7aa70c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp index 35cee56..16bd631 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index d898692..759a700 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp index a547695..5fe4b3a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp index ed26eae..b5c9b6d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 6d6f915..f931a8d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h index b84c0ff..72e169f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp new file mode 100644 index 0000000..c4a6e3d --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp new file mode 100644 index 0000000..4eb3b95 --- /dev/null +++ b/contrib/llvm/tools/lldb/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); +} |