[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Move std::map iterator formatter into LibCxxMap.cpp (PR #97687)

2024-07-04 Thread Michael Buch via lldb-commits

https://github.com/Michael137 created 
https://github.com/llvm/llvm-project/pull/97687

The two formatters follow very similar techniques to retrieve data out of the 
map. We're changing this for `std::map` in 
https://github.com/llvm/llvm-project/pull/97579 and plan to change it in the 
same way for the iterator formatter. Having them in the same place will allow 
us to re-use some of the logic (and we won't have to repeat some of the 
clarification comments).

>From f6b3e6055a9e2263f61e3f70d7a97ddbb7db5ab0 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 4 Jul 2024 09:30:19 +0200
Subject: [PATCH] [lldb][DataFormatter][NFC] Move std::map iterator formatter
 into LibCxxMap.cpp

The two formatters follow very similar techniques to retrieve data out of the 
map. We're changing this for `std::map` in 
https://github.com/llvm/llvm-project/pull/97579 and plan to change it in the 
same way for the iterator formatter. Having them in the same place will allow 
us to re-use some of the logic (and we won't have to repeat some of the 
clarification comments).
---
 .../Plugins/Language/CPlusPlus/LibCxx.cpp | 188 --
 .../Plugins/Language/CPlusPlus/LibCxx.h   |  29 +--
 .../Plugins/Language/CPlusPlus/LibCxxMap.cpp  | 187 +
 3 files changed, 191 insertions(+), 213 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index ad467c3966e609..05cfa0568c25d4 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -202,194 +202,6 @@ bool 
lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
   return true;
 }
 
-/*
- (lldb) fr var ibeg --raw --ptr-depth 1
- (std::__1::__map_iterator,
- std::__1::allocator > >, std::__1::__tree_node,
- std::__1::allocator > >, void *> *, long> >) ibeg = {
- __i_ = {
- __ptr_ = 0x000100103870 {
- std::__1::__tree_node_base = {
- std::__1::__tree_end_node *> = {
- __left_ = 0x
- }
- __right_ = 0x
- __parent_ = 0x0001001038b0
- __is_black_ = true
- }
- __value_ = {
- first = 0
- second = { std::string }
- */
-
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
-LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-: SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr(), m_pair_sp() {
-  if (valobj_sp)
-Update();
-}
-
-lldb::ChildCacheState
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
-  m_pair_sp.reset();
-  m_pair_ptr = nullptr;
-
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  TargetSP target_sp(valobj_sp->GetTargetSP());
-
-  if (!target_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  // 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("__i_"));
-  if (!__i_) {
-m_pair_ptr = nullptr;
-return lldb::ChildCacheState::eRefetch;
-  }
-  CompilerType pair_type(
-  __i_->GetCompilerType().GetTypeTemplateArgument(0));
-  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 lldb::ChildCacheState::eRefetch;
-  }
-
-  auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRE

[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Move std::map iterator formatter into LibCxxMap.cpp (PR #97687)

2024-07-04 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)


Changes

The two formatters follow very similar techniques to retrieve data out of the 
map. We're changing this for `std::map` in 
https://github.com/llvm/llvm-project/pull/97579 and plan to change it in the 
same way for the iterator formatter. Having them in the same place will allow 
us to re-use some of the logic (and we won't have to repeat some of the 
clarification comments).

---
Full diff: https://github.com/llvm/llvm-project/pull/97687.diff


3 Files Affected:

- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp (-188) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.h (+4-25) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp (+187) 


``diff
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index ad467c3966e60..05cfa0568c25d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -202,194 +202,6 @@ bool 
lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
   return true;
 }
 
-/*
- (lldb) fr var ibeg --raw --ptr-depth 1
- (std::__1::__map_iterator,
- std::__1::allocator > >, std::__1::__tree_node,
- std::__1::allocator > >, void *> *, long> >) ibeg = {
- __i_ = {
- __ptr_ = 0x000100103870 {
- std::__1::__tree_node_base = {
- std::__1::__tree_end_node *> = {
- __left_ = 0x
- }
- __right_ = 0x
- __parent_ = 0x0001001038b0
- __is_black_ = true
- }
- __value_ = {
- first = 0
- second = { std::string }
- */
-
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
-LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-: SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr(), m_pair_sp() {
-  if (valobj_sp)
-Update();
-}
-
-lldb::ChildCacheState
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
-  m_pair_sp.reset();
-  m_pair_ptr = nullptr;
-
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  TargetSP target_sp(valobj_sp->GetTargetSP());
-
-  if (!target_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  // 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("__i_"));
-  if (!__i_) {
-m_pair_ptr = nullptr;
-return lldb::ChildCacheState::eRefetch;
-  }
-  CompilerType pair_type(
-  __i_->GetCompilerType().GetTypeTemplateArgument(0));
-  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 lldb::ChildCacheState::eRefetch;
-  }
-
-  auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS));
-  m_pair_ptr = nullptr;
-  if (addr && addr != LLDB_INVALID_ADDRESS) {
-auto ts = pair_type.GetTypeSystem();
-auto ast_ctx = ts.dyn_cast_or_null();
-if (!ast_ctx)
-  return lldb::ChildCacheState::eRefetch;
-
-// Mimick layout of std::__tree_iterator::__ptr_ and read it in
-// from process memory.
-//
-// The following shows the contiguous block of memory:
-//
-//+-+ class __tree_end_node
-// __ptr_ |

[Lldb-commits] [lldb] 927def4 - Revert "[lldb] Print empty enums as if they were unrecognised normal enums (#97553)"

2024-07-04 Thread David Spickett via lldb-commits

Author: David Spickett
Date: 2024-07-04T07:49:36Z
New Revision: 927def49728371d746476e79a6570cd93a4d335c

URL: 
https://github.com/llvm/llvm-project/commit/927def49728371d746476e79a6570cd93a4d335c
DIFF: 
https://github.com/llvm/llvm-project/commit/927def49728371d746476e79a6570cd93a4d335c.diff

LOG: Revert "[lldb] Print empty enums as if they were unrecognised normal enums 
(#97553)"

This reverts commit 41fddc4ec3302f125a5b84ae86c8027dedc89984.

Due to build errors with gcc passing signed ints to unsigned ints.

Added: 


Modified: 
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test
lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp

Removed: 




diff  --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp 
b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index f70efe5ed57e4..9c77a5d6e66ee 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -8656,25 +8656,20 @@ static bool DumpEnumValue(const clang::QualType 
&qual_type, Stream &s,
   // every enumerator is either a one bit value or a superset of the previous
   // enumerators. Also 0 doesn't make sense when the enumerators are used as
   // flags.
-  clang::EnumDecl::enumerator_range enumerators = enum_decl->enumerators();
-  if (enumerators.empty())
-can_be_bitfield = false;
-  else {
-for (auto *enumerator : enumerators) {
-  llvm::APSInt init_val = enumerator->getInitVal();
-  uint64_t val = qual_type_is_signed ? init_val.getSExtValue()
- : init_val.getZExtValue();
-  if (qual_type_is_signed)
-val = llvm::SignExtend64(val, 8 * byte_size);
-  if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0)
-can_be_bitfield = false;
-  covered_bits |= val;
-  ++num_enumerators;
-  if (val == enum_svalue) {
-// Found an exact match, that's all we need to do.
-s.PutCString(enumerator->getNameAsString());
-return true;
-  }
+  for (auto *enumerator : enum_decl->enumerators()) {
+llvm::APSInt init_val = enumerator->getInitVal();
+uint64_t val =
+qual_type_is_signed ? init_val.getSExtValue() : 
init_val.getZExtValue();
+if (qual_type_is_signed)
+  val = llvm::SignExtend64(val, 8 * byte_size);
+if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0)
+  can_be_bitfield = false;
+covered_bits |= val;
+++num_enumerators;
+if (val == enum_svalue) {
+  // Found an exact match, that's all we need to do.
+  s.PutCString(enumerator->getNameAsString());
+  return true;
 }
   }
 

diff  --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test 
b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test
index b2c792ed6003e..548dd6cdbc275 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test
@@ -22,5 +22,5 @@ PRINTEC: use of undeclared identifier 'EC'
 
 RUN: %lldb %t -b -o "target variable a e ec" | FileCheck --check-prefix=VARS %s
 VARS: (const (unnamed struct)) a = 
-VARS: (const (unnamed enum)) e = 1
-VARS: (const (unnamed enum)) ec = 1
+VARS: (const (unnamed enum)) e = 0x1
+VARS: (const (unnamed enum)) ec = 0x1

diff  --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp 
b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp
index af6fa55bab171..a7ccd74721f66 100644
--- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp
+++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp
@@ -71,13 +71,12 @@ class ValueObjectMockProcessTest : public ::testing::Test {
   }
 
   CompilerType
-  MakeEnumType(const std::vector> enumerators,
-   bool is_signed) {
-CompilerType int_type = m_type_system->GetBuiltinTypeForEncodingAndBitSize(
-is_signed ? lldb::eEncodingSint : lldb::eEncodingUint, 32);
+  MakeEnumType(const std::vector> enumerators) {
+CompilerType uint_type = 
m_type_system->GetBuiltinTypeForEncodingAndBitSize(
+lldb::eEncodingUint, 32);
 CompilerType enum_type = m_type_system->CreateEnumerationType(
 "TestEnum", m_type_system->GetTranslationUnitDecl(),
-OptionalClangModuleID(), Declaration(), int_type, false);
+OptionalClangModuleID(), Declaration(), uint_type, false);
 
 m_type_system->StartTagDeclarationDefinition(enum_type);
 Declaration decl;
@@ -124,27 +123,12 @@ class ValueObjectMockProcessTest : public ::testing::Test 
{
   lldb::ProcessSP m_process_sp;
 };
 
-TEST_F(ValueObjectMockProcessTest, EmptyEnum) {
-  // All values of an empty enum should be shown as plain numbers.
-  TestDumpValueObject(MakeEnumType({}, false),
-  {{0, 

[Lldb-commits] [lldb] 328d9f6 - Reland "[lldb] Print empty enums as if they were unrecognised normal enums (#97553)"

2024-07-04 Thread David Spickett via lldb-commits

Author: David Spickett
Date: 2024-07-04T08:51:23Z
New Revision: 328d9f62976defb96cba8102ea54f44cf88c8032

URL: 
https://github.com/llvm/llvm-project/commit/328d9f62976defb96cba8102ea54f44cf88c8032
DIFF: 
https://github.com/llvm/llvm-project/commit/328d9f62976defb96cba8102ea54f44cf88c8032.diff

LOG: Reland "[lldb] Print empty enums as if they were unrecognised normal enums 
(#97553)"

This reverts commit 927def49728371d746476e79a6570cd93a4d335c.

I've refactored the tests so that we're explicit about whether the
enum is signed or not. Which means we use the proper types
throughout.

Added: 


Modified: 
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test
lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp

Removed: 




diff  --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp 
b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 9c77a5d6e66ee..f70efe5ed57e4 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -8656,20 +8656,25 @@ static bool DumpEnumValue(const clang::QualType 
&qual_type, Stream &s,
   // every enumerator is either a one bit value or a superset of the previous
   // enumerators. Also 0 doesn't make sense when the enumerators are used as
   // flags.
-  for (auto *enumerator : enum_decl->enumerators()) {
-llvm::APSInt init_val = enumerator->getInitVal();
-uint64_t val =
-qual_type_is_signed ? init_val.getSExtValue() : 
init_val.getZExtValue();
-if (qual_type_is_signed)
-  val = llvm::SignExtend64(val, 8 * byte_size);
-if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0)
-  can_be_bitfield = false;
-covered_bits |= val;
-++num_enumerators;
-if (val == enum_svalue) {
-  // Found an exact match, that's all we need to do.
-  s.PutCString(enumerator->getNameAsString());
-  return true;
+  clang::EnumDecl::enumerator_range enumerators = enum_decl->enumerators();
+  if (enumerators.empty())
+can_be_bitfield = false;
+  else {
+for (auto *enumerator : enumerators) {
+  llvm::APSInt init_val = enumerator->getInitVal();
+  uint64_t val = qual_type_is_signed ? init_val.getSExtValue()
+ : init_val.getZExtValue();
+  if (qual_type_is_signed)
+val = llvm::SignExtend64(val, 8 * byte_size);
+  if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0)
+can_be_bitfield = false;
+  covered_bits |= val;
+  ++num_enumerators;
+  if (val == enum_svalue) {
+// Found an exact match, that's all we need to do.
+s.PutCString(enumerator->getNameAsString());
+return true;
+  }
 }
   }
 

diff  --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test 
b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test
index 548dd6cdbc275..b2c792ed6003e 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test
@@ -22,5 +22,5 @@ PRINTEC: use of undeclared identifier 'EC'
 
 RUN: %lldb %t -b -o "target variable a e ec" | FileCheck --check-prefix=VARS %s
 VARS: (const (unnamed struct)) a = 
-VARS: (const (unnamed enum)) e = 0x1
-VARS: (const (unnamed enum)) ec = 0x1
+VARS: (const (unnamed enum)) e = 1
+VARS: (const (unnamed enum)) ec = 1

diff  --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp 
b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp
index a7ccd74721f66..950e981a3f5a4 100644
--- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp
+++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp
@@ -18,6 +18,8 @@
 
 #include "gtest/gtest.h"
 
+#include 
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -70,28 +72,12 @@ class ValueObjectMockProcessTest : public ::testing::Test {
 m_type_system = m_holder->GetAST();
   }
 
-  CompilerType
-  MakeEnumType(const std::vector> enumerators) {
-CompilerType uint_type = 
m_type_system->GetBuiltinTypeForEncodingAndBitSize(
-lldb::eEncodingUint, 32);
-CompilerType enum_type = m_type_system->CreateEnumerationType(
-"TestEnum", m_type_system->GetTranslationUnitDecl(),
-OptionalClangModuleID(), Declaration(), uint_type, false);
-
-m_type_system->StartTagDeclarationDefinition(enum_type);
-Declaration decl;
-for (auto [name, value] : enumerators)
-  m_type_system->AddEnumerationValueToEnumerationType(enum_type, decl, 
name,
-  value, 32);
-m_type_system->CompleteTagDeclarationDefinition(enum_type);
-
-return enum_type;
-  }
-
-  void TestDumpValueObject(
-  CompilerType enum_type,
-  const std::vector<
-   

[Lldb-commits] [lldb] [LLDB] Support exception breakpoints for plugin-provided languages (PR #97675)

2024-07-04 Thread David Spickett via lldb-commits

DavidSpickett wrote:

> This method is used in addition to the hardcoded list and, as an example, I'm 
> using it for the ObjC language support.

And does this list include languages that are not plugin provided?

I was wondering why only Objective C changed, but if the rest are not plugins 
then this makes sense.

https://github.com/llvm/llvm-project/pull/97675
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB] Support exception breakpoints for plugin-provided languages (PR #97675)

2024-07-04 Thread David Spickett via lldb-commits


@@ -245,7 +245,7 @@ class Language : public PluginInterface {
   // a match.  But we wouldn't want this to match AnotherA::my_function.  The
   // user is specifying a truncated path, not a truncated set of characters.
   // This function does a language-aware comparison for those purposes.
-  virtual bool DemangledNameContainsPath(llvm::StringRef path, 
+  virtual bool DemangledNameContainsPath(llvm::StringRef path,

DavidSpickett wrote:

Unrelated change.

https://github.com/llvm/llvm-project/pull/97675
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB] Support exception breakpoints for plugin-provided languages (PR #97675)

2024-07-04 Thread David Spickett via lldb-commits

https://github.com/DavidSpickett approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/97675
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB] Support exception breakpoints for plugin-provided languages (PR #97675)

2024-07-04 Thread David Spickett via lldb-commits


@@ -319,6 +316,12 @@ class CommandObjectBreakpointSet : public 
CommandObjectParsed {
   error_context = "Unknown language type for exception breakpoint";
   break;
 default:
+  if (Language *languagePlugin = Language::FindPlugin(language)) {

DavidSpickett wrote:

You could drop the braces from the first if I think, but this is already in so 
many sets of braces I'd keep them for clarity's sake.

https://github.com/llvm/llvm-project/pull/97675
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] 07b3e2c - [LLDB] XFail on Windows TestThreadAPI.py test_StepInstruction

2024-07-04 Thread Muhammad Omair Javaid via lldb-commits

Author: Muhammad Omair Javaid
Date: 2024-07-04T15:59:05+05:00
New Revision: 07b3e2c0c68b93a3d4d89426dc7fd14cc31ca6be

URL: 
https://github.com/llvm/llvm-project/commit/07b3e2c0c68b93a3d4d89426dc7fd14cc31ca6be
DIFF: 
https://github.com/llvm/llvm-project/commit/07b3e2c0c68b93a3d4d89426dc7fd14cc31ca6be.diff

LOG: [LLDB] XFail on Windows TestThreadAPI.py test_StepInstruction

TestThreadAPI.py test_StepInstruction started failing after #97493

Following assertion fails but I am not sure if test will pass after
changing the test.

AssertionError: 'void __cdecl call_me(bool)' != 'call_me(bool)'

I have marked it as xfail I ll run it on a Windows machine to find
an appropriate fix.

https://lab.llvm.org/buildbot/#/builders/141/builds/476

Added: 


Modified: 
lldb/test/API/python_api/thread/TestThreadAPI.py

Removed: 




diff  --git a/lldb/test/API/python_api/thread/TestThreadAPI.py 
b/lldb/test/API/python_api/thread/TestThreadAPI.py
index d5fc77532d859..a74302263aa45 100644
--- a/lldb/test/API/python_api/thread/TestThreadAPI.py
+++ b/lldb/test/API/python_api/thread/TestThreadAPI.py
@@ -51,7 +51,8 @@ def test_negative_indexing(self):
 """Test SBThread.frame with negative indexes."""
 self.build()
 self.validate_negative_indexing()
-
+ 
+@expectedFailureAll(oslist=["windows"])
 def test_StepInstruction(self):
 """Test that StepInstruction preserves the plan stack."""
 self.build()



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Lldb/map iterator refactor (PR #97713)

2024-07-04 Thread Michael Buch via lldb-commits

https://github.com/Michael137 created 
https://github.com/llvm/llvm-project/pull/97713

Depends on https://github.com/llvm/llvm-project/pull/97687

Similar to https://github.com/llvm/llvm-project/pull/97579, this patch 
simplifies the way in which we retrieve the key/value pair of a `std::map` (in 
this case of the `std::map::iterator`).

We do this for the same reason: not only was the old logic hard to follow, and 
encoded the libc++ layout in non-obvious ways, it was also fragile to alignment 
miscalculations (https://github.com/llvm/llvm-project/pull/97443); this would 
break once the new layout of std::map landed as part of 
https://github.com/llvm/llvm-project/issues/93069.

Instead, this patch simply casts the `__iter_pointer` to the `__node_pointer` 
and uses a straightforward `GetChildMemberWithName("__value_")` to get to the 
key/value we care about.

We can eventually re-use the core-part of the `std::map` and 
`std::map::iterator` formatters. But it will be an easier to change to review 
once both simplifications landed.

>From f6b3e6055a9e2263f61e3f70d7a97ddbb7db5ab0 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 4 Jul 2024 09:30:19 +0200
Subject: [PATCH 1/2] [lldb][DataFormatter][NFC] Move std::map iterator
 formatter into LibCxxMap.cpp

The two formatters follow very similar techniques to retrieve data out of the 
map. We're changing this for `std::map` in 
https://github.com/llvm/llvm-project/pull/97579 and plan to change it in the 
same way for the iterator formatter. Having them in the same place will allow 
us to re-use some of the logic (and we won't have to repeat some of the 
clarification comments).
---
 .../Plugins/Language/CPlusPlus/LibCxx.cpp | 188 --
 .../Plugins/Language/CPlusPlus/LibCxx.h   |  29 +--
 .../Plugins/Language/CPlusPlus/LibCxxMap.cpp  | 187 +
 3 files changed, 191 insertions(+), 213 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index ad467c3966e60..05cfa0568c25d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -202,194 +202,6 @@ bool 
lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
   return true;
 }
 
-/*
- (lldb) fr var ibeg --raw --ptr-depth 1
- (std::__1::__map_iterator,
- std::__1::allocator > >, std::__1::__tree_node,
- std::__1::allocator > >, void *> *, long> >) ibeg = {
- __i_ = {
- __ptr_ = 0x000100103870 {
- std::__1::__tree_node_base = {
- std::__1::__tree_end_node *> = {
- __left_ = 0x
- }
- __right_ = 0x
- __parent_ = 0x0001001038b0
- __is_black_ = true
- }
- __value_ = {
- first = 0
- second = { std::string }
- */
-
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
-LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-: SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr(), m_pair_sp() {
-  if (valobj_sp)
-Update();
-}
-
-lldb::ChildCacheState
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
-  m_pair_sp.reset();
-  m_pair_ptr = nullptr;
-
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  TargetSP target_sp(valobj_sp->GetTargetSP());
-
-  if (!target_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  // 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("__i_"));
-  if (!__i_) {
-m_pair_ptr = nullptr;
-

[Lldb-commits] [lldb] [lldb][DataFormatter] Simplify libc++ std::map::iterator formatter (PR #97713)

2024-07-04 Thread Michael Buch via lldb-commits

https://github.com/Michael137 edited 
https://github.com/llvm/llvm-project/pull/97713
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][DataFormatter] Simplify libc++ std::map::iterator formatter (PR #97713)

2024-07-04 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)


Changes

Depends on https://github.com/llvm/llvm-project/pull/97687

Similar to https://github.com/llvm/llvm-project/pull/97579, this patch 
simplifies the way in which we retrieve the key/value pair of a `std::map` (in 
this case of the `std::map::iterator`).

We do this for the same reason: not only was the old logic hard to follow, and 
encoded the libc++ layout in non-obvious ways, it was also fragile to alignment 
miscalculations (https://github.com/llvm/llvm-project/pull/97443); this would 
break once the new layout of std::map landed as part of 
https://github.com/llvm/llvm-project/issues/93069.

Instead, this patch simply casts the `__iter_pointer` to the `__node_pointer` 
and uses a straightforward `GetChildMemberWithName("__value_")` to get to the 
key/value we care about.

We can eventually re-use the core-part of the `std::map` and 
`std::map::iterator` formatters. But it will be an easier to change to review 
once both simplifications landed.

---
Full diff: https://github.com/llvm/llvm-project/pull/97713.diff


4 Files Affected:

- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp (-188) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.h (+4-25) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp (+115) 
- (modified) 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
 (+10) 


``diff
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index ad467c3966e60..05cfa0568c25d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -202,194 +202,6 @@ bool 
lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
   return true;
 }
 
-/*
- (lldb) fr var ibeg --raw --ptr-depth 1
- (std::__1::__map_iterator,
- std::__1::allocator > >, std::__1::__tree_node,
- std::__1::allocator > >, void *> *, long> >) ibeg = {
- __i_ = {
- __ptr_ = 0x000100103870 {
- std::__1::__tree_node_base = {
- std::__1::__tree_end_node *> = {
- __left_ = 0x
- }
- __right_ = 0x
- __parent_ = 0x0001001038b0
- __is_black_ = true
- }
- __value_ = {
- first = 0
- second = { std::string }
- */
-
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
-LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-: SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr(), m_pair_sp() {
-  if (valobj_sp)
-Update();
-}
-
-lldb::ChildCacheState
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
-  m_pair_sp.reset();
-  m_pair_ptr = nullptr;
-
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  TargetSP target_sp(valobj_sp->GetTargetSP());
-
-  if (!target_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  // 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("__i_"));
-  if (!__i_) {
-m_pair_ptr = nullptr;
-return lldb::ChildCacheState::eRefetch;
-  }
-  CompilerType pair_type(
-  __i_->GetCompilerType().GetTypeTemplateArgument(0));
-  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);
-

[Lldb-commits] [lldb] [LLDB] Support exception breakpoints for plugin-provided languages (PR #97675)

2024-07-04 Thread Walter Erquinigo via lldb-commits

https://github.com/walter-erquinigo updated 
https://github.com/llvm/llvm-project/pull/97675

>From 5d1a7254d1e1a541a7b901be0d3a84eab42474b2 Mon Sep 17 00:00:00 2001
From: walter erquinigo 
Date: Thu, 4 Jul 2024 00:34:14 -0400
Subject: [PATCH 1/2] [LLDB] Support exception breakpoints for plugin-provided
 languages

CommandObjectBreakpoint has a harcoded list of languages for which exception 
breakpoints can be enabled. I'm making this a bit more generic so that my Mojo 
plugin can get this feature.
Basically, I'm adding a new overridable method 
`Language::SupportsExceptionBreakpoints` that can be used by language plugins 
to determine whether they support this feature or not. This method is used in 
addition to the hardcoded list and, as an example, I'm using it for the ObjC 
language support.

Another route is simply to avoid doing the check that it's being done right now 
and simply try to the create the exception breakpoint for whatever language 
that is not in the hardcoded list. I'm happy to do that if the reviewers think 
it's a good idea.

As a note, the other possible place for adding this 
`SupportsExceptionBreakpoints` method is in `LanguageRuntime`. However, 
accessing it requires having a process, which is not always the case when 
invoking the `breakpoint set -E` command. The process might not be alive yet, 
so `Language` is a good second place for this.

And as a final note, I don't want to make this `SupportsExceptionBreakpoints` 
complicated. I'm keeping it as simple as possible because it can easily evolve 
as it's not part of the public API.
---
 lldb/include/lldb/Target/Language.h  | 6 +-
 lldb/source/Commands/CommandObjectBreakpoint.cpp | 9 ++---
 lldb/source/Plugins/Language/ObjC/ObjCLanguage.h | 2 ++
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/lldb/include/lldb/Target/Language.h 
b/lldb/include/lldb/Target/Language.h
index ff7c60bf68bfc..9c2c765ce497f 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -245,7 +245,7 @@ class Language : public PluginInterface {
   // a match.  But we wouldn't want this to match AnotherA::my_function.  The
   // user is specifying a truncated path, not a truncated set of characters.
   // This function does a language-aware comparison for those purposes.
-  virtual bool DemangledNameContainsPath(llvm::StringRef path, 
+  virtual bool DemangledNameContainsPath(llvm::StringRef path,
  ConstString demangled) const;
 
   // if a language has a custom format for printing variable declarations that
@@ -363,6 +363,10 @@ class Language : public PluginInterface {
 return false;
   }
 
+  /// Returns true if this Language supports exception breakpoints via a
+  /// corresponding LanguageRuntime plugin.
+  virtual bool SupportsExceptionBreakpoints() const { return false; }
+
 protected:
   // Classes that inherit from Language can see and modify these
 
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp 
b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index cd4c7790f447e..a5fe9273fac76 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -308,9 +308,6 @@ class CommandObjectBreakpointSet : public 
CommandObjectParsed {
 case eLanguageTypeC_plus_plus_14:
   m_exception_language = eLanguageTypeC_plus_plus;
   break;
-case eLanguageTypeObjC:
-  m_exception_language = eLanguageTypeObjC;
-  break;
 case eLanguageTypeObjC_plus_plus:
   error_context =
   "Set exception breakpoints separately for c++ and objective-c";
@@ -319,6 +316,12 @@ class CommandObjectBreakpointSet : public 
CommandObjectParsed {
   error_context = "Unknown language type for exception breakpoint";
   break;
 default:
+  if (Language *languagePlugin = Language::FindPlugin(language)) {
+if (languagePlugin->SupportsExceptionBreakpoints()) {
+  m_exception_language = language;
+  break;
+}
+  }
   error_context = "Unsupported language type for exception breakpoint";
 }
 if (!error_context.empty())
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h 
b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index a50f4b036108d..a61d0f128370d 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -194,6 +194,8 @@ class ObjCLanguage : public Language {
 
   llvm::StringRef GetInstanceVariableName() override { return "self"; }
 
+  bool SupportsExceptionBreakpoints() const override { return true; }
+
   // PluginInterface protocol
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
 };

>From e99702d0cafaaa87e06a845e3f3e14868f9e800b Mon Sep 17 00:00:00 2001
From: Walter Erquinigo 
Date: Thu, 4 Jul 2024 10:02:45 -0400
Subject

[Lldb-commits] [lldb] [LLDB] Support exception breakpoints for plugin-provided languages (PR #97675)

2024-07-04 Thread Walter Erquinigo via lldb-commits


@@ -319,6 +316,12 @@ class CommandObjectBreakpointSet : public 
CommandObjectParsed {
   error_context = "Unknown language type for exception breakpoint";
   break;
 default:
+  if (Language *languagePlugin = Language::FindPlugin(language)) {

walter-erquinigo wrote:

Within switch statements I tend to be very paranoid with braces

https://github.com/llvm/llvm-project/pull/97675
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB] Support exception breakpoints for plugin-provided languages (PR #97675)

2024-07-04 Thread Walter Erquinigo via lldb-commits

walter-erquinigo wrote:

> And does this list include languages that are not plugin provided?

The hardcoded list in the file being changes includes C++ and Objc in its 
various variants.

> I was wondering why only Objective C changed, but if the rest are not plugins 
> then this makes sense.

That was the only simple example I could use to show how this change does work. 

Thanks for the review!

https://github.com/llvm/llvm-project/pull/97675
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] 94a067a - [LLDB] Support exception breakpoints for plugin-provided languages (#97675)

2024-07-04 Thread via lldb-commits

Author: Walter Erquinigo
Date: 2024-07-04T10:05:01-04:00
New Revision: 94a067a306fecceac913cc6d9bfdcd49464358ec

URL: 
https://github.com/llvm/llvm-project/commit/94a067a306fecceac913cc6d9bfdcd49464358ec
DIFF: 
https://github.com/llvm/llvm-project/commit/94a067a306fecceac913cc6d9bfdcd49464358ec.diff

LOG: [LLDB] Support exception breakpoints for plugin-provided languages (#97675)

CommandObjectBreakpoint has a harcoded list of languages for which
exception breakpoints can be enabled. I'm making this a bit more generic
so that my Mojo plugin can get this feature.
Basically, I'm adding a new overridable method
`Language::SupportsExceptionBreakpoints` that can be used by language
plugins to determine whether they support this feature or not. This
method is used in addition to the hardcoded list and, as an example, I'm
using it for the ObjC language support.

Another route is simply to avoid doing the check that it's being done
right now and simply try to the create the exception breakpoint for
whatever language that is not in the hardcoded list. I'm happy to do
that if the reviewers think it's a good idea.

As a note, the other possible place for adding this
`SupportsExceptionBreakpoints` method is in `LanguageRuntime`. However,
accessing it requires having a process, which is not always the case
when invoking the `breakpoint set -E` command. The process might not be
alive yet, so `Language` is a good second place for this.

And as a final note, I don't want to make this
`SupportsExceptionBreakpoints` complicated. I'm keeping it as simple as
possible because it can easily evolve as it's not part of the public
API.

Added: 


Modified: 
lldb/include/lldb/Target/Language.h
lldb/source/Commands/CommandObjectBreakpoint.cpp
lldb/source/Plugins/Language/ObjC/ObjCLanguage.h

Removed: 




diff  --git a/lldb/include/lldb/Target/Language.h 
b/lldb/include/lldb/Target/Language.h
index ff7c60bf68bfc9..2d6e5a40a0c0e4 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -363,6 +363,10 @@ class Language : public PluginInterface {
 return false;
   }
 
+  /// Returns true if this Language supports exception breakpoints via a
+  /// corresponding LanguageRuntime plugin.
+  virtual bool SupportsExceptionBreakpoints() const { return false; }
+
 protected:
   // Classes that inherit from Language can see and modify these
 

diff  --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp 
b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index cd4c7790f447e1..a5fe9273fac76d 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -308,9 +308,6 @@ class CommandObjectBreakpointSet : public 
CommandObjectParsed {
 case eLanguageTypeC_plus_plus_14:
   m_exception_language = eLanguageTypeC_plus_plus;
   break;
-case eLanguageTypeObjC:
-  m_exception_language = eLanguageTypeObjC;
-  break;
 case eLanguageTypeObjC_plus_plus:
   error_context =
   "Set exception breakpoints separately for c++ and objective-c";
@@ -319,6 +316,12 @@ class CommandObjectBreakpointSet : public 
CommandObjectParsed {
   error_context = "Unknown language type for exception breakpoint";
   break;
 default:
+  if (Language *languagePlugin = Language::FindPlugin(language)) {
+if (languagePlugin->SupportsExceptionBreakpoints()) {
+  m_exception_language = language;
+  break;
+}
+  }
   error_context = "Unsupported language type for exception breakpoint";
 }
 if (!error_context.empty())

diff  --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h 
b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index a50f4b036108d7..a61d0f128370d4 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -194,6 +194,8 @@ class ObjCLanguage : public Language {
 
   llvm::StringRef GetInstanceVariableName() override { return "self"; }
 
+  bool SupportsExceptionBreakpoints() const override { return true; }
+
   // PluginInterface protocol
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
 };



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB] Support exception breakpoints for plugin-provided languages (PR #97675)

2024-07-04 Thread Walter Erquinigo via lldb-commits

https://github.com/walter-erquinigo closed 
https://github.com/llvm/llvm-project/pull/97675
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Move std::map iterator formatter into LibCxxMap.cpp (PR #97687)

2024-07-04 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

LGTM.

https://github.com/llvm/llvm-project/pull/97687
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] fbd1b65 - [lldb][DataFormatter][NFC] Move std::map iterator formatter into LibCxxMap.cpp (#97687)

2024-07-04 Thread via lldb-commits

Author: Michael Buch
Date: 2024-07-04T17:06:10+01:00
New Revision: fbd1b6567ae41d64f1dbb6b32c7cf8a1b710b8d9

URL: 
https://github.com/llvm/llvm-project/commit/fbd1b6567ae41d64f1dbb6b32c7cf8a1b710b8d9
DIFF: 
https://github.com/llvm/llvm-project/commit/fbd1b6567ae41d64f1dbb6b32c7cf8a1b710b8d9.diff

LOG: [lldb][DataFormatter][NFC] Move std::map iterator formatter into 
LibCxxMap.cpp (#97687)

The two formatters follow very similar techniques to retrieve data out
of the map. We're changing this for `std::map` in
https://github.com/llvm/llvm-project/pull/97579 and plan to change it in
the same way for the iterator formatter. Having them in the same place
will allow us to re-use some of the logic (and we won't have to repeat
some of the clarification comments).

Added: 


Modified: 
lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp

Removed: 




diff  --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index ad467c3966e60..05cfa0568c25d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -202,194 +202,6 @@ bool 
lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
   return true;
 }
 
-/*
- (lldb) fr var ibeg --raw --ptr-depth 1
- (std::__1::__map_iterator,
- std::__1::allocator > >, std::__1::__tree_node,
- std::__1::allocator > >, void *> *, long> >) ibeg = {
- __i_ = {
- __ptr_ = 0x000100103870 {
- std::__1::__tree_node_base = {
- std::__1::__tree_end_node *> = {
- __left_ = 0x
- }
- __right_ = 0x
- __parent_ = 0x0001001038b0
- __is_black_ = true
- }
- __value_ = {
- first = 0
- second = { std::string }
- */
-
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::
-LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-: SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr(), m_pair_sp() {
-  if (valobj_sp)
-Update();
-}
-
-lldb::ChildCacheState
-lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
-  m_pair_sp.reset();
-  m_pair_ptr = nullptr;
-
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  TargetSP target_sp(valobj_sp->GetTargetSP());
-
-  if (!target_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  // 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("__i_"));
-  if (!__i_) {
-m_pair_ptr = nullptr;
-return lldb::ChildCacheState::eRefetch;
-  }
-  CompilerType pair_type(
-  __i_->GetCompilerType().GetTypeTemplateArgument(0));
-  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 lldb::ChildCacheState::eRefetch;
-  }
-
-  auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS));
-  m_pair_ptr = nullptr;
-  if (addr && addr != LLDB_INVALID_ADDRESS) {
-auto ts = pair_type.GetTypeSystem();
-auto ast_ctx = ts.dyn_cast_or_null();
-if (!ast_ctx)
-  return lldb::ChildCacheState::eRefetch;
-
-// Mimick layo

[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Move std::map iterator formatter into LibCxxMap.cpp (PR #97687)

2024-07-04 Thread Michael Buch via lldb-commits

https://github.com/Michael137 closed 
https://github.com/llvm/llvm-project/pull/97687
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][DataFormatter] Move std::unordered_map::iterator formatter into LibCxxUnorderedMap.cpp (PR #97752)

2024-07-04 Thread Michael Buch via lldb-commits

https://github.com/Michael137 created 
https://github.com/llvm/llvm-project/pull/97752

Similar to how we moved the `std::map::iterator` formatter in 
https://github.com/llvm/llvm-project/pull/97687, do the same for 
`std::unordered_map::iterator`.

Again the `unordered_map` and `unordered_map::iterator` formatters try to do 
very similar things: retrieve data out of the map. The iterator formatter does 
this in a fragile way (similar to how `std::map` does it, see 
https://github.com/llvm/llvm-project/pull/97579). Thus we will be refactoring 
the `std::unordered_map::iterator` in upcoming patches. Having it in 
`LibCxxUnorderedMap` will allow us to re-use some of the logic (and we won't 
have to repeat some of the clarification comments).

>From f62e9688284af9295aeee0987398805884c37a4f Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 4 Jul 2024 13:35:21 +0200
Subject: [PATCH] [lldb][DataFormatter] Move std::unordered_map::iterator
 formatter into LibCxxUnorderedMap.cpp

---
 .../Plugins/Language/CPlusPlus/LibCxx.cpp | 149 -
 .../Plugins/Language/CPlusPlus/LibCxx.h   |  54 +
 .../Language/CPlusPlus/LibCxxUnorderedMap.cpp | 196 ++
 3 files changed, 200 insertions(+), 199 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 05cfa0568c25d4..feaa51a96843ab 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -202,155 +202,6 @@ bool 
lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
   return true;
 }
 
-lldb_private::formatters::LibCxxUnorderedMapIteratorSyntheticFrontEnd::
-LibCxxUnorderedMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-: SyntheticChildrenFrontEnd(*valobj_sp) {
-  if (valobj_sp)
-Update();
-}
-
-lldb::ChildCacheState lldb_private::formatters::
-LibCxxUnorderedMapIteratorSyntheticFrontEnd::Update() {
-  m_pair_sp.reset();
-  m_iter_ptr = nullptr;
-
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  TargetSP target_sp(valobj_sp->GetTargetSP());
-
-  if (!target_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  auto exprPathOptions = ValueObject::GetValueForExpressionPathOptions()
- .DontCheckDotVsArrowSyntax()
- .SetSyntheticChildrenTraversal(
- 
ValueObject::GetValueForExpressionPathOptions::
- SyntheticChildrenTraversal::None);
-
-  // 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_iter_ptr =
-  valobj_sp
-  ->GetValueForExpressionPath(".__i_.__node_", nullptr, nullptr,
-  exprPathOptions, nullptr)
-  .get();
-
-  if (m_iter_ptr) {
-auto iter_child(valobj_sp->GetChildMemberWithName("__i_"));
-if (!iter_child) {
-  m_iter_ptr = nullptr;
-  return lldb::ChildCacheState::eRefetch;
-}
-
-CompilerType node_type(iter_child->GetCompilerType()
-   .GetTypeTemplateArgument(0)
-   .GetPointeeType());
-
-CompilerType pair_type(node_type.GetTypeTemplateArgument(0));
-
-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_iter_ptr = nullptr;
-  return lldb::ChildCacheState::eRefetch;
-}
-
-uint64_t addr = m_iter_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-m_iter_ptr = nullptr;
-
-if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
-  return lldb::ChildCacheState::eRefetch;
-
-auto ts = pair_type.GetTypeSystem();
-auto ast_ctx = ts.dyn_cast_or_null();
-if (!ast_ctx)
-  return lldb::ChildCacheState::eRefetch;
-
-// Mimick layout of std::__hash_iterator::__node_ and read it in
-// from process memory.
-//
-// The following shows the contiguous block of memory:
-//
-// +-+ class __hash_node_base
-// __node_ | __next_pointer __next_; |
-// +-+ class __hash_node
-// | size_t __hash_; |
-// | __node_value_type __value_; | <<< our key/value pair
-// +-+
-//
-CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
-llvm::StringRef(),
-  

[Lldb-commits] [lldb] [lldb][DataFormatter] Move std::unordered_map::iterator formatter into LibCxxUnorderedMap.cpp (PR #97752)

2024-07-04 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)


Changes

Similar to how we moved the `std::map::iterator` formatter in 
https://github.com/llvm/llvm-project/pull/97687, do the same for 
`std::unordered_map::iterator`.

Again the `unordered_map` and `unordered_map::iterator` formatters try to do 
very similar things: retrieve data out of the map. The iterator formatter does 
this in a fragile way (similar to how `std::map` does it, see 
https://github.com/llvm/llvm-project/pull/97579). Thus we will be refactoring 
the `std::unordered_map::iterator` in upcoming patches. Having it in 
`LibCxxUnorderedMap` will allow us to re-use some of the logic (and we won't 
have to repeat some of the clarification comments).

---
Full diff: https://github.com/llvm/llvm-project/pull/97752.diff


3 Files Affected:

- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp (-149) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.h (+4-50) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp 
(+196) 


``diff
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 05cfa0568c25d..feaa51a96843a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -202,155 +202,6 @@ bool 
lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
   return true;
 }
 
-lldb_private::formatters::LibCxxUnorderedMapIteratorSyntheticFrontEnd::
-LibCxxUnorderedMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-: SyntheticChildrenFrontEnd(*valobj_sp) {
-  if (valobj_sp)
-Update();
-}
-
-lldb::ChildCacheState lldb_private::formatters::
-LibCxxUnorderedMapIteratorSyntheticFrontEnd::Update() {
-  m_pair_sp.reset();
-  m_iter_ptr = nullptr;
-
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  TargetSP target_sp(valobj_sp->GetTargetSP());
-
-  if (!target_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  auto exprPathOptions = ValueObject::GetValueForExpressionPathOptions()
- .DontCheckDotVsArrowSyntax()
- .SetSyntheticChildrenTraversal(
- 
ValueObject::GetValueForExpressionPathOptions::
- SyntheticChildrenTraversal::None);
-
-  // 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_iter_ptr =
-  valobj_sp
-  ->GetValueForExpressionPath(".__i_.__node_", nullptr, nullptr,
-  exprPathOptions, nullptr)
-  .get();
-
-  if (m_iter_ptr) {
-auto iter_child(valobj_sp->GetChildMemberWithName("__i_"));
-if (!iter_child) {
-  m_iter_ptr = nullptr;
-  return lldb::ChildCacheState::eRefetch;
-}
-
-CompilerType node_type(iter_child->GetCompilerType()
-   .GetTypeTemplateArgument(0)
-   .GetPointeeType());
-
-CompilerType pair_type(node_type.GetTypeTemplateArgument(0));
-
-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_iter_ptr = nullptr;
-  return lldb::ChildCacheState::eRefetch;
-}
-
-uint64_t addr = m_iter_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-m_iter_ptr = nullptr;
-
-if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
-  return lldb::ChildCacheState::eRefetch;
-
-auto ts = pair_type.GetTypeSystem();
-auto ast_ctx = ts.dyn_cast_or_null();
-if (!ast_ctx)
-  return lldb::ChildCacheState::eRefetch;
-
-// Mimick layout of std::__hash_iterator::__node_ and read it in
-// from process memory.
-//
-// The following shows the contiguous block of memory:
-//
-// +-+ class __hash_node_base
-// __node_ | __next_pointer __next_; |
-// +-+ class __hash_node
-// | size_t __hash_; |
-// | __node_value_type __value_; | <<< our key/value pair
-// +-+
-//
-CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
-llvm::StringRef(),
-{{"__next_",
-  ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
- {"__hash_", ast_ctx->GetBasicType(lldb::eBasicTypeUnsignedLongLong)}

[Lldb-commits] [lldb] [lldb][DataFormatter] Simplify std::unordered_map::iterator formatter (PR #97754)

2024-07-04 Thread Michael Buch via lldb-commits

https://github.com/Michael137 created 
https://github.com/llvm/llvm-project/pull/97754

Depends on https://github.com/llvm/llvm-project/pull/97752

This patch changes the way we retrieve the key/value pair in the 
`std::unordered_map::iterator` formatter (similar to how we are changing it for 
`std::map::iterator` in https://github.com/llvm/llvm-project/pull/97713, the 
motivations being the same).

The `std::unordered_map` already does it this way, so we align the iterator 
counterpart to do the same.

>From b10f76bd6d02106e80315a70a7b72461cb6f2a99 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Thu, 4 Jul 2024 13:35:21 +0200
Subject: [PATCH 1/2] [lldb][DataFormatter] Move std::unordered_map::iterator
 formatter into LibCxxUnorderedMap.cpp

---
 .../Plugins/Language/CPlusPlus/LibCxx.cpp | 149 -
 .../Plugins/Language/CPlusPlus/LibCxx.h   |  54 +
 .../Language/CPlusPlus/LibCxxUnorderedMap.cpp | 196 ++
 3 files changed, 200 insertions(+), 199 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 05cfa0568c25d..feaa51a96843a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -202,155 +202,6 @@ bool 
lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
   return true;
 }
 
-lldb_private::formatters::LibCxxUnorderedMapIteratorSyntheticFrontEnd::
-LibCxxUnorderedMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-: SyntheticChildrenFrontEnd(*valobj_sp) {
-  if (valobj_sp)
-Update();
-}
-
-lldb::ChildCacheState lldb_private::formatters::
-LibCxxUnorderedMapIteratorSyntheticFrontEnd::Update() {
-  m_pair_sp.reset();
-  m_iter_ptr = nullptr;
-
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  TargetSP target_sp(valobj_sp->GetTargetSP());
-
-  if (!target_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  auto exprPathOptions = ValueObject::GetValueForExpressionPathOptions()
- .DontCheckDotVsArrowSyntax()
- .SetSyntheticChildrenTraversal(
- 
ValueObject::GetValueForExpressionPathOptions::
- SyntheticChildrenTraversal::None);
-
-  // 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_iter_ptr =
-  valobj_sp
-  ->GetValueForExpressionPath(".__i_.__node_", nullptr, nullptr,
-  exprPathOptions, nullptr)
-  .get();
-
-  if (m_iter_ptr) {
-auto iter_child(valobj_sp->GetChildMemberWithName("__i_"));
-if (!iter_child) {
-  m_iter_ptr = nullptr;
-  return lldb::ChildCacheState::eRefetch;
-}
-
-CompilerType node_type(iter_child->GetCompilerType()
-   .GetTypeTemplateArgument(0)
-   .GetPointeeType());
-
-CompilerType pair_type(node_type.GetTypeTemplateArgument(0));
-
-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_iter_ptr = nullptr;
-  return lldb::ChildCacheState::eRefetch;
-}
-
-uint64_t addr = m_iter_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-m_iter_ptr = nullptr;
-
-if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
-  return lldb::ChildCacheState::eRefetch;
-
-auto ts = pair_type.GetTypeSystem();
-auto ast_ctx = ts.dyn_cast_or_null();
-if (!ast_ctx)
-  return lldb::ChildCacheState::eRefetch;
-
-// Mimick layout of std::__hash_iterator::__node_ and read it in
-// from process memory.
-//
-// The following shows the contiguous block of memory:
-//
-// +-+ class __hash_node_base
-// __node_ | __next_pointer __next_; |
-// +-+ class __hash_node
-// | size_t __hash_; |
-// | __node_value_type __value_; | <<< our key/value pair
-// +-+
-//
-CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
-llvm::StringRef(),
-{{"__next_",
-  ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
- {"__hash_", ast_ctx->GetBasicType(lldb::eBasicTypeUnsignedLongLong)},
- {"__value_", pair_type}});
-std::optional size = tree_nod

[Lldb-commits] [lldb] [lldb][DataFormatter] Simplify std::unordered_map::iterator formatter (PR #97754)

2024-07-04 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)


Changes

Depends on https://github.com/llvm/llvm-project/pull/97752

This patch changes the way we retrieve the key/value pair in the 
`std::unordered_map::iterator` formatter (similar to how we are changing it for 
`std::map::iterator` in https://github.com/llvm/llvm-project/pull/97713, the 
motivations being the same).

The `std::unordered_map` already does it this way, so we align the iterator 
counterpart to do the same.

---
Full diff: https://github.com/llvm/llvm-project/pull/97754.diff


5 Files Affected:

- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp (-149) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.h (+4-50) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp 
(+150) 
- (modified) 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
 (+16) 
- (modified) 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
 (+19-6) 


``diff
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 05cfa0568c25d..feaa51a96843a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -202,155 +202,6 @@ bool 
lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
   return true;
 }
 
-lldb_private::formatters::LibCxxUnorderedMapIteratorSyntheticFrontEnd::
-LibCxxUnorderedMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-: SyntheticChildrenFrontEnd(*valobj_sp) {
-  if (valobj_sp)
-Update();
-}
-
-lldb::ChildCacheState lldb_private::formatters::
-LibCxxUnorderedMapIteratorSyntheticFrontEnd::Update() {
-  m_pair_sp.reset();
-  m_iter_ptr = nullptr;
-
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  TargetSP target_sp(valobj_sp->GetTargetSP());
-
-  if (!target_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  if (!valobj_sp)
-return lldb::ChildCacheState::eRefetch;
-
-  auto exprPathOptions = ValueObject::GetValueForExpressionPathOptions()
- .DontCheckDotVsArrowSyntax()
- .SetSyntheticChildrenTraversal(
- 
ValueObject::GetValueForExpressionPathOptions::
- SyntheticChildrenTraversal::None);
-
-  // 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_iter_ptr =
-  valobj_sp
-  ->GetValueForExpressionPath(".__i_.__node_", nullptr, nullptr,
-  exprPathOptions, nullptr)
-  .get();
-
-  if (m_iter_ptr) {
-auto iter_child(valobj_sp->GetChildMemberWithName("__i_"));
-if (!iter_child) {
-  m_iter_ptr = nullptr;
-  return lldb::ChildCacheState::eRefetch;
-}
-
-CompilerType node_type(iter_child->GetCompilerType()
-   .GetTypeTemplateArgument(0)
-   .GetPointeeType());
-
-CompilerType pair_type(node_type.GetTypeTemplateArgument(0));
-
-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_iter_ptr = nullptr;
-  return lldb::ChildCacheState::eRefetch;
-}
-
-uint64_t addr = m_iter_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-m_iter_ptr = nullptr;
-
-if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
-  return lldb::ChildCacheState::eRefetch;
-
-auto ts = pair_type.GetTypeSystem();
-auto ast_ctx = ts.dyn_cast_or_null();
-if (!ast_ctx)
-  return lldb::ChildCacheState::eRefetch;
-
-// Mimick layout of std::__hash_iterator::__node_ and read it in
-// from process memory.
-//
-// The following shows the contiguous block of memory:
-//
-// +-+ class __hash_node_base
-// __node_ | __next_pointer __next_; |
-// +-+ class __hash_node
-// | size_t __hash_; |
-// | __node_value_type __value_; | <<< our key/value pair
-// +-+
-//
-CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
-llvm::StringRef(),
-{{"__next_",
-  ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
- {"__hash_", ast_ctx->GetBasicType(lldb::eBasicTypeUnsignedLon

[Lldb-commits] [lldb] [lldb][DataFormatter] Simplify std::unordered_map::iterator formatter (PR #97754)

2024-07-04 Thread via lldb-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff fbd1b6567ae41d64f1dbb6b32c7cf8a1b710b8d9 
9e66b1c4787ad49b7f4ffab9f87746d7c59a4fd5 -- 
lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
lldb/source/Plugins/Language/CPlusPlus/LibCxx.h 
lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
``





View the diff from clang-format here.


``diff
diff --git 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
index 534a22f98f..19ef2f556f 100644
--- 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
+++ 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
@@ -34,7 +34,7 @@ int main()
 sium["hello"] = 137;
 
 int_vector iv;
-   iv.push_back(3);
+iv.push_back(3);
 
string_vector sv;
sv.push_back("hello");
@@ -45,7 +45,7 @@ int main()
 si_umap_iter siumI = sium.begin();
 
 ivter ivI = iv.begin();
-   svter svI = sv.begin();
+svter svI = sv.begin();
 
return 0; // Set break point at this line.
 }

``




https://github.com/llvm/llvm-project/pull/97754
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Support new libc++ __compressed_pair layout (PR #96538)

2024-07-04 Thread Michael Buch via lldb-commits

https://github.com/Michael137 updated 
https://github.com/llvm/llvm-project/pull/96538

>From 0d39f1ecfb9643f944aa1352d4a307e5638ab08f Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Mon, 29 Jan 2024 16:23:16 +
Subject: [PATCH 1/2] [lldb] Support new libc++ __compressed_pair layout

This patch is in preparation for the `__compressed_pair`
refactor in https://github.com/llvm/llvm-project/pull/76756.

This gets the formatter tests to at least pass.

Currently in draft because there's still some cleanup to be done.
---
 lldb/examples/synthetic/libcxx.py | 26 --
 .../Plugins/Language/CPlusPlus/LibCxx.cpp | 61 ++
 .../Plugins/Language/CPlusPlus/LibCxxList.cpp | 83 ---
 .../Plugins/Language/CPlusPlus/LibCxxMap.cpp  | 68 +++
 .../Language/CPlusPlus/LibCxxUnorderedMap.cpp | 62 +-
 .../Language/CPlusPlus/LibCxxVector.cpp   | 40 +
 .../list/TestDataFormatterGenericList.py  |  3 +-
 .../libcxx/string/simulator/main.cpp  |  1 +
 .../TestDataFormatterLibcxxUniquePtr.py   |  7 +-
 9 files changed, 246 insertions(+), 105 deletions(-)

diff --git a/lldb/examples/synthetic/libcxx.py 
b/lldb/examples/synthetic/libcxx.py
index 474aaa428fa23a..060ff901008497 100644
--- a/lldb/examples/synthetic/libcxx.py
+++ b/lldb/examples/synthetic/libcxx.py
@@ -721,6 +721,12 @@ def _get_value_of_compressed_pair(self, pair):
 def update(self):
 logger = lldb.formatters.Logger.Logger()
 try:
+has_compressed_pair_layout = True
+alloc_valobj = self.valobj.GetChildMemberWithName("__alloc_")
+size_valobj = self.valobj.GetChildMemberWithName("__size_")
+if alloc_valobj.IsValid() and size_valobj.IsValid():
+has_compressed_pair_layout = False
+
 # A deque is effectively a two-dim array, with fixed width.
 # 'map' contains pointers to the rows of this array. The
 # full memory area allocated by the deque is delimited
@@ -734,9 +740,13 @@ def update(self):
 # variable tells which element in this NxM array is the 0th
 # one, and the 'size' element gives the number of elements
 # in the deque.
-count = self._get_value_of_compressed_pair(
-self.valobj.GetChildMemberWithName("__size_")
-)
+if has_compressed_pair_layout:
+count = self._get_value_of_compressed_pair(
+self.valobj.GetChildMemberWithName("__size_")
+)
+else:
+count = size_valobj.GetValueAsUnsigned(0)
+
 # give up now if we cant access memory reliably
 if self.block_size < 0:
 logger.write("block_size < 0")
@@ -748,9 +758,13 @@ def update(self):
 self.map_begin = map_.GetChildMemberWithName("__begin_")
 map_begin = self.map_begin.GetValueAsUnsigned(0)
 map_end = 
map_.GetChildMemberWithName("__end_").GetValueAsUnsigned(0)
-map_endcap = self._get_value_of_compressed_pair(
-map_.GetChildMemberWithName("__end_cap_")
-)
+
+if has_compressed_pair_layout:
+map_endcap = self._get_value_of_compressed_pair(
+map_.GetChildMemberWithName("__end_cap_")
+)
+else:
+map_endcap = 
map_.GetChildMemberWithName("__end_cap_").GetValueAsUnsigned(0)
 
 # check consistency
 if not map_first <= map_begin <= map_end <= map_endcap:
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 0f9f93b727ce86..1eee1d9cec7e82 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -27,6 +27,7 @@
 #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
 #include 
 #include 
 
@@ -176,9 +177,9 @@ bool 
lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
   if (!ptr_sp)
 return false;
 
-  ptr_sp = GetFirstValueOfLibCXXCompressedPair(*ptr_sp);
-  if (!ptr_sp)
-return false;
+  if (ValueObjectSP compressed_pair_value__sp =
+  GetFirstValueOfLibCXXCompressedPair(*ptr_sp))
+ptr_sp = std::move(compressed_pair_value__sp);
 
   if (ptr_sp->GetValueAsUnsigned(0) == 0) {
 stream.Printf("nullptr");
@@ -701,15 +702,28 @@ 
lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
   if (!ptr_sp)
 return lldb::ChildCacheState::eRefetch;
 
+  bool has_compressed_pair_layout = true;
+  ValueObjectSP deleter_sp(valobj_sp->GetChildMemberWithName("__deleter_"));
+  if (deleter_sp)
+has_compressed_pair_layout = false;
+
   // Retrieve the actual pointer and the deleter, and clone them to give them
   // user-friendly