[Lldb-commits] [lldb] Reland "[lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (#145065)" (PR #145126)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2572a2f224d8c3372fadc0edfa2af5f618765669 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Fri, 20 Jun 2025 18:09:54 +0100
Subject: [PATCH] Reland "[lldb][DWARF] Remove object_pointer from
 ParsedDWARFAttributes (#145065)"

This reverts commit 877511920dcf36463e06746d626e8876583a6abd.

This fixes the `TestObjCInBlockVars.py` LLDB API test.

The issue was that `GetCXXObjectParameter` wouldn't deduce the object
parameter of Objective-C method definitions correctly. In DWARF those
don't have a `DW_AT_specification` (so no link back to a DeclContext
that is a class type). The fix is to only check the validity of the
DeclContext DIE *if* no `DW_AT_object_pointer` exists on the DIE. If
`DW_AT_object_pointer` does exist, we should just always use that as the
object_parameter.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  | 28 ++-
 .../SymbolFile/DWARF/DWARFASTParserClang.h|  7 +++--
 2 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4f79c8aa3f811..3bec89cdf7469 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -445,15 +445,6 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const 
DWARFDIE &die) {
   name.SetCString(form_value.AsCString());
   break;
 
-case DW_AT_object_pointer:
-  // GetAttributes follows DW_AT_specification.
-  // DW_TAG_subprogram definitions and declarations may both
-  // have a DW_AT_object_pointer. Don't overwrite the one
-  // we parsed for the definition with the one from the declaration.
-  if (!object_pointer.IsValid())
-object_pointer = form_value.Reference();
-  break;
-
 case DW_AT_signature:
   signature = form_value;
   break;
@@ -1116,7 +1107,7 @@ bool DWARFASTParserClang::ParseObjCMethod(
 std::pair DWARFASTParserClang::ParseCXXMethod(
 const DWARFDIE &die, CompilerType clang_type,
 const ParsedDWARFTypeAttributes &attrs, const DWARFDIE &decl_ctx_die,
-bool is_static, bool &ignore_containing_context) {
+const DWARFDIE &object_parameter, bool &ignore_containing_context) {
   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
   SymbolFileDWARF *dwarf = die.GetDWARF();
   assert(dwarf);
@@ -1200,6 +1191,9 @@ std::pair 
DWARFASTParserClang::ParseCXXMethod(
   TypeSystemClang::GetDeclContextForType(class_opaque_type), die,
   attrs.name.GetCString());
 
+  // In DWARF, a C++ method is static if it has no object parameter child.
+  const bool is_static = !object_parameter.IsValid();
+
   // We have a C++ member function with no children (this pointer!) and clang
   // will get mad if we try and make a function that isn't well formed in the
   // DWARF, so we will just skip it...
@@ -1225,9 +1219,7 @@ std::pair 
DWARFASTParserClang::ParseCXXMethod(
 ClangASTMetadata metadata;
 metadata.SetUserID(die.GetID());
 
-char const *object_pointer_name =
-attrs.object_pointer ? attrs.object_pointer.GetName() : nullptr;
-if (object_pointer_name) {
+if (char const *object_pointer_name = object_parameter.GetName()) {
   metadata.SetObjectPtrName(object_pointer_name);
   LLDB_LOGF(log, "Setting object pointer name: %s on method object %p.\n",
 object_pointer_name, static_cast(cxx_method_decl));
@@ -1323,11 +1315,9 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
 type_handled =
 ParseObjCMethod(*objc_method, die, clang_type, attrs, is_variadic);
   } else if (is_cxx_method) {
-// In DWARF, a C++ method is static if it has no object parameter 
child.
-const bool is_static = !object_parameter.IsValid();
 auto [handled, type_sp] =
-ParseCXXMethod(die, clang_type, attrs, decl_ctx_die, is_static,
-   ignore_containing_context);
+ParseCXXMethod(die, clang_type, attrs, decl_ctx_die,
+   object_parameter, ignore_containing_context);
 if (type_sp)
   return type_sp;
 
@@ -1422,9 +1412,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   ClangASTMetadata metadata;
   metadata.SetUserID(die.GetID());
 
-  char const *object_pointer_name =
-  attrs.object_pointer ? attrs.object_pointer.GetName() : nullptr;
-  if (object_pointer_name) {
+  if (char const *object_pointer_name = object_parameter.GetName()) {
 metadata.SetObjectPtrName(object_pointer_name);
 LLDB_LOGF(log,
   "Setting object pointer name: %s on function "
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
in

[Lldb-commits] [lldb] [lldb-dap] Fix flaky test (PR #145231)

2025-06-22 Thread via lldb-commits

https://github.com/DrSergei created 
https://github.com/llvm/llvm-project/pull/145231

This patch fixes a possible data race between main and event handler threads. 
Terminated event can be sent from `Disconnect` function or event handler. 
Consequently, there are some possible sequences of events. We must check events 
twice, because without getting an exited event, `exit_status` will be None. 
But, we don't know the order of events (for example, we can get terminated 
event before exited event), so we check events by filter. It is correct, 
because terminated event will be sent only once (guarded by `llvm::call_once`).

This patch moved from 
[145010](https://github.com/llvm/llvm-project/pull/145010) and based on idea 
from this 
[comment](https://github.com/llvm/llvm-project/pull/145010#discussion_r2159637210).

>From f83073c80a72eb3c913c5101993f4208f0a94aae Mon Sep 17 00:00:00 2001
From: Druzhkov Sergei 
Date: Thu, 19 Jun 2025 15:50:27 +0300
Subject: [PATCH] [lldb-dap] Fix flaky test

---
 lldb/test/API/tools/lldb-dap/server/TestDAP_server.py | 3 ++-
 lldb/tools/lldb-dap/tool/lldb-dap.cpp | 4 +---
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py 
b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
index ed17044a220d4..116bc53a2dde0 100644
--- a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
+++ b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
@@ -101,7 +101,8 @@ def test_server_interrupt(self):
 # Interrupt the server which should disconnect all clients.
 process.send_signal(signal.SIGINT)
 
-self.dap_server.wait_for_terminated()
+self.dap_server.wait_for_event(["terminated", "exited"])
+self.dap_server.wait_for_event(["terminated", "exited"])
 self.assertIsNotNone(
 self.dap_server.exit_status,
 "Process exited before interrupting lldb-dap server",
diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp 
b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
index 9b9de5e21a742..9de6283319bb6 100644
--- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
@@ -310,7 +310,7 @@ serveConnection(const Socket::SocketProtocol &protocol, 
const std::string &name,
 "DAP session (" + client_name +
 ") error: ");
   }
-
+  io->Close();
   DAP_LOG(log, "({0}) client disconnected", client_name);
   std::unique_lock lock(dap_sessions_mutex);
   dap_sessions.erase(io.get());
@@ -342,8 +342,6 @@ serveConnection(const Socket::SocketProtocol &protocol, 
const std::string &name,
  << " disconnected failed: "
  << llvm::toString(std::move(error)) << "\n";
   }
-  // Close the socket to ensure the DAP::Loop read finishes.
-  sock->Close();
 }
   }
 

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


[Lldb-commits] [lldb] [lldb] Fix qEcho message handling (PR #145072)

2025-06-22 Thread Dmitry Vasilyev via lldb-commits

slydiman wrote:

The buildbot lldb-remote-linux-ubuntu is still broken.
Please fix it ASAP or revert the patch.

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


[Lldb-commits] [lldb] [lldb-dap] Fix flaky test (PR #145231)

2025-06-22 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: None (DrSergei)


Changes

This patch fixes a possible data race between main and event handler threads. 
Terminated event can be sent from `Disconnect` function or event handler. 
Consequently, there are some possible sequences of events. We must check events 
twice, because without getting an exited event, `exit_status` will be None. 
But, we don't know the order of events (for example, we can get terminated 
event before exited event), so we check events by filter. It is correct, 
because terminated event will be sent only once (guarded by `llvm::call_once`).

This patch moved from 
[145010](https://github.com/llvm/llvm-project/pull/145010) and based on idea 
from this 
[comment](https://github.com/llvm/llvm-project/pull/145010#discussion_r2159637210).

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


2 Files Affected:

- (modified) lldb/test/API/tools/lldb-dap/server/TestDAP_server.py (+2-1) 
- (modified) lldb/tools/lldb-dap/tool/lldb-dap.cpp (+1-3) 


``diff
diff --git a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py 
b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
index ed17044a220d4..116bc53a2dde0 100644
--- a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
+++ b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py
@@ -101,7 +101,8 @@ def test_server_interrupt(self):
 # Interrupt the server which should disconnect all clients.
 process.send_signal(signal.SIGINT)
 
-self.dap_server.wait_for_terminated()
+self.dap_server.wait_for_event(["terminated", "exited"])
+self.dap_server.wait_for_event(["terminated", "exited"])
 self.assertIsNotNone(
 self.dap_server.exit_status,
 "Process exited before interrupting lldb-dap server",
diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp 
b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
index 9b9de5e21a742..9de6283319bb6 100644
--- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp
@@ -310,7 +310,7 @@ serveConnection(const Socket::SocketProtocol &protocol, 
const std::string &name,
 "DAP session (" + client_name +
 ") error: ");
   }
-
+  io->Close();
   DAP_LOG(log, "({0}) client disconnected", client_name);
   std::unique_lock lock(dap_sessions_mutex);
   dap_sessions.erase(io.get());
@@ -342,8 +342,6 @@ serveConnection(const Socket::SocketProtocol &protocol, 
const std::string &name,
  << " disconnected failed: "
  << llvm::toString(std::move(error)) << "\n";
   }
-  // Close the socket to ensure the DAP::Loop read finishes.
-  sock->Close();
 }
   }
 

``




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


[Lldb-commits] [lldb] d2c0451 - [lldb][DWAFASTParserClang][NFC] Rename GetCXXObjectParameter to GetObjectParameter

2025-06-22 Thread Michael Buch via lldb-commits

Author: Michael Buch
Date: 2025-06-22T11:41:48+01:00
New Revision: d2c0451d05d95c98727d2447abd1cb4bfed90890

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

LOG: [lldb][DWAFASTParserClang][NFC] Rename GetCXXObjectParameter to 
GetObjectParameter

Since this is used for Objective-C too.

Added: 


Modified: 
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp

Removed: 




diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4f79c8aa3f811..a4cb608edd8b4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -159,13 +159,9 @@ static bool TagIsRecordType(dw_tag_t tag) {
   }
 }
 
-/// Get the object parameter DIE if one exists, otherwise returns
-/// a default DWARFDIE. If \c containing_decl_ctx is not a valid
-/// C++ declaration context for class methods, assume no object
-/// parameter exists for the given \c subprogram.
 DWARFDIE
-DWARFASTParserClang::GetCXXObjectParameter(const DWARFDIE &subprogram,
-   const DWARFDIE &decl_ctx_die) {
+DWARFASTParserClang::GetObjectParameter(const DWARFDIE &subprogram,
+const DWARFDIE &decl_ctx_die) {
   assert(subprogram);
   assert(subprogram.Tag() == DW_TAG_subprogram ||
  subprogram.Tag() == DW_TAG_inlined_subroutine ||
@@ -1305,7 +1301,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   clang::CallingConv calling_convention =
   ConvertDWARFCallingConventionToClang(attrs);
 
-  const DWARFDIE object_parameter = GetCXXObjectParameter(die, decl_ctx_die);
+  const DWARFDIE object_parameter = GetObjectParameter(die, decl_ctx_die);
 
   // clang_type will get the function prototype clang type after this
   // call
@@ -2417,7 +2413,7 @@ 
DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
   assert(containing_decl_ctx);
 
   const unsigned cv_quals =
-  GetCXXMethodCVQuals(die, GetCXXObjectParameter(die, decl_ctx_die));
+  GetCXXMethodCVQuals(die, GetObjectParameter(die, decl_ctx_die));
 
   ParseChildParameters(containing_decl_ctx, die, is_variadic,
has_template_params, param_types, param_names);

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 111604ce4068a..e57fc503d34c1 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -112,9 +112,19 @@ class DWARFASTParserClang : public 
lldb_private::plugin::dwarf::DWARFASTParser {
   void MapDeclDIEToDefDIE(const lldb_private::plugin::dwarf::DWARFDIE 
&decl_die,
   const lldb_private::plugin::dwarf::DWARFDIE 
&def_die);
 
-  lldb_private::plugin::dwarf::DWARFDIE GetCXXObjectParameter(
-  const lldb_private::plugin::dwarf::DWARFDIE &subprogram,
-  const lldb_private::plugin::dwarf::DWARFDIE &decl_ctx_die);
+  /// Get the object parameter DIE if one exists, otherwise returns
+  /// a default DWARFDIE.
+  ///
+  /// \param[in] subprogram DIE of function for which to get the object
+  /// parameter. \param[in] containing_decl_ctx DIE representing declaration
+  /// context of \a subprogram. If this DIE isn't a valid declaration context
+  /// for class methods, assume no object parameter exists.
+  ///
+  /// \returns DIE of object parameter if one exists.
+  ///
+  lldb_private::plugin::dwarf::DWARFDIE
+  GetObjectParameter(const lldb_private::plugin::dwarf::DWARFDIE &subprogram,
+ const lldb_private::plugin::dwarf::DWARFDIE 
&decl_ctx_die);
 
 protected:
   /// Protected typedefs and members.

diff  --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp 
b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index 2d4b79fed4a55..f18e938dbc4c9 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -898,8 +898,7 @@ TEST_F(DWARFASTParserClangTests, 
TestParseDWARFAttributes_ObjectPointer) {
 auto param_die = decl_die.GetFirstChild();
 ASSERT_TRUE(param_die.IsValid());
 
-EXPECT_EQ(param_die,
-  ast_parser.GetCXXObjectParameter(decl_die, context_die));
+EXPECT_EQ(param_die, ast_parser.GetObjectParameter(decl_die, context_die));
   }
 
   {
@@ -912,8 +911,8 @@ TEST_F(DWARFASTParserClangTests, 
TestParseDWARFAttributes_ObjectPointer) {
 auto param_die = subprogram_def

[Lldb-commits] [lldb] [lldb] Migrate away from ValueRange(std::nullopt) (NFC) (PR #145245)

2025-06-22 Thread Kazu Hirata via lldb-commits

https://github.com/kazutakahirata created 
https://github.com/llvm/llvm-project/pull/145245

ArrayRef has a constructor that accepts std::nullopt.  This
constructor dates back to the days when we still had llvm::Optional.

Since the use of std::nullopt outside the context of std::optional is
kind of abuse and not intuitive to new comers, I would like to move
away from the constructor and eventually remove it.

This patch takes care of the lldb side of migration.


>From 939e745c6af0b228a0be8925361dfc684c65d1b4 Mon Sep 17 00:00:00 2001
From: Kazu Hirata 
Date: Sun, 22 Jun 2025 07:52:11 -0700
Subject: [PATCH] [lldb] Migrate away from ValueRange(std::nullopt) (NFC)

ArrayRef has a constructor that accepts std::nullopt.  This
constructor dates back to the days when we still had llvm::Optional.

Since the use of std::nullopt outside the context of std::optional is
kind of abuse and not intuitive to new comers, I would like to move
away from the constructor and eventually remove it.

This patch takes care of the lldb side of migration.
---
 lldb/source/Symbol/Function.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index 4fc793750f84f..6114eccd935ee 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -343,7 +343,7 @@ llvm::ArrayRef> 
Function::GetCallEdges() {
   Block &block = GetBlock(/*can_create*/true);
   SymbolFile *sym_file = block.GetSymbolFile();
   if (!sym_file)
-return std::nullopt;
+return {};
 
   // Lazily read call site information from the SymbolFile.
   m_call_edges = sym_file->ParseCallEdgesInFunction(GetID());

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


[Lldb-commits] [lldb] Revert "[lldb] Fix qEcho message handling (#145072)" (PR #145241)

2025-06-22 Thread via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Migrate away from ValueRange(std::nullopt) (NFC) (PR #145245)

2025-06-22 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Kazu Hirata (kazutakahirata)


Changes

ArrayRef has a constructor that accepts std::nullopt.  This
constructor dates back to the days when we still had llvm::Optional.

Since the use of std::nullopt outside the context of std::optional is
kind of abuse and not intuitive to new comers, I would like to move
away from the constructor and eventually remove it.

This patch takes care of the lldb side of migration.


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


1 Files Affected:

- (modified) lldb/source/Symbol/Function.cpp (+1-1) 


``diff
diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index 4fc793750f84f..6114eccd935ee 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -343,7 +343,7 @@ llvm::ArrayRef> 
Function::GetCallEdges() {
   Block &block = GetBlock(/*can_create*/true);
   SymbolFile *sym_file = block.GetSymbolFile();
   if (!sym_file)
-return std::nullopt;
+return {};
 
   // Lazily read call site information from the SymbolFile.
   m_call_edges = sym_file->ParseCallEdgesInFunction(GetID());

``




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


[Lldb-commits] [lldb] Reland "[lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (#145065)" (PR #145126)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2572a2f224d8c3372fadc0edfa2af5f618765669 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Fri, 20 Jun 2025 18:09:54 +0100
Subject: [PATCH 1/3] Reland "[lldb][DWARF] Remove object_pointer from
 ParsedDWARFAttributes (#145065)"

This reverts commit 877511920dcf36463e06746d626e8876583a6abd.

This fixes the `TestObjCInBlockVars.py` LLDB API test.

The issue was that `GetCXXObjectParameter` wouldn't deduce the object
parameter of Objective-C method definitions correctly. In DWARF those
don't have a `DW_AT_specification` (so no link back to a DeclContext
that is a class type). The fix is to only check the validity of the
DeclContext DIE *if* no `DW_AT_object_pointer` exists on the DIE. If
`DW_AT_object_pointer` does exist, we should just always use that as the
object_parameter.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  | 28 ++-
 .../SymbolFile/DWARF/DWARFASTParserClang.h|  7 +++--
 2 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4f79c8aa3f811..3bec89cdf7469 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -445,15 +445,6 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const 
DWARFDIE &die) {
   name.SetCString(form_value.AsCString());
   break;
 
-case DW_AT_object_pointer:
-  // GetAttributes follows DW_AT_specification.
-  // DW_TAG_subprogram definitions and declarations may both
-  // have a DW_AT_object_pointer. Don't overwrite the one
-  // we parsed for the definition with the one from the declaration.
-  if (!object_pointer.IsValid())
-object_pointer = form_value.Reference();
-  break;
-
 case DW_AT_signature:
   signature = form_value;
   break;
@@ -1116,7 +1107,7 @@ bool DWARFASTParserClang::ParseObjCMethod(
 std::pair DWARFASTParserClang::ParseCXXMethod(
 const DWARFDIE &die, CompilerType clang_type,
 const ParsedDWARFTypeAttributes &attrs, const DWARFDIE &decl_ctx_die,
-bool is_static, bool &ignore_containing_context) {
+const DWARFDIE &object_parameter, bool &ignore_containing_context) {
   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
   SymbolFileDWARF *dwarf = die.GetDWARF();
   assert(dwarf);
@@ -1200,6 +1191,9 @@ std::pair 
DWARFASTParserClang::ParseCXXMethod(
   TypeSystemClang::GetDeclContextForType(class_opaque_type), die,
   attrs.name.GetCString());
 
+  // In DWARF, a C++ method is static if it has no object parameter child.
+  const bool is_static = !object_parameter.IsValid();
+
   // We have a C++ member function with no children (this pointer!) and clang
   // will get mad if we try and make a function that isn't well formed in the
   // DWARF, so we will just skip it...
@@ -1225,9 +1219,7 @@ std::pair 
DWARFASTParserClang::ParseCXXMethod(
 ClangASTMetadata metadata;
 metadata.SetUserID(die.GetID());
 
-char const *object_pointer_name =
-attrs.object_pointer ? attrs.object_pointer.GetName() : nullptr;
-if (object_pointer_name) {
+if (char const *object_pointer_name = object_parameter.GetName()) {
   metadata.SetObjectPtrName(object_pointer_name);
   LLDB_LOGF(log, "Setting object pointer name: %s on method object %p.\n",
 object_pointer_name, static_cast(cxx_method_decl));
@@ -1323,11 +1315,9 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
 type_handled =
 ParseObjCMethod(*objc_method, die, clang_type, attrs, is_variadic);
   } else if (is_cxx_method) {
-// In DWARF, a C++ method is static if it has no object parameter 
child.
-const bool is_static = !object_parameter.IsValid();
 auto [handled, type_sp] =
-ParseCXXMethod(die, clang_type, attrs, decl_ctx_die, is_static,
-   ignore_containing_context);
+ParseCXXMethod(die, clang_type, attrs, decl_ctx_die,
+   object_parameter, ignore_containing_context);
 if (type_sp)
   return type_sp;
 
@@ -1422,9 +1412,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   ClangASTMetadata metadata;
   metadata.SetUserID(die.GetID());
 
-  char const *object_pointer_name =
-  attrs.object_pointer ? attrs.object_pointer.GetName() : nullptr;
-  if (object_pointer_name) {
+  if (char const *object_pointer_name = object_parameter.GetName()) {
 metadata.SetObjectPtrName(object_pointer_name);
 LLDB_LOGF(log,
   "Setting object pointer name: %s on function "
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.

[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2c54344a0bf7c7937166820ae0ada92c4e4445cb Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Wed, 29 Jan 2025 12:15:35 +
Subject: [PATCH 1/6] [lldb][DWARFASTParserClang] Support constant index
 encoding of DW_AT_object_pointer

Starting with https://github.com/llvm/llvm-project/pull/124790, Clang
emits `DW_AT_object_pointer` encoded as integer constants rather than
DIE references. This patch accounts for this.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  47 +++--
 .../x86/explicit-member-function-quals.cpp|  21 +-
 .../DWARF/DWARFASTParserClangTests.cpp| 196 ++
 3 files changed, 244 insertions(+), 20 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a4cb608edd8b4..1e86629e0f730 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -170,23 +170,46 @@ DWARFASTParserClang::GetObjectParameter(const DWARFDIE 
&subprogram,
   if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
-  if (DWARFDIE object_parameter =
-  subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer))
-return object_parameter;
+  // The DW_AT_object_pointer may be either encoded as a reference to a DIE,
+  // in which case that's the object parameter we want. Or it can be a constant
+  // index of the parameter.
+  std::optional object_pointer_index;
+  DWARFFormValue form_value;
+  if (subprogram.GetDIE()->GetAttributeValue(
+  subprogram.GetCU(), DW_AT_object_pointer, form_value,
+  /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) {
+if (auto ref = form_value.Reference())
+  return ref;
+
+object_pointer_index = form_value.Unsigned();
+  }
+
+  // Try to find the DW_TAG_formal_parameter via object_pointer_index.
+  DWARFDIE object_pointer;
+  size_t param_index = 0;
+  for (const auto &child : subprogram.children()) {
+if (child.Tag() != DW_TAG_formal_parameter)
+  continue;
 
-  // If no DW_AT_object_pointer was specified, assume the implicit object
-  // parameter is the first parameter to the function, is called "this" and is
-  // artificial (which is what most compilers would generate).
-  auto children = subprogram.children();
-  auto it = llvm::find_if(children, [](const DWARFDIE &child) {
-return child.Tag() == DW_TAG_formal_parameter;
-  });
+if (param_index == object_pointer_index.value_or(0))
+  object_pointer = child;
+
+++param_index;
+  }
 
-  if (it == children.end())
+  // No formal parameter found for object pointer index.
+  // Nothing to be done.
+  if (!object_pointer)
 return {};
 
-  DWARFDIE object_pointer = *it;
+  // We found the object pointer encoded via DW_AT_object_pointer.
+  // No need for the remaining heuristics.
+  if (object_pointer_index)
+return object_pointer;
 
+  // If no DW_AT_object_pointer was specified, assume the implicit object
+  // parameter is the first parameter to the function, is called "this" and is
+  // artificial (which is what most compilers would generate).
   if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
 return {};
 
diff --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp 
b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
index 33001db69f83e..f89f0f4a4f0bf 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
@@ -1,4 +1,9 @@
 // XFAIL: *
+//
+// FIXME: Explicit object parameter is not shown in
+// type lookup output. This is because we don't attach
+// valid source locations to decls in the DWARF AST,
+// so the ParmVarDecl::isExplicitObjectParameter fails.
 
 // Tests that we correctly deduce the CV-quals and storage
 // class of explicit object member functions.
@@ -8,15 +13,15 @@
 //
 // CHECK:  (lldb) type lookup Foo
 // CHECK-NEXT: struct Foo {
-// CHECK-NEXT:  void Method(Foo);
-// CHECK-NEXT:  void cMethod(const Foo &) const;
-// CHECK-NEXT:  void vMethod(volatile Foo &) volatile;
-// CHECK-NEXT:  void cvMethod(const volatile Foo &) const volatile;
+// CHECK-NEXT:  void Method(this Foo);
+// CHECK-NEXT:  void cMethod(this const Foo &) const;
+// CHECK-NEXT:  void vMethod(this volatile Foo &) volatile;
+// CHECK-NEXT:  void cvMethod(this const volatile Foo &) const volatile;
 // CHECK-NEXT: }
 
 struct Foo {
-  void Method(this Foo) {}
-  void cMethod(this Foo const &) {}
-  void vMethod(this Foo volatile &) {}
-  void cvMethod(this Foo const volatile &) {}
+  [[gnu::always_inline]] void Method(this Foo) {}
+  [[gnu::always_inline]] void cMethod(this Foo const &) {}
+  [[gnu::always_inline]] void vMethod(this Foo volatile

[Lldb-commits] [lldb] [lldb] Migrate away from ValueRange(std::nullopt) (NFC) (PR #145245)

2025-06-22 Thread Alex Langford via lldb-commits

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


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


[Lldb-commits] [lldb] [lldb-dap] Fix DAPError (PR #145010)

2025-06-22 Thread via lldb-commits

https://github.com/DrSergei updated 
https://github.com/llvm/llvm-project/pull/145010

>From 262b3d4643b893a4db6733b7ae893bea5b2dcf84 Mon Sep 17 00:00:00 2001
From: Druzhkov Sergei 
Date: Thu, 19 Jun 2025 15:50:27 +0300
Subject: [PATCH] [lldb-dap] Fix DAPError

---
 lldb/tools/lldb-dap/DAPError.cpp|  6 ++---
 lldb/tools/lldb-dap/DAPError.h  |  2 +-
 lldb/unittests/DAP/CMakeLists.txt   |  1 +
 lldb/unittests/DAP/DAPErrorTest.cpp | 38 +
 4 files changed, 43 insertions(+), 4 deletions(-)
 create mode 100644 lldb/unittests/DAP/DAPErrorTest.cpp

diff --git a/lldb/tools/lldb-dap/DAPError.cpp b/lldb/tools/lldb-dap/DAPError.cpp
index 60347d577f821..d2f80c5c6d634 100644
--- a/lldb/tools/lldb-dap/DAPError.cpp
+++ b/lldb/tools/lldb-dap/DAPError.cpp
@@ -18,13 +18,13 @@ char DAPError::ID;
 DAPError::DAPError(std::string message, std::error_code EC, bool show_user,
std::optional url,
std::optional url_label)
-: m_message(message), m_ec(EC), m_show_user(show_user), m_url(url),
-  m_url_label(url_label) {}
+: m_message(std::move(message)), m_ec(EC), m_show_user(show_user),
+  m_url(std::move(url)), m_url_label(std::move(url_label)) {}
 
 void DAPError::log(llvm::raw_ostream &OS) const { OS << m_message; }
 
 std::error_code DAPError::convertToErrorCode() const {
-  return llvm::inconvertibleErrorCode();
+  return m_ec;
 }
 
 char NotStoppedError::ID;
diff --git a/lldb/tools/lldb-dap/DAPError.h b/lldb/tools/lldb-dap/DAPError.h
index 4c94bdd6ac3d6..e18614fe71935 100644
--- a/lldb/tools/lldb-dap/DAPError.h
+++ b/lldb/tools/lldb-dap/DAPError.h
@@ -30,7 +30,7 @@ class DAPError : public llvm::ErrorInfo {
   const std::string &getMessage() const { return m_message; }
   bool getShowUser() const { return m_show_user; }
   const std::optional &getURL() const { return m_url; }
-  const std::optional &getURLLabel() const { return m_url; }
+  const std::optional &getURLLabel() const { return m_url_label; }
 
 private:
   std::string m_message;
diff --git a/lldb/unittests/DAP/CMakeLists.txt 
b/lldb/unittests/DAP/CMakeLists.txt
index ee623d341ec69..d5824f4b38a5e 100644
--- a/lldb/unittests/DAP/CMakeLists.txt
+++ b/lldb/unittests/DAP/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_lldb_unittest(DAPTests
+  DAPErrorTest.cpp
   DAPTest.cpp
   FifoFilesTest.cpp
   Handler/DisconnectTest.cpp
diff --git a/lldb/unittests/DAP/DAPErrorTest.cpp 
b/lldb/unittests/DAP/DAPErrorTest.cpp
new file mode 100644
index 0..4591145fb2e21
--- /dev/null
+++ b/lldb/unittests/DAP/DAPErrorTest.cpp
@@ -0,0 +1,38 @@
+//===-- DAPErrorTest.cpp
+//---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "DAPError.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+
+using namespace lldb_dap;
+using namespace llvm;
+
+TEST(DAPErrorTest, DefaultConstructor) {
+  DAPError error("Invalid thread");
+
+  EXPECT_EQ(error.getMessage(), "Invalid thread");
+  EXPECT_EQ(error.convertToErrorCode(), llvm::inconvertibleErrorCode());
+  EXPECT_TRUE(error.getShowUser());
+  EXPECT_EQ(error.getURL(), std::nullopt);
+  EXPECT_EQ(error.getURLLabel(), std::nullopt);
+}
+
+TEST(DAPErrorTest, FullConstructor) {
+  auto timed_out = std::make_error_code(std::errc::timed_out);
+  DAPError error("Timed out", timed_out, false, "URL", "URLLabel");
+
+  EXPECT_EQ(error.getMessage(), "Timed out");
+  EXPECT_EQ(error.convertToErrorCode(), timed_out);
+  EXPECT_FALSE(error.getShowUser());
+  EXPECT_THAT(error.getURL(), testing::Optional("URL"));
+  EXPECT_THAT(error.getURLLabel(), testing::Optional("URLLabel"));
+}

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


[Lldb-commits] [lldb] [lldb] Migrate away from ValueRange(std::nullopt) (NFC) (PR #145245)

2025-06-22 Thread Kazu Hirata via lldb-commits

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


[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2c54344a0bf7c7937166820ae0ada92c4e4445cb Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Wed, 29 Jan 2025 12:15:35 +
Subject: [PATCH 1/5] [lldb][DWARFASTParserClang] Support constant index
 encoding of DW_AT_object_pointer

Starting with https://github.com/llvm/llvm-project/pull/124790, Clang
emits `DW_AT_object_pointer` encoded as integer constants rather than
DIE references. This patch accounts for this.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  47 +++--
 .../x86/explicit-member-function-quals.cpp|  21 +-
 .../DWARF/DWARFASTParserClangTests.cpp| 196 ++
 3 files changed, 244 insertions(+), 20 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a4cb608edd8b4..1e86629e0f730 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -170,23 +170,46 @@ DWARFASTParserClang::GetObjectParameter(const DWARFDIE 
&subprogram,
   if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
-  if (DWARFDIE object_parameter =
-  subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer))
-return object_parameter;
+  // The DW_AT_object_pointer may be either encoded as a reference to a DIE,
+  // in which case that's the object parameter we want. Or it can be a constant
+  // index of the parameter.
+  std::optional object_pointer_index;
+  DWARFFormValue form_value;
+  if (subprogram.GetDIE()->GetAttributeValue(
+  subprogram.GetCU(), DW_AT_object_pointer, form_value,
+  /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) {
+if (auto ref = form_value.Reference())
+  return ref;
+
+object_pointer_index = form_value.Unsigned();
+  }
+
+  // Try to find the DW_TAG_formal_parameter via object_pointer_index.
+  DWARFDIE object_pointer;
+  size_t param_index = 0;
+  for (const auto &child : subprogram.children()) {
+if (child.Tag() != DW_TAG_formal_parameter)
+  continue;
 
-  // If no DW_AT_object_pointer was specified, assume the implicit object
-  // parameter is the first parameter to the function, is called "this" and is
-  // artificial (which is what most compilers would generate).
-  auto children = subprogram.children();
-  auto it = llvm::find_if(children, [](const DWARFDIE &child) {
-return child.Tag() == DW_TAG_formal_parameter;
-  });
+if (param_index == object_pointer_index.value_or(0))
+  object_pointer = child;
+
+++param_index;
+  }
 
-  if (it == children.end())
+  // No formal parameter found for object pointer index.
+  // Nothing to be done.
+  if (!object_pointer)
 return {};
 
-  DWARFDIE object_pointer = *it;
+  // We found the object pointer encoded via DW_AT_object_pointer.
+  // No need for the remaining heuristics.
+  if (object_pointer_index)
+return object_pointer;
 
+  // If no DW_AT_object_pointer was specified, assume the implicit object
+  // parameter is the first parameter to the function, is called "this" and is
+  // artificial (which is what most compilers would generate).
   if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
 return {};
 
diff --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp 
b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
index 33001db69f83e..f89f0f4a4f0bf 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
@@ -1,4 +1,9 @@
 // XFAIL: *
+//
+// FIXME: Explicit object parameter is not shown in
+// type lookup output. This is because we don't attach
+// valid source locations to decls in the DWARF AST,
+// so the ParmVarDecl::isExplicitObjectParameter fails.
 
 // Tests that we correctly deduce the CV-quals and storage
 // class of explicit object member functions.
@@ -8,15 +13,15 @@
 //
 // CHECK:  (lldb) type lookup Foo
 // CHECK-NEXT: struct Foo {
-// CHECK-NEXT:  void Method(Foo);
-// CHECK-NEXT:  void cMethod(const Foo &) const;
-// CHECK-NEXT:  void vMethod(volatile Foo &) volatile;
-// CHECK-NEXT:  void cvMethod(const volatile Foo &) const volatile;
+// CHECK-NEXT:  void Method(this Foo);
+// CHECK-NEXT:  void cMethod(this const Foo &) const;
+// CHECK-NEXT:  void vMethod(this volatile Foo &) volatile;
+// CHECK-NEXT:  void cvMethod(this const volatile Foo &) const volatile;
 // CHECK-NEXT: }
 
 struct Foo {
-  void Method(this Foo) {}
-  void cMethod(this Foo const &) {}
-  void vMethod(this Foo volatile &) {}
-  void cvMethod(this Foo const volatile &) {}
+  [[gnu::always_inline]] void Method(this Foo) {}
+  [[gnu::always_inline]] void cMethod(this Foo const &) {}
+  [[gnu::always_inline]] void vMethod(this Foo volatile

[Lldb-commits] [lldb] Reland "[lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (#145065)" (PR #145126)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2572a2f224d8c3372fadc0edfa2af5f618765669 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Fri, 20 Jun 2025 18:09:54 +0100
Subject: [PATCH 1/2] Reland "[lldb][DWARF] Remove object_pointer from
 ParsedDWARFAttributes (#145065)"

This reverts commit 877511920dcf36463e06746d626e8876583a6abd.

This fixes the `TestObjCInBlockVars.py` LLDB API test.

The issue was that `GetCXXObjectParameter` wouldn't deduce the object
parameter of Objective-C method definitions correctly. In DWARF those
don't have a `DW_AT_specification` (so no link back to a DeclContext
that is a class type). The fix is to only check the validity of the
DeclContext DIE *if* no `DW_AT_object_pointer` exists on the DIE. If
`DW_AT_object_pointer` does exist, we should just always use that as the
object_parameter.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  | 28 ++-
 .../SymbolFile/DWARF/DWARFASTParserClang.h|  7 +++--
 2 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4f79c8aa3f811..3bec89cdf7469 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -445,15 +445,6 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const 
DWARFDIE &die) {
   name.SetCString(form_value.AsCString());
   break;
 
-case DW_AT_object_pointer:
-  // GetAttributes follows DW_AT_specification.
-  // DW_TAG_subprogram definitions and declarations may both
-  // have a DW_AT_object_pointer. Don't overwrite the one
-  // we parsed for the definition with the one from the declaration.
-  if (!object_pointer.IsValid())
-object_pointer = form_value.Reference();
-  break;
-
 case DW_AT_signature:
   signature = form_value;
   break;
@@ -1116,7 +1107,7 @@ bool DWARFASTParserClang::ParseObjCMethod(
 std::pair DWARFASTParserClang::ParseCXXMethod(
 const DWARFDIE &die, CompilerType clang_type,
 const ParsedDWARFTypeAttributes &attrs, const DWARFDIE &decl_ctx_die,
-bool is_static, bool &ignore_containing_context) {
+const DWARFDIE &object_parameter, bool &ignore_containing_context) {
   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
   SymbolFileDWARF *dwarf = die.GetDWARF();
   assert(dwarf);
@@ -1200,6 +1191,9 @@ std::pair 
DWARFASTParserClang::ParseCXXMethod(
   TypeSystemClang::GetDeclContextForType(class_opaque_type), die,
   attrs.name.GetCString());
 
+  // In DWARF, a C++ method is static if it has no object parameter child.
+  const bool is_static = !object_parameter.IsValid();
+
   // We have a C++ member function with no children (this pointer!) and clang
   // will get mad if we try and make a function that isn't well formed in the
   // DWARF, so we will just skip it...
@@ -1225,9 +1219,7 @@ std::pair 
DWARFASTParserClang::ParseCXXMethod(
 ClangASTMetadata metadata;
 metadata.SetUserID(die.GetID());
 
-char const *object_pointer_name =
-attrs.object_pointer ? attrs.object_pointer.GetName() : nullptr;
-if (object_pointer_name) {
+if (char const *object_pointer_name = object_parameter.GetName()) {
   metadata.SetObjectPtrName(object_pointer_name);
   LLDB_LOGF(log, "Setting object pointer name: %s on method object %p.\n",
 object_pointer_name, static_cast(cxx_method_decl));
@@ -1323,11 +1315,9 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
 type_handled =
 ParseObjCMethod(*objc_method, die, clang_type, attrs, is_variadic);
   } else if (is_cxx_method) {
-// In DWARF, a C++ method is static if it has no object parameter 
child.
-const bool is_static = !object_parameter.IsValid();
 auto [handled, type_sp] =
-ParseCXXMethod(die, clang_type, attrs, decl_ctx_die, is_static,
-   ignore_containing_context);
+ParseCXXMethod(die, clang_type, attrs, decl_ctx_die,
+   object_parameter, ignore_containing_context);
 if (type_sp)
   return type_sp;
 
@@ -1422,9 +1412,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   ClangASTMetadata metadata;
   metadata.SetUserID(die.GetID());
 
-  char const *object_pointer_name =
-  attrs.object_pointer ? attrs.object_pointer.GetName() : nullptr;
-  if (object_pointer_name) {
+  if (char const *object_pointer_name = object_parameter.GetName()) {
 metadata.SetObjectPtrName(object_pointer_name);
 LLDB_LOGF(log,
   "Setting object pointer name: %s on function "
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.

[Lldb-commits] [lldb] Revert "[lldb] Fix qEcho message handling (#145072)" (PR #145241)

2025-06-22 Thread via lldb-commits

https://github.com/eleviant created 
https://github.com/llvm/llvm-project/pull/145241

Temporarily revert commit e066f35c6981c720e3a7e5883efc40c861b3b7ee, because 
lldb tests randomly hang after it's been pushed.

>From 2f636e6b9f99592dda885e9c9af06464e0a2a6c0 Mon Sep 17 00:00:00 2001
From: Evgeny Leviant 
Date: Sun, 22 Jun 2025 18:54:44 +0200
Subject: [PATCH] Revert "[lldb] Fix qEcho message handling (#145072)"

Temporarily revert commit e066f35c6981c720e3a7e5883efc40c861b3b7ee,
because lldb tests randomly hang after it's been pushed.
---
 .../Python/lldbsuite/test/gdbclientutils.py   | 10 ---
 .../gdb-remote/GDBRemoteCommunication.cpp |  3 +-
 .../GDBRemoteCommunicationClient.cpp  |  2 +-
 .../gdb_remote_client/TestGDBRemoteClient.py  | 72 ---
 4 files changed, 2 insertions(+), 85 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py 
b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py
index b603c35c8df09..753de22b9cfee 100644
--- a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py
+++ b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py
@@ -92,9 +92,6 @@ class MockGDBServerResponder:
 class RESPONSE_DISCONNECT:
 pass
 
-class RESPONSE_NONE:
-pass
-
 def __init__(self):
 self.packetLog = []
 
@@ -184,8 +181,6 @@ def respond(self, packet):
 return self.qQueryGDBServer()
 if packet == "qHostInfo":
 return self.qHostInfo()
-if packet.startswith("qEcho"):
-return self.qEcho(int(packet.split(":")[1]))
 if packet == "qGetWorkingDir":
 return self.qGetWorkingDir()
 if packet == "qOffsets":
@@ -242,9 +237,6 @@ def qProcessInfo(self):
 def qHostInfo(self):
 return "ptrsize:8;endian:little;"
 
-def qEcho(self):
-return "E04"
-
 def qQueryGDBServer(self):
 return "E04"
 
@@ -663,8 +655,6 @@ def _handlePacket(self, packet):
 if not isinstance(response, list):
 response = [response]
 for part in response:
-if part is MockGDBServerResponder.RESPONSE_NONE:
-continue
 if part is MockGDBServerResponder.RESPONSE_DISCONNECT:
 raise self.TerminateConnectionException()
 self._sendPacket(part)
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index f244f7abe45e3..2aea7c6b781d7 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -354,9 +354,8 @@ 
GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
 disconnected = true;
 Disconnect();
   }
-} else {
-  timed_out = true;
 }
+timed_out = true;
 break;
   case eConnectionStatusSuccess:
 // printf ("status = success but error = %s\n",
diff --git 
a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index d8130cae71ce6..adbf06b9a19a0 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -406,7 +406,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
 m_supports_qXfer_memory_map_read = eLazyBoolYes;
   else if (x == "qXfer:siginfo:read+")
 m_supports_qXfer_siginfo_read = eLazyBoolYes;
-  else if (x == "qEcho+")
+  else if (x == "qEcho")
 m_supports_qEcho = eLazyBoolYes;
   else if (x == "QPassSignals+")
 m_supports_QPassSignals = eLazyBoolYes;
diff --git 
a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py 
b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
index 12b464d3397eb..08ac9290ee85a 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
@@ -356,78 +356,6 @@ def A(self, packet):
 ["vRun;%s;61726731;61726732;61726733" % (exe_hex,)]
 )
 
-def test_launch_lengthy_vRun(self):
-class MyResponder(MockGDBServerResponder):
-def __init__(self, *args, **kwargs):
-self.started = False
-return super().__init__(*args, **kwargs)
-
-def qC(self):
-if self.started:
-return "QCp10.10"
-else:
-return "E42"
-
-def qfThreadInfo(self):
-if self.started:
-return "mp10.10"
-else:
-return "E42"
-
-def qsThreadInfo(self):
-return "l"
-
-def qEcho(self, num):
-resp = "qEcho:" + str(num

[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2c54344a0bf7c7937166820ae0ada92c4e4445cb Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Wed, 29 Jan 2025 12:15:35 +
Subject: [PATCH 1/2] [lldb][DWARFASTParserClang] Support constant index
 encoding of DW_AT_object_pointer

Starting with https://github.com/llvm/llvm-project/pull/124790, Clang
emits `DW_AT_object_pointer` encoded as integer constants rather than
DIE references. This patch accounts for this.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  47 +++--
 .../x86/explicit-member-function-quals.cpp|  21 +-
 .../DWARF/DWARFASTParserClangTests.cpp| 196 ++
 3 files changed, 244 insertions(+), 20 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a4cb608edd8b4..1e86629e0f730 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -170,23 +170,46 @@ DWARFASTParserClang::GetObjectParameter(const DWARFDIE 
&subprogram,
   if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
-  if (DWARFDIE object_parameter =
-  subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer))
-return object_parameter;
+  // The DW_AT_object_pointer may be either encoded as a reference to a DIE,
+  // in which case that's the object parameter we want. Or it can be a constant
+  // index of the parameter.
+  std::optional object_pointer_index;
+  DWARFFormValue form_value;
+  if (subprogram.GetDIE()->GetAttributeValue(
+  subprogram.GetCU(), DW_AT_object_pointer, form_value,
+  /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) {
+if (auto ref = form_value.Reference())
+  return ref;
+
+object_pointer_index = form_value.Unsigned();
+  }
+
+  // Try to find the DW_TAG_formal_parameter via object_pointer_index.
+  DWARFDIE object_pointer;
+  size_t param_index = 0;
+  for (const auto &child : subprogram.children()) {
+if (child.Tag() != DW_TAG_formal_parameter)
+  continue;
 
-  // If no DW_AT_object_pointer was specified, assume the implicit object
-  // parameter is the first parameter to the function, is called "this" and is
-  // artificial (which is what most compilers would generate).
-  auto children = subprogram.children();
-  auto it = llvm::find_if(children, [](const DWARFDIE &child) {
-return child.Tag() == DW_TAG_formal_parameter;
-  });
+if (param_index == object_pointer_index.value_or(0))
+  object_pointer = child;
+
+++param_index;
+  }
 
-  if (it == children.end())
+  // No formal parameter found for object pointer index.
+  // Nothing to be done.
+  if (!object_pointer)
 return {};
 
-  DWARFDIE object_pointer = *it;
+  // We found the object pointer encoded via DW_AT_object_pointer.
+  // No need for the remaining heuristics.
+  if (object_pointer_index)
+return object_pointer;
 
+  // If no DW_AT_object_pointer was specified, assume the implicit object
+  // parameter is the first parameter to the function, is called "this" and is
+  // artificial (which is what most compilers would generate).
   if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
 return {};
 
diff --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp 
b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
index 33001db69f83e..f89f0f4a4f0bf 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
@@ -1,4 +1,9 @@
 // XFAIL: *
+//
+// FIXME: Explicit object parameter is not shown in
+// type lookup output. This is because we don't attach
+// valid source locations to decls in the DWARF AST,
+// so the ParmVarDecl::isExplicitObjectParameter fails.
 
 // Tests that we correctly deduce the CV-quals and storage
 // class of explicit object member functions.
@@ -8,15 +13,15 @@
 //
 // CHECK:  (lldb) type lookup Foo
 // CHECK-NEXT: struct Foo {
-// CHECK-NEXT:  void Method(Foo);
-// CHECK-NEXT:  void cMethod(const Foo &) const;
-// CHECK-NEXT:  void vMethod(volatile Foo &) volatile;
-// CHECK-NEXT:  void cvMethod(const volatile Foo &) const volatile;
+// CHECK-NEXT:  void Method(this Foo);
+// CHECK-NEXT:  void cMethod(this const Foo &) const;
+// CHECK-NEXT:  void vMethod(this volatile Foo &) volatile;
+// CHECK-NEXT:  void cvMethod(this const volatile Foo &) const volatile;
 // CHECK-NEXT: }
 
 struct Foo {
-  void Method(this Foo) {}
-  void cMethod(this Foo const &) {}
-  void vMethod(this Foo volatile &) {}
-  void cvMethod(this Foo const volatile &) {}
+  [[gnu::always_inline]] void Method(this Foo) {}
+  [[gnu::always_inline]] void cMethod(this Foo const &) {}
+  [[gnu::always_inline]] void vMethod(this Foo volatile

[Lldb-commits] [lldb] Reland "[lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (#145065)" (PR #145126)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2572a2f224d8c3372fadc0edfa2af5f618765669 Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Fri, 20 Jun 2025 18:09:54 +0100
Subject: [PATCH 1/2] Reland "[lldb][DWARF] Remove object_pointer from
 ParsedDWARFAttributes (#145065)"

This reverts commit 877511920dcf36463e06746d626e8876583a6abd.

This fixes the `TestObjCInBlockVars.py` LLDB API test.

The issue was that `GetCXXObjectParameter` wouldn't deduce the object
parameter of Objective-C method definitions correctly. In DWARF those
don't have a `DW_AT_specification` (so no link back to a DeclContext
that is a class type). The fix is to only check the validity of the
DeclContext DIE *if* no `DW_AT_object_pointer` exists on the DIE. If
`DW_AT_object_pointer` does exist, we should just always use that as the
object_parameter.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  | 28 ++-
 .../SymbolFile/DWARF/DWARFASTParserClang.h|  7 +++--
 2 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4f79c8aa3f811..3bec89cdf7469 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -445,15 +445,6 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const 
DWARFDIE &die) {
   name.SetCString(form_value.AsCString());
   break;
 
-case DW_AT_object_pointer:
-  // GetAttributes follows DW_AT_specification.
-  // DW_TAG_subprogram definitions and declarations may both
-  // have a DW_AT_object_pointer. Don't overwrite the one
-  // we parsed for the definition with the one from the declaration.
-  if (!object_pointer.IsValid())
-object_pointer = form_value.Reference();
-  break;
-
 case DW_AT_signature:
   signature = form_value;
   break;
@@ -1116,7 +1107,7 @@ bool DWARFASTParserClang::ParseObjCMethod(
 std::pair DWARFASTParserClang::ParseCXXMethod(
 const DWARFDIE &die, CompilerType clang_type,
 const ParsedDWARFTypeAttributes &attrs, const DWARFDIE &decl_ctx_die,
-bool is_static, bool &ignore_containing_context) {
+const DWARFDIE &object_parameter, bool &ignore_containing_context) {
   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
   SymbolFileDWARF *dwarf = die.GetDWARF();
   assert(dwarf);
@@ -1200,6 +1191,9 @@ std::pair 
DWARFASTParserClang::ParseCXXMethod(
   TypeSystemClang::GetDeclContextForType(class_opaque_type), die,
   attrs.name.GetCString());
 
+  // In DWARF, a C++ method is static if it has no object parameter child.
+  const bool is_static = !object_parameter.IsValid();
+
   // We have a C++ member function with no children (this pointer!) and clang
   // will get mad if we try and make a function that isn't well formed in the
   // DWARF, so we will just skip it...
@@ -1225,9 +1219,7 @@ std::pair 
DWARFASTParserClang::ParseCXXMethod(
 ClangASTMetadata metadata;
 metadata.SetUserID(die.GetID());
 
-char const *object_pointer_name =
-attrs.object_pointer ? attrs.object_pointer.GetName() : nullptr;
-if (object_pointer_name) {
+if (char const *object_pointer_name = object_parameter.GetName()) {
   metadata.SetObjectPtrName(object_pointer_name);
   LLDB_LOGF(log, "Setting object pointer name: %s on method object %p.\n",
 object_pointer_name, static_cast(cxx_method_decl));
@@ -1323,11 +1315,9 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
 type_handled =
 ParseObjCMethod(*objc_method, die, clang_type, attrs, is_variadic);
   } else if (is_cxx_method) {
-// In DWARF, a C++ method is static if it has no object parameter 
child.
-const bool is_static = !object_parameter.IsValid();
 auto [handled, type_sp] =
-ParseCXXMethod(die, clang_type, attrs, decl_ctx_die, is_static,
-   ignore_containing_context);
+ParseCXXMethod(die, clang_type, attrs, decl_ctx_die,
+   object_parameter, ignore_containing_context);
 if (type_sp)
   return type_sp;
 
@@ -1422,9 +1412,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
   ClangASTMetadata metadata;
   metadata.SetUserID(die.GetID());
 
-  char const *object_pointer_name =
-  attrs.object_pointer ? attrs.object_pointer.GetName() : nullptr;
-  if (object_pointer_name) {
+  if (char const *object_pointer_name = object_parameter.GetName()) {
 metadata.SetObjectPtrName(object_pointer_name);
 LLDB_LOGF(log,
   "Setting object pointer name: %s on function "
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.

[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2c54344a0bf7c7937166820ae0ada92c4e4445cb Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Wed, 29 Jan 2025 12:15:35 +
Subject: [PATCH 1/5] [lldb][DWARFASTParserClang] Support constant index
 encoding of DW_AT_object_pointer

Starting with https://github.com/llvm/llvm-project/pull/124790, Clang
emits `DW_AT_object_pointer` encoded as integer constants rather than
DIE references. This patch accounts for this.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  47 +++--
 .../x86/explicit-member-function-quals.cpp|  21 +-
 .../DWARF/DWARFASTParserClangTests.cpp| 196 ++
 3 files changed, 244 insertions(+), 20 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a4cb608edd8b4..1e86629e0f730 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -170,23 +170,46 @@ DWARFASTParserClang::GetObjectParameter(const DWARFDIE 
&subprogram,
   if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
-  if (DWARFDIE object_parameter =
-  subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer))
-return object_parameter;
+  // The DW_AT_object_pointer may be either encoded as a reference to a DIE,
+  // in which case that's the object parameter we want. Or it can be a constant
+  // index of the parameter.
+  std::optional object_pointer_index;
+  DWARFFormValue form_value;
+  if (subprogram.GetDIE()->GetAttributeValue(
+  subprogram.GetCU(), DW_AT_object_pointer, form_value,
+  /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) {
+if (auto ref = form_value.Reference())
+  return ref;
+
+object_pointer_index = form_value.Unsigned();
+  }
+
+  // Try to find the DW_TAG_formal_parameter via object_pointer_index.
+  DWARFDIE object_pointer;
+  size_t param_index = 0;
+  for (const auto &child : subprogram.children()) {
+if (child.Tag() != DW_TAG_formal_parameter)
+  continue;
 
-  // If no DW_AT_object_pointer was specified, assume the implicit object
-  // parameter is the first parameter to the function, is called "this" and is
-  // artificial (which is what most compilers would generate).
-  auto children = subprogram.children();
-  auto it = llvm::find_if(children, [](const DWARFDIE &child) {
-return child.Tag() == DW_TAG_formal_parameter;
-  });
+if (param_index == object_pointer_index.value_or(0))
+  object_pointer = child;
+
+++param_index;
+  }
 
-  if (it == children.end())
+  // No formal parameter found for object pointer index.
+  // Nothing to be done.
+  if (!object_pointer)
 return {};
 
-  DWARFDIE object_pointer = *it;
+  // We found the object pointer encoded via DW_AT_object_pointer.
+  // No need for the remaining heuristics.
+  if (object_pointer_index)
+return object_pointer;
 
+  // If no DW_AT_object_pointer was specified, assume the implicit object
+  // parameter is the first parameter to the function, is called "this" and is
+  // artificial (which is what most compilers would generate).
   if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
 return {};
 
diff --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp 
b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
index 33001db69f83e..f89f0f4a4f0bf 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
@@ -1,4 +1,9 @@
 // XFAIL: *
+//
+// FIXME: Explicit object parameter is not shown in
+// type lookup output. This is because we don't attach
+// valid source locations to decls in the DWARF AST,
+// so the ParmVarDecl::isExplicitObjectParameter fails.
 
 // Tests that we correctly deduce the CV-quals and storage
 // class of explicit object member functions.
@@ -8,15 +13,15 @@
 //
 // CHECK:  (lldb) type lookup Foo
 // CHECK-NEXT: struct Foo {
-// CHECK-NEXT:  void Method(Foo);
-// CHECK-NEXT:  void cMethod(const Foo &) const;
-// CHECK-NEXT:  void vMethod(volatile Foo &) volatile;
-// CHECK-NEXT:  void cvMethod(const volatile Foo &) const volatile;
+// CHECK-NEXT:  void Method(this Foo);
+// CHECK-NEXT:  void cMethod(this const Foo &) const;
+// CHECK-NEXT:  void vMethod(this volatile Foo &) volatile;
+// CHECK-NEXT:  void cvMethod(this const volatile Foo &) const volatile;
 // CHECK-NEXT: }
 
 struct Foo {
-  void Method(this Foo) {}
-  void cMethod(this Foo const &) {}
-  void vMethod(this Foo volatile &) {}
-  void cvMethod(this Foo const volatile &) {}
+  [[gnu::always_inline]] void Method(this Foo) {}
+  [[gnu::always_inline]] void cMethod(this Foo const &) {}
+  [[gnu::always_inline]] void vMethod(this Foo volatile

[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2c54344a0bf7c7937166820ae0ada92c4e4445cb Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Wed, 29 Jan 2025 12:15:35 +
Subject: [PATCH 1/4] [lldb][DWARFASTParserClang] Support constant index
 encoding of DW_AT_object_pointer

Starting with https://github.com/llvm/llvm-project/pull/124790, Clang
emits `DW_AT_object_pointer` encoded as integer constants rather than
DIE references. This patch accounts for this.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  47 +++--
 .../x86/explicit-member-function-quals.cpp|  21 +-
 .../DWARF/DWARFASTParserClangTests.cpp| 196 ++
 3 files changed, 244 insertions(+), 20 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a4cb608edd8b4..1e86629e0f730 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -170,23 +170,46 @@ DWARFASTParserClang::GetObjectParameter(const DWARFDIE 
&subprogram,
   if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
-  if (DWARFDIE object_parameter =
-  subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer))
-return object_parameter;
+  // The DW_AT_object_pointer may be either encoded as a reference to a DIE,
+  // in which case that's the object parameter we want. Or it can be a constant
+  // index of the parameter.
+  std::optional object_pointer_index;
+  DWARFFormValue form_value;
+  if (subprogram.GetDIE()->GetAttributeValue(
+  subprogram.GetCU(), DW_AT_object_pointer, form_value,
+  /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) {
+if (auto ref = form_value.Reference())
+  return ref;
+
+object_pointer_index = form_value.Unsigned();
+  }
+
+  // Try to find the DW_TAG_formal_parameter via object_pointer_index.
+  DWARFDIE object_pointer;
+  size_t param_index = 0;
+  for (const auto &child : subprogram.children()) {
+if (child.Tag() != DW_TAG_formal_parameter)
+  continue;
 
-  // If no DW_AT_object_pointer was specified, assume the implicit object
-  // parameter is the first parameter to the function, is called "this" and is
-  // artificial (which is what most compilers would generate).
-  auto children = subprogram.children();
-  auto it = llvm::find_if(children, [](const DWARFDIE &child) {
-return child.Tag() == DW_TAG_formal_parameter;
-  });
+if (param_index == object_pointer_index.value_or(0))
+  object_pointer = child;
+
+++param_index;
+  }
 
-  if (it == children.end())
+  // No formal parameter found for object pointer index.
+  // Nothing to be done.
+  if (!object_pointer)
 return {};
 
-  DWARFDIE object_pointer = *it;
+  // We found the object pointer encoded via DW_AT_object_pointer.
+  // No need for the remaining heuristics.
+  if (object_pointer_index)
+return object_pointer;
 
+  // If no DW_AT_object_pointer was specified, assume the implicit object
+  // parameter is the first parameter to the function, is called "this" and is
+  // artificial (which is what most compilers would generate).
   if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
 return {};
 
diff --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp 
b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
index 33001db69f83e..f89f0f4a4f0bf 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
@@ -1,4 +1,9 @@
 // XFAIL: *
+//
+// FIXME: Explicit object parameter is not shown in
+// type lookup output. This is because we don't attach
+// valid source locations to decls in the DWARF AST,
+// so the ParmVarDecl::isExplicitObjectParameter fails.
 
 // Tests that we correctly deduce the CV-quals and storage
 // class of explicit object member functions.
@@ -8,15 +13,15 @@
 //
 // CHECK:  (lldb) type lookup Foo
 // CHECK-NEXT: struct Foo {
-// CHECK-NEXT:  void Method(Foo);
-// CHECK-NEXT:  void cMethod(const Foo &) const;
-// CHECK-NEXT:  void vMethod(volatile Foo &) volatile;
-// CHECK-NEXT:  void cvMethod(const volatile Foo &) const volatile;
+// CHECK-NEXT:  void Method(this Foo);
+// CHECK-NEXT:  void cMethod(this const Foo &) const;
+// CHECK-NEXT:  void vMethod(this volatile Foo &) volatile;
+// CHECK-NEXT:  void cvMethod(this const volatile Foo &) const volatile;
 // CHECK-NEXT: }
 
 struct Foo {
-  void Method(this Foo) {}
-  void cMethod(this Foo const &) {}
-  void vMethod(this Foo volatile &) {}
-  void cvMethod(this Foo const volatile &) {}
+  [[gnu::always_inline]] void Method(this Foo) {}
+  [[gnu::always_inline]] void cMethod(this Foo const &) {}
+  [[gnu::always_inline]] void vMethod(this Foo volatile

[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2c54344a0bf7c7937166820ae0ada92c4e4445cb Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Wed, 29 Jan 2025 12:15:35 +
Subject: [PATCH 1/3] [lldb][DWARFASTParserClang] Support constant index
 encoding of DW_AT_object_pointer

Starting with https://github.com/llvm/llvm-project/pull/124790, Clang
emits `DW_AT_object_pointer` encoded as integer constants rather than
DIE references. This patch accounts for this.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  47 +++--
 .../x86/explicit-member-function-quals.cpp|  21 +-
 .../DWARF/DWARFASTParserClangTests.cpp| 196 ++
 3 files changed, 244 insertions(+), 20 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a4cb608edd8b4..1e86629e0f730 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -170,23 +170,46 @@ DWARFASTParserClang::GetObjectParameter(const DWARFDIE 
&subprogram,
   if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
-  if (DWARFDIE object_parameter =
-  subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer))
-return object_parameter;
+  // The DW_AT_object_pointer may be either encoded as a reference to a DIE,
+  // in which case that's the object parameter we want. Or it can be a constant
+  // index of the parameter.
+  std::optional object_pointer_index;
+  DWARFFormValue form_value;
+  if (subprogram.GetDIE()->GetAttributeValue(
+  subprogram.GetCU(), DW_AT_object_pointer, form_value,
+  /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) {
+if (auto ref = form_value.Reference())
+  return ref;
+
+object_pointer_index = form_value.Unsigned();
+  }
+
+  // Try to find the DW_TAG_formal_parameter via object_pointer_index.
+  DWARFDIE object_pointer;
+  size_t param_index = 0;
+  for (const auto &child : subprogram.children()) {
+if (child.Tag() != DW_TAG_formal_parameter)
+  continue;
 
-  // If no DW_AT_object_pointer was specified, assume the implicit object
-  // parameter is the first parameter to the function, is called "this" and is
-  // artificial (which is what most compilers would generate).
-  auto children = subprogram.children();
-  auto it = llvm::find_if(children, [](const DWARFDIE &child) {
-return child.Tag() == DW_TAG_formal_parameter;
-  });
+if (param_index == object_pointer_index.value_or(0))
+  object_pointer = child;
+
+++param_index;
+  }
 
-  if (it == children.end())
+  // No formal parameter found for object pointer index.
+  // Nothing to be done.
+  if (!object_pointer)
 return {};
 
-  DWARFDIE object_pointer = *it;
+  // We found the object pointer encoded via DW_AT_object_pointer.
+  // No need for the remaining heuristics.
+  if (object_pointer_index)
+return object_pointer;
 
+  // If no DW_AT_object_pointer was specified, assume the implicit object
+  // parameter is the first parameter to the function, is called "this" and is
+  // artificial (which is what most compilers would generate).
   if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
 return {};
 
diff --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp 
b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
index 33001db69f83e..f89f0f4a4f0bf 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
@@ -1,4 +1,9 @@
 // XFAIL: *
+//
+// FIXME: Explicit object parameter is not shown in
+// type lookup output. This is because we don't attach
+// valid source locations to decls in the DWARF AST,
+// so the ParmVarDecl::isExplicitObjectParameter fails.
 
 // Tests that we correctly deduce the CV-quals and storage
 // class of explicit object member functions.
@@ -8,15 +13,15 @@
 //
 // CHECK:  (lldb) type lookup Foo
 // CHECK-NEXT: struct Foo {
-// CHECK-NEXT:  void Method(Foo);
-// CHECK-NEXT:  void cMethod(const Foo &) const;
-// CHECK-NEXT:  void vMethod(volatile Foo &) volatile;
-// CHECK-NEXT:  void cvMethod(const volatile Foo &) const volatile;
+// CHECK-NEXT:  void Method(this Foo);
+// CHECK-NEXT:  void cMethod(this const Foo &) const;
+// CHECK-NEXT:  void vMethod(this volatile Foo &) volatile;
+// CHECK-NEXT:  void cvMethod(this const volatile Foo &) const volatile;
 // CHECK-NEXT: }
 
 struct Foo {
-  void Method(this Foo) {}
-  void cMethod(this Foo const &) {}
-  void vMethod(this Foo volatile &) {}
-  void cvMethod(this Foo const volatile &) {}
+  [[gnu::always_inline]] void Method(this Foo) {}
+  [[gnu::always_inline]] void cMethod(this Foo const &) {}
+  [[gnu::always_inline]] void vMethod(this Foo volatile

[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (PR #144998)

2025-06-22 Thread Michael Buch via lldb-commits

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

>From 2c54344a0bf7c7937166820ae0ada92c4e4445cb Mon Sep 17 00:00:00 2001
From: Michael Buch 
Date: Wed, 29 Jan 2025 12:15:35 +
Subject: [PATCH 1/4] [lldb][DWARFASTParserClang] Support constant index
 encoding of DW_AT_object_pointer

Starting with https://github.com/llvm/llvm-project/pull/124790, Clang
emits `DW_AT_object_pointer` encoded as integer constants rather than
DIE references. This patch accounts for this.
---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  |  47 +++--
 .../x86/explicit-member-function-quals.cpp|  21 +-
 .../DWARF/DWARFASTParserClangTests.cpp| 196 ++
 3 files changed, 244 insertions(+), 20 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a4cb608edd8b4..1e86629e0f730 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -170,23 +170,46 @@ DWARFASTParserClang::GetObjectParameter(const DWARFDIE 
&subprogram,
   if (!decl_ctx_die.IsStructUnionOrClass())
 return {};
 
-  if (DWARFDIE object_parameter =
-  subprogram.GetAttributeValueAsReferenceDIE(DW_AT_object_pointer))
-return object_parameter;
+  // The DW_AT_object_pointer may be either encoded as a reference to a DIE,
+  // in which case that's the object parameter we want. Or it can be a constant
+  // index of the parameter.
+  std::optional object_pointer_index;
+  DWARFFormValue form_value;
+  if (subprogram.GetDIE()->GetAttributeValue(
+  subprogram.GetCU(), DW_AT_object_pointer, form_value,
+  /*end_attr_offset_ptr=*/nullptr, /*check_elaborating_dies=*/true)) {
+if (auto ref = form_value.Reference())
+  return ref;
+
+object_pointer_index = form_value.Unsigned();
+  }
+
+  // Try to find the DW_TAG_formal_parameter via object_pointer_index.
+  DWARFDIE object_pointer;
+  size_t param_index = 0;
+  for (const auto &child : subprogram.children()) {
+if (child.Tag() != DW_TAG_formal_parameter)
+  continue;
 
-  // If no DW_AT_object_pointer was specified, assume the implicit object
-  // parameter is the first parameter to the function, is called "this" and is
-  // artificial (which is what most compilers would generate).
-  auto children = subprogram.children();
-  auto it = llvm::find_if(children, [](const DWARFDIE &child) {
-return child.Tag() == DW_TAG_formal_parameter;
-  });
+if (param_index == object_pointer_index.value_or(0))
+  object_pointer = child;
+
+++param_index;
+  }
 
-  if (it == children.end())
+  // No formal parameter found for object pointer index.
+  // Nothing to be done.
+  if (!object_pointer)
 return {};
 
-  DWARFDIE object_pointer = *it;
+  // We found the object pointer encoded via DW_AT_object_pointer.
+  // No need for the remaining heuristics.
+  if (object_pointer_index)
+return object_pointer;
 
+  // If no DW_AT_object_pointer was specified, assume the implicit object
+  // parameter is the first parameter to the function, is called "this" and is
+  // artificial (which is what most compilers would generate).
   if (!object_pointer.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
 return {};
 
diff --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp 
b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
index 33001db69f83e..f89f0f4a4f0bf 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/explicit-member-function-quals.cpp
@@ -1,4 +1,9 @@
 // XFAIL: *
+//
+// FIXME: Explicit object parameter is not shown in
+// type lookup output. This is because we don't attach
+// valid source locations to decls in the DWARF AST,
+// so the ParmVarDecl::isExplicitObjectParameter fails.
 
 // Tests that we correctly deduce the CV-quals and storage
 // class of explicit object member functions.
@@ -8,15 +13,15 @@
 //
 // CHECK:  (lldb) type lookup Foo
 // CHECK-NEXT: struct Foo {
-// CHECK-NEXT:  void Method(Foo);
-// CHECK-NEXT:  void cMethod(const Foo &) const;
-// CHECK-NEXT:  void vMethod(volatile Foo &) volatile;
-// CHECK-NEXT:  void cvMethod(const volatile Foo &) const volatile;
+// CHECK-NEXT:  void Method(this Foo);
+// CHECK-NEXT:  void cMethod(this const Foo &) const;
+// CHECK-NEXT:  void vMethod(this volatile Foo &) volatile;
+// CHECK-NEXT:  void cvMethod(this const volatile Foo &) const volatile;
 // CHECK-NEXT: }
 
 struct Foo {
-  void Method(this Foo) {}
-  void cMethod(this Foo const &) {}
-  void vMethod(this Foo volatile &) {}
-  void cvMethod(this Foo const volatile &) {}
+  [[gnu::always_inline]] void Method(this Foo) {}
+  [[gnu::always_inline]] void cMethod(this Foo const &) {}
+  [[gnu::always_inline]] void vMethod(this Foo volatile

[Lldb-commits] [lldb] [lldb-dap] Fix DAPError (PR #145010)

2025-06-22 Thread via lldb-commits

DrSergei wrote:

The part about flaky test was moved to separate 
[PR](https://github.com/llvm/llvm-project/pull/145231). Also, added tests for 
DAPError class.

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


[Lldb-commits] [lldb] [lldb-dap] Fix DAPError (PR #145010)

2025-06-22 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 HEAD~1 HEAD --extensions cpp,h -- 
lldb/unittests/DAP/DAPErrorTest.cpp lldb/tools/lldb-dap/DAPError.cpp 
lldb/tools/lldb-dap/DAPError.h
``





View the diff from clang-format here.


``diff
diff --git a/lldb/tools/lldb-dap/DAPError.cpp b/lldb/tools/lldb-dap/DAPError.cpp
index d2f80c5c6..5c5bae37c 100644
--- a/lldb/tools/lldb-dap/DAPError.cpp
+++ b/lldb/tools/lldb-dap/DAPError.cpp
@@ -23,9 +23,7 @@ DAPError::DAPError(std::string message, std::error_code EC, 
bool show_user,
 
 void DAPError::log(llvm::raw_ostream &OS) const { OS << m_message; }
 
-std::error_code DAPError::convertToErrorCode() const {
-  return m_ec;
-}
+std::error_code DAPError::convertToErrorCode() const { return m_ec; }
 
 char NotStoppedError::ID;
 

``




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


[Lldb-commits] [lldb] [lldb-dap] Fix DAPError (PR #145010)

2025-06-22 Thread via lldb-commits

https://github.com/DrSergei updated 
https://github.com/llvm/llvm-project/pull/145010

>From b0263ab7f9d630d8751587c5365bb84d4fe140f4 Mon Sep 17 00:00:00 2001
From: Druzhkov Sergei 
Date: Thu, 19 Jun 2025 15:50:27 +0300
Subject: [PATCH] [lldb-dap] Fix DAPError

---
 lldb/tools/lldb-dap/DAPError.cpp|  8 +++---
 lldb/tools/lldb-dap/DAPError.h  |  2 +-
 lldb/unittests/DAP/CMakeLists.txt   |  1 +
 lldb/unittests/DAP/DAPErrorTest.cpp | 38 +
 4 files changed, 43 insertions(+), 6 deletions(-)
 create mode 100644 lldb/unittests/DAP/DAPErrorTest.cpp

diff --git a/lldb/tools/lldb-dap/DAPError.cpp b/lldb/tools/lldb-dap/DAPError.cpp
index 60347d577f821..5c5bae37cc600 100644
--- a/lldb/tools/lldb-dap/DAPError.cpp
+++ b/lldb/tools/lldb-dap/DAPError.cpp
@@ -18,14 +18,12 @@ char DAPError::ID;
 DAPError::DAPError(std::string message, std::error_code EC, bool show_user,
std::optional url,
std::optional url_label)
-: m_message(message), m_ec(EC), m_show_user(show_user), m_url(url),
-  m_url_label(url_label) {}
+: m_message(std::move(message)), m_ec(EC), m_show_user(show_user),
+  m_url(std::move(url)), m_url_label(std::move(url_label)) {}
 
 void DAPError::log(llvm::raw_ostream &OS) const { OS << m_message; }
 
-std::error_code DAPError::convertToErrorCode() const {
-  return llvm::inconvertibleErrorCode();
-}
+std::error_code DAPError::convertToErrorCode() const { return m_ec; }
 
 char NotStoppedError::ID;
 
diff --git a/lldb/tools/lldb-dap/DAPError.h b/lldb/tools/lldb-dap/DAPError.h
index 4c94bdd6ac3d6..e18614fe71935 100644
--- a/lldb/tools/lldb-dap/DAPError.h
+++ b/lldb/tools/lldb-dap/DAPError.h
@@ -30,7 +30,7 @@ class DAPError : public llvm::ErrorInfo {
   const std::string &getMessage() const { return m_message; }
   bool getShowUser() const { return m_show_user; }
   const std::optional &getURL() const { return m_url; }
-  const std::optional &getURLLabel() const { return m_url; }
+  const std::optional &getURLLabel() const { return m_url_label; }
 
 private:
   std::string m_message;
diff --git a/lldb/unittests/DAP/CMakeLists.txt 
b/lldb/unittests/DAP/CMakeLists.txt
index ee623d341ec69..d5824f4b38a5e 100644
--- a/lldb/unittests/DAP/CMakeLists.txt
+++ b/lldb/unittests/DAP/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_lldb_unittest(DAPTests
+  DAPErrorTest.cpp
   DAPTest.cpp
   FifoFilesTest.cpp
   Handler/DisconnectTest.cpp
diff --git a/lldb/unittests/DAP/DAPErrorTest.cpp 
b/lldb/unittests/DAP/DAPErrorTest.cpp
new file mode 100644
index 0..4591145fb2e21
--- /dev/null
+++ b/lldb/unittests/DAP/DAPErrorTest.cpp
@@ -0,0 +1,38 @@
+//===-- DAPErrorTest.cpp
+//---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "DAPError.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+
+using namespace lldb_dap;
+using namespace llvm;
+
+TEST(DAPErrorTest, DefaultConstructor) {
+  DAPError error("Invalid thread");
+
+  EXPECT_EQ(error.getMessage(), "Invalid thread");
+  EXPECT_EQ(error.convertToErrorCode(), llvm::inconvertibleErrorCode());
+  EXPECT_TRUE(error.getShowUser());
+  EXPECT_EQ(error.getURL(), std::nullopt);
+  EXPECT_EQ(error.getURLLabel(), std::nullopt);
+}
+
+TEST(DAPErrorTest, FullConstructor) {
+  auto timed_out = std::make_error_code(std::errc::timed_out);
+  DAPError error("Timed out", timed_out, false, "URL", "URLLabel");
+
+  EXPECT_EQ(error.getMessage(), "Timed out");
+  EXPECT_EQ(error.convertToErrorCode(), timed_out);
+  EXPECT_FALSE(error.getShowUser());
+  EXPECT_THAT(error.getURL(), testing::Optional("URL"));
+  EXPECT_THAT(error.getURLLabel(), testing::Optional("URLLabel"));
+}

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


[Lldb-commits] [lldb] Revert "[lldb] Fix qEcho message handling (#145072)" (PR #145241)

2025-06-22 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: None (eleviant)


Changes

Temporarily revert commit e066f35c6981c720e3a7e5883efc40c861b3b7ee, because 
lldb tests randomly hang after it's been pushed.

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


4 Files Affected:

- (modified) lldb/packages/Python/lldbsuite/test/gdbclientutils.py (-10) 
- (modified) lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp 
(+1-2) 
- (modified) 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (+1-1) 
- (modified) 
lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py (-72) 


``diff
diff --git a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py 
b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py
index b603c35c8df09..753de22b9cfee 100644
--- a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py
+++ b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py
@@ -92,9 +92,6 @@ class MockGDBServerResponder:
 class RESPONSE_DISCONNECT:
 pass
 
-class RESPONSE_NONE:
-pass
-
 def __init__(self):
 self.packetLog = []
 
@@ -184,8 +181,6 @@ def respond(self, packet):
 return self.qQueryGDBServer()
 if packet == "qHostInfo":
 return self.qHostInfo()
-if packet.startswith("qEcho"):
-return self.qEcho(int(packet.split(":")[1]))
 if packet == "qGetWorkingDir":
 return self.qGetWorkingDir()
 if packet == "qOffsets":
@@ -242,9 +237,6 @@ def qProcessInfo(self):
 def qHostInfo(self):
 return "ptrsize:8;endian:little;"
 
-def qEcho(self):
-return "E04"
-
 def qQueryGDBServer(self):
 return "E04"
 
@@ -663,8 +655,6 @@ def _handlePacket(self, packet):
 if not isinstance(response, list):
 response = [response]
 for part in response:
-if part is MockGDBServerResponder.RESPONSE_NONE:
-continue
 if part is MockGDBServerResponder.RESPONSE_DISCONNECT:
 raise self.TerminateConnectionException()
 self._sendPacket(part)
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index f244f7abe45e3..2aea7c6b781d7 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -354,9 +354,8 @@ 
GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
 disconnected = true;
 Disconnect();
   }
-} else {
-  timed_out = true;
 }
+timed_out = true;
 break;
   case eConnectionStatusSuccess:
 // printf ("status = success but error = %s\n",
diff --git 
a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index d8130cae71ce6..adbf06b9a19a0 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -406,7 +406,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
 m_supports_qXfer_memory_map_read = eLazyBoolYes;
   else if (x == "qXfer:siginfo:read+")
 m_supports_qXfer_siginfo_read = eLazyBoolYes;
-  else if (x == "qEcho+")
+  else if (x == "qEcho")
 m_supports_qEcho = eLazyBoolYes;
   else if (x == "QPassSignals+")
 m_supports_QPassSignals = eLazyBoolYes;
diff --git 
a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py 
b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
index 12b464d3397eb..08ac9290ee85a 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
@@ -356,78 +356,6 @@ def A(self, packet):
 ["vRun;%s;61726731;61726732;61726733" % (exe_hex,)]
 )
 
-def test_launch_lengthy_vRun(self):
-class MyResponder(MockGDBServerResponder):
-def __init__(self, *args, **kwargs):
-self.started = False
-return super().__init__(*args, **kwargs)
-
-def qC(self):
-if self.started:
-return "QCp10.10"
-else:
-return "E42"
-
-def qfThreadInfo(self):
-if self.started:
-return "mp10.10"
-else:
-return "E42"
-
-def qsThreadInfo(self):
-return "l"
-
-def qEcho(self, num):
-resp = "qEcho:" + str(num)
-if num >= 2:
-# We have launched our program
-self.started = True
-return [resp, "T13"]
-
-   

[Lldb-commits] [lldb] 80b9fcf - Revert "[lldb] Fix qEcho message handling (#145072)" (#145241)

2025-06-22 Thread via lldb-commits

Author: eleviant
Date: 2025-06-22T18:59:08+02:00
New Revision: 80b9fcf8fdf2a44da291b41d9244aa99e867f26c

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

LOG: Revert "[lldb] Fix qEcho message handling (#145072)" (#145241)

Temporarily revert commit e066f35c6981c720e3a7e5883efc40c861b3b7ee,
because lldb tests randomly hang after it's been pushed.

Added: 


Modified: 
lldb/packages/Python/lldbsuite/test/gdbclientutils.py
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py

Removed: 




diff  --git a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py 
b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py
index b603c35c8df09..753de22b9cfee 100644
--- a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py
+++ b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py
@@ -92,9 +92,6 @@ class MockGDBServerResponder:
 class RESPONSE_DISCONNECT:
 pass
 
-class RESPONSE_NONE:
-pass
-
 def __init__(self):
 self.packetLog = []
 
@@ -184,8 +181,6 @@ def respond(self, packet):
 return self.qQueryGDBServer()
 if packet == "qHostInfo":
 return self.qHostInfo()
-if packet.startswith("qEcho"):
-return self.qEcho(int(packet.split(":")[1]))
 if packet == "qGetWorkingDir":
 return self.qGetWorkingDir()
 if packet == "qOffsets":
@@ -242,9 +237,6 @@ def qProcessInfo(self):
 def qHostInfo(self):
 return "ptrsize:8;endian:little;"
 
-def qEcho(self):
-return "E04"
-
 def qQueryGDBServer(self):
 return "E04"
 
@@ -663,8 +655,6 @@ def _handlePacket(self, packet):
 if not isinstance(response, list):
 response = [response]
 for part in response:
-if part is MockGDBServerResponder.RESPONSE_NONE:
-continue
 if part is MockGDBServerResponder.RESPONSE_DISCONNECT:
 raise self.TerminateConnectionException()
 self._sendPacket(part)

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index f244f7abe45e3..2aea7c6b781d7 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -354,9 +354,8 @@ 
GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
 disconnected = true;
 Disconnect();
   }
-} else {
-  timed_out = true;
 }
+timed_out = true;
 break;
   case eConnectionStatusSuccess:
 // printf ("status = success but error = %s\n",

diff  --git 
a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index d8130cae71ce6..adbf06b9a19a0 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -406,7 +406,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
 m_supports_qXfer_memory_map_read = eLazyBoolYes;
   else if (x == "qXfer:siginfo:read+")
 m_supports_qXfer_siginfo_read = eLazyBoolYes;
-  else if (x == "qEcho+")
+  else if (x == "qEcho")
 m_supports_qEcho = eLazyBoolYes;
   else if (x == "QPassSignals+")
 m_supports_QPassSignals = eLazyBoolYes;

diff  --git 
a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py 
b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
index 12b464d3397eb..08ac9290ee85a 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
@@ -356,78 +356,6 @@ def A(self, packet):
 ["vRun;%s;61726731;61726732;61726733" % (exe_hex,)]
 )
 
-def test_launch_lengthy_vRun(self):
-class MyResponder(MockGDBServerResponder):
-def __init__(self, *args, **kwargs):
-self.started = False
-return super().__init__(*args, **kwargs)
-
-def qC(self):
-if self.started:
-return "QCp10.10"
-else:
-return "E42"
-
-def qfThreadInfo(self):
-if self.started:
-return "mp10.10"
-else:
-return "E42"
-
-def qsThreadInfo(self):
-return "l"
-
-d